Fixed build scripts for OS X 10.7 build slave.
1 # vim: set ts=2 sw=2 tw=99 noet ft=python:
4 from ambuild.command import SymlinkCommand
5 from ambuild.command import ShellCommand
9 self.compiler = Cpp.Compiler()
12 self.possibleSdks = { }
13 self.possibleSdks['ep1'] = {'sdk': 'HL2SDK', 'ext': '1.ep1', 'def': '1',
14 'name': 'EPISODEONE', 'platform': ['windows', 'linux']}
15 self.possibleSdks['ep2'] = {'sdk': 'HL2SDKOB', 'ext': '2.ep2', 'def': '3',
16 'name': 'ORANGEBOX', 'platform': ['windows', 'linux']}
17 self.possibleSdks['ep2v'] = {'sdk': 'HL2SDKOBVALVE', 'ext': '2.ep2v', 'def': '6',
18 'name': 'ORANGEBOXVALVE', 'platform': ['windows', 'linux', 'darwin']}
19 self.possibleSdks['l4d'] = {'sdk': 'HL2SDKL4D', 'ext': '2.l4d', 'def': '7',
20 'name': 'LEFT4DEAD', 'platform': ['windows', 'linux', 'darwin']}
21 self.possibleSdks['l4d2'] = {'sdk': 'HL2SDKL4D2', 'ext': '2.l4d2', 'def': '8',
22 'name': 'LEFT4DEAD2', 'platform': ['windows', 'linux', 'darwin']}
23 self.possibleSdks['darkm'] = {'sdk': 'HL2SDK-DARKM', 'ext': '2.darkm', 'def': '2',
24 'name': 'DARKMESSIAH', 'platform': ['windows']}
25 self.possibleSdks['swarm'] = {'sdk': 'HL2SDK-SWARM', 'ext': '2.swarm', 'def': '9',
26 'name': 'ALIENSWARM', 'platform': ['windows']}
27 self.possibleSdks['bgt'] = {'sdk': 'HL2SDK-BGT', 'ext': '2.bgt', 'def': '4',
28 'name': 'BLOODYGOODTIME', 'platform': ['windows']}
29 self.possibleSdks['eye'] = {'sdk': 'HL2SDK-EYE', 'ext': '2.eye', 'def': '5',
30 'name': 'EYE', 'platform': ['windows']}
34 if AMBuild.mode == 'config':
36 self.compiler.DetectAll(AMBuild)
39 envvars = { 'MMSOURCE18': 'mmsource-1.8',
40 'HL2SDKOBVALVE': 'hl2sdk-ob-valve',
41 'HL2SDKL4D': 'hl2sdk-l4d',
42 'HL2SDKL4D2': 'hl2sdk-l4d2',
46 if AMBuild.target['platform'] != 'darwin':
47 envvars['HL2SDK'] = 'hl2sdk'
48 envvars['HL2SDKOB'] = 'hl2sdk-ob'
50 #Dark Messiah is Windows-only
51 if AMBuild.target['platform'] == 'windows':
52 envvars['HL2SDK-DARKM'] = 'hl2sdk-darkm'
53 envvars['HL2SDK-SWARM'] = 'hl2sdk-swarm'
54 envvars['HL2SDK-BGT'] = 'hl2sdk-bgt'
55 envvars['HL2SDK-EYE'] = 'hl2sdk-eye'
57 # Finds if a dict with `key` set to `value` is present on the dict of dicts `dictionary`
58 def findDictByKey(dictionary, key, value):
59 for index in dictionary:
60 elem = dictionary[index]
61 if elem[key] == value:
68 if not os.path.isdir(path):
69 raise Exception('Path for {0} was not found: {1}'.format(i, path))
70 elif i.startswith('HL2SDK'):
71 (info, sdk) = findDictByKey(self.possibleSdks, 'sdk', i)
72 self.sdkInfo[sdk] = info
76 while head != None and head != oldhead:
77 path = os.path.join(head, envvars[i])
78 if os.path.isdir(path):
81 head, tail = os.path.split(head)
82 if i.startswith('HL2SDK'):
83 if head != None and head != oldhead:
84 (info, sdk) = findDictByKey(self.possibleSdks, 'sdk', i)
85 self.sdkInfo[sdk] = info
86 elif head == None or head == oldhead:
87 raise Exception('Could not find a valid path for {0}'.format(i))
88 AMBuild.cache.CacheVariable(i, path)
90 if len(self.sdkInfo) < 1:
91 raise Exception('At least one SDK must be available.')
93 AMBuild.cache.CacheVariable('sdkInfo', self.sdkInfo)
96 cxx = self.compiler.cxx
97 if isinstance(cxx, Cpp.CompatGCC):
98 if isinstance(cxx, Cpp.GCC):
100 elif isinstance(cxx, Cpp.Clang):
101 self.vendor = 'clang'
102 self.compiler.AddToListVar('CDEFINES', 'stricmp=strcasecmp')
103 self.compiler.AddToListVar('CDEFINES', '_stricmp=strcasecmp')
104 self.compiler.AddToListVar('CDEFINES', '_snprintf=snprintf')
105 self.compiler.AddToListVar('CDEFINES', '_vsnprintf=vsnprintf')
106 self.compiler.AddToListVar('CFLAGS', '-pipe')
107 self.compiler.AddToListVar('CFLAGS', '-fno-strict-aliasing')
108 if (self.vendor == 'gcc' and cxx.majorVersion >= 4) or self.vendor == 'clang':
109 self.compiler.AddToListVar('CFLAGS', '-fvisibility=hidden')
110 self.compiler.AddToListVar('CXXFLAGS', '-fvisibility-inlines-hidden')
111 self.compiler.AddToListVar('CFLAGS', '-Wall')
112 self.compiler.AddToListVar('CFLAGS', '-Werror')
113 self.compiler.AddToListVar('CFLAGS', '-Wno-uninitialized')
114 self.compiler.AddToListVar('CFLAGS', '-Wno-unused')
115 self.compiler.AddToListVar('CFLAGS', '-Wno-switch')
116 self.compiler.AddToListVar('CFLAGS', '-msse')
117 self.compiler.AddToListVar('CFLAGS', '-m32')
118 self.compiler.AddToListVar('CFLAGS', '-g3')
119 self.compiler.AddToListVar('POSTLINKFLAGS', '-m32')
120 self.compiler.AddToListVar('CXXFLAGS', '-fno-exceptions')
121 self.compiler.AddToListVar('CXXFLAGS', '-fno-rtti')
122 self.compiler.AddToListVar('CXXFLAGS', '-fno-threadsafe-statics')
123 self.compiler.AddToListVar('CXXFLAGS', '-Wno-non-virtual-dtor')
124 self.compiler.AddToListVar('CXXFLAGS', '-Wno-overloaded-virtual')
125 if (self.vendor == 'gcc' and cxx.majorVersion >= 4 and cxx.minorVersion >= 3) or \
126 (self.vendor == 'clang' and cxx.majorVersion >= 3):
127 self.compiler.AddToListVar('CXXFLAGS', '-Wno-delete-non-virtual-dtor')
128 self.compiler.AddToListVar('CDEFINES', 'HAVE_STDINT_H')
129 self.compiler.AddToListVar('CDEFINES', 'GNUC')
130 if self.vendor == 'gcc':
131 self.compiler.AddToListVar('CFLAGS', '-mfpmath=sse')
132 elif isinstance(cxx, Cpp.MSVC):
134 if AMBuild.options.debug == '1':
135 self.compiler.AddToListVar('CFLAGS', '/MTd')
136 self.compiler.AddToListVar('POSTLINKFLAGS', '/NODEFAULTLIB:libcmt')
138 self.compiler.AddToListVar('CFLAGS', '/MT')
139 self.compiler.AddToListVar('CDEFINES', '_CRT_SECURE_NO_DEPRECATE')
140 self.compiler.AddToListVar('CDEFINES', '_CRT_SECURE_NO_WARNINGS')
141 self.compiler.AddToListVar('CDEFINES', '_CRT_NONSTDC_NO_DEPRECATE')
142 self.compiler.AddToListVar('CXXFLAGS', '/EHsc')
143 self.compiler.AddToListVar('CXXFLAGS', '/GR-')
144 self.compiler.AddToListVar('CFLAGS', '/W3')
145 self.compiler.AddToListVar('CFLAGS', '/nologo')
146 self.compiler.AddToListVar('CFLAGS', '/Zi')
147 self.compiler.AddToListVar('CXXFLAGS', '/TP')
148 self.compiler.AddToListVar('POSTLINKFLAGS', '/DEBUG')
149 self.compiler.AddToListVar('POSTLINKFLAGS', '/MACHINE:X86')
150 self.compiler.AddToListVar('POSTLINKFLAGS', '/SUBSYSTEM:WINDOWS')
151 self.compiler.AddToListVar('POSTLINKFLAGS', 'kernel32.lib')
152 self.compiler.AddToListVar('POSTLINKFLAGS', 'user32.lib')
153 self.compiler.AddToListVar('POSTLINKFLAGS', 'gdi32.lib')
154 self.compiler.AddToListVar('POSTLINKFLAGS', 'winspool.lib')
155 self.compiler.AddToListVar('POSTLINKFLAGS', 'comdlg32.lib')
156 self.compiler.AddToListVar('POSTLINKFLAGS', 'advapi32.lib')
157 self.compiler.AddToListVar('POSTLINKFLAGS', 'shell32.lib')
158 self.compiler.AddToListVar('POSTLINKFLAGS', 'ole32.lib')
159 self.compiler.AddToListVar('POSTLINKFLAGS', 'oleaut32.lib')
160 self.compiler.AddToListVar('POSTLINKFLAGS', 'uuid.lib')
161 self.compiler.AddToListVar('POSTLINKFLAGS', 'odbc32.lib')
162 self.compiler.AddToListVar('POSTLINKFLAGS', 'odbccp32.lib')
165 if AMBuild.options.opt == '1':
166 self.compiler.AddToListVar('CDEFINES', 'NDEBUG')
167 if self.vendor == 'gcc' or self.vendor == 'clang':
168 self.compiler.AddToListVar('CFLAGS', '-O3')
169 elif self.vendor == 'msvc':
170 self.compiler.AddToListVar('CFLAGS', '/Ox')
171 self.compiler.AddToListVar('POSTLINKFLAGS', '/OPT:ICF')
172 self.compiler.AddToListVar('POSTLINKFLAGS', '/OPT:REF')
175 if AMBuild.options.debug == '1':
176 self.compiler.AddToListVar('CDEFINES', 'DEBUG')
177 self.compiler.AddToListVar('CDEFINES', '_DEBUG')
178 if self.vendor == 'msvc':
179 self.compiler.AddToListVar('CFLAGS', '/Od')
180 self.compiler.AddToListVar('CFLAGS', '/RTC1')
183 if AMBuild.target['platform'] == 'linux':
184 self.compiler.AddToListVar('CDEFINES', '_LINUX')
185 if self.vendor == 'gcc':
186 self.compiler.AddToListVar('POSTLINKFLAGS', '-static-libgcc')
187 if self.vendor == 'clang':
188 self.compiler.AddToListVar('POSTLINKFLAGS', '-lgcc_eh')
189 elif AMBuild.target['platform'] == 'darwin':
190 self.compiler.AddToListVar('POSTLINKFLAGS', '-mmacosx-version-min=10.5')
191 self.compiler.AddToListVar('POSTLINKFLAGS', ['-arch', 'i386'])
192 self.compiler.AddToListVar('POSTLINKFLAGS', '-lstdc++')
194 # For OS X dylib versioning
196 productFile = open(os.path.join(AMBuild.sourceFolder, 'product.version'), 'r')
197 productContents = productFile.read()
199 m = re.match('(\d+)\.(\d+)\.(\d+).*', productContents)
201 self.version = '1.0.0'
203 major, minor, release = m.groups()
204 self.version = '{0}.{1}.{2}'.format(major, minor, release)
205 AMBuild.cache.CacheVariable('version', self.version)
206 elif AMBuild.target['platform'] == 'windows':
207 self.compiler.AddToListVar('CDEFINES', 'WIN32')
208 self.compiler.AddToListVar('CDEFINES', '_WINDOWS')
211 self.compiler.AddToListVar('CDEFINES', 'SOURCEMOD_BUILD')
212 self.compiler.AddToListVar('CDEFINES', 'SM_GENERATED_BUILD')
213 self.compiler.AddToListVar('CINCLUDES',
214 os.path.join(AMBuild.outputFolder, 'includes'))
215 self.compiler.ToConfig(AMBuild, 'compiler')
216 AMBuild.cache.CacheVariable('vendor', self.vendor)
218 AMBuild.cache.CacheVariable('targetMap', self.targetMap)
220 self.sdkInfo = AMBuild.cache['sdkInfo']
221 self.compiler.FromConfig(AMBuild, 'compiler')
222 self.targetMap = AMBuild.cache['targetMap']
224 if AMBuild.target['platform'] == 'windows':
225 self.compiler.AddToListVar('RCINCLUDES', os.path.join(AMBuild.sourceFolder, 'public'))
226 self.compiler.AddToListVar('RCINCLUDES',
227 os.path.join(AMBuild.outputFolder, 'includes'))
228 self.mmsPath = AMBuild.cache['MMSOURCE18']
230 def DefaultCompiler(self):
231 return self.compiler.Clone()
233 def JobMatters(self, jobname):
234 file = sys._getframe().f_code.co_filename
235 if AMBuild.mode == 'config':
236 self.targetMap[jobname] = file
238 if len(AMBuild.args) == 0:
240 if not jobname in AMBuild.args:
243 def DefaultExtCompiler(self, path):
244 compiler = self.DefaultCompiler()
245 compiler['CXXINCLUDES'].append(os.path.join(AMBuild.sourceFolder, path))
246 compiler['CXXINCLUDES'].append(os.path.join(AMBuild.sourceFolder, path, 'sdk'))
247 compiler['CXXINCLUDES'].append(os.path.join(AMBuild.sourceFolder, 'public'))
248 compiler['CXXINCLUDES'].append(os.path.join(AMBuild.sourceFolder, 'public', 'extensions'))
249 compiler['CXXINCLUDES'].append(os.path.join(AMBuild.sourceFolder, 'public', 'sourcepawn'))
252 def AutoVersion(self, folder, binary):
253 if AMBuild.target['platform'] == 'windows':
254 env = {'RCDEFINES': ['BINARY_NAME="' + binary.binaryFile + '"', 'SM_GENERATED_BUILD']}
255 binary.AddResourceFile(os.path.join(folder, 'version.rc' ), env)
256 elif AMBuild.target['platform'] == 'darwin' and isinstance(binary, Cpp.LibraryBuilder):
257 binary.compiler['POSTLINKFLAGS'].extend(['-compatibility_version', '1.0.0'])
258 binary.compiler['POSTLINKFLAGS'].extend(['-current_version', AMBuild.cache['version']])
262 def StripBinary(self, job, binary):
263 workFolder = os.path.join(AMBuild.outputFolder, job.workFolder)
264 src = os.path.join('..', workFolder, binary.binaryFile)
265 if not binary.NeedsRelink(src):
267 if AMBuild.target['platform'] == 'linux':
268 job.AddCommand(ShellCommand('objcopy --only-keep-debug ' + src + ' ' + src + '.dbg'))
269 job.AddCommand(ShellCommand('objcopy --strip-debug ' + src))
270 job.AddCommand(ShellCommand('objcopy --add-gnu-debuglink=' + src + '.dbg ' + src))
271 elif AMBuild.target['platform'] == 'darwin':
272 job.AddCommand(ShellCommand('dsymutil ' + src))
273 job.AddCommand(ShellCommand('strip -S ' + src))
275 def PreSetupHL2Job(self, job, builder, sdk):
276 info = self.sdkInfo[sdk]
277 sdkPath = AMBuild.cache[info['sdk']]
278 if AMBuild.target['platform'] == 'linux':
280 staticLibs = os.path.join(sdkPath, 'linux_sdk')
282 staticLibs = os.path.join(sdkPath, 'lib', 'linux')
283 workFolder = os.path.join(AMBuild.outputFolder, job.workFolder)
284 if sdk in ['ep2v', 'l4d', 'l4d2']:
285 for i in ['tier1_i486.a', 'mathlib_i486.a', 'libvstdlib.so', 'libtier0.so']:
286 link = os.path.join(workFolder, i)
287 target = os.path.join(staticLibs, i)
291 job.AddCommand(SymlinkCommand(link, target))
293 for i in ['tier1_i486.a', 'mathlib_i486.a', 'vstdlib_i486.so', 'tier0_i486.so']:
294 link = os.path.join(workFolder, i)
295 target = os.path.join(staticLibs, i)
299 job.AddCommand(SymlinkCommand(link, target))
300 elif AMBuild.target['platform'] == 'darwin':
301 staticLibs = os.path.join(sdkPath, 'lib', 'mac')
302 workFolder = os.path.join(AMBuild.outputFolder, job.workFolder)
303 for i in ['tier1_i486.a', 'mathlib_i486.a', 'libvstdlib.dylib', 'libtier0.dylib']:
304 link = os.path.join(workFolder, i)
305 target = os.path.join(staticLibs, i)
309 job.AddCommand(SymlinkCommand(link, target))
310 elif AMBuild.target['platform'] == 'windows':
311 libs = ['tier0', 'tier1', 'vstdlib', 'mathlib']
313 libs.append('interfaces')
315 libPath = os.path.join(sdkPath, 'lib', 'public', lib) + '.lib'
316 builder.RebuildIfNewer(libPath)
317 builder['POSTLINKFLAGS'].append(libPath)
319 def PostSetupHL2Job(self, job, builder, sdk):
320 if AMBuild.target['platform'] in ['linux', 'darwin']:
321 builder.AddObjectFiles(['tier1_i486.a', 'mathlib_i486.a'])
323 def DefaultHL2Compiler(self, path, sdk, noLink = False, oldMms = '-legacy'):
324 compiler = self.DefaultExtCompiler(path)
330 compiler['CXXINCLUDES'].append(os.path.join(self.mmsPath, mms))
331 compiler['CXXINCLUDES'].append(os.path.join(self.mmsPath, mms, 'sourcehook'))
333 info = self.possibleSdks
334 compiler['CDEFINES'].extend(['SE_' + info[i]['name'] + '=' + info[i]['def'] for i in info])
336 paths = [['public'], ['public', 'engine'], ['public', 'mathlib'], ['public', 'vstdlib'],
337 ['public', 'tier0'], ['public', 'tier1']]
338 if sdk == 'ep1' or sdk == 'darkm':
339 paths.append(['public', 'dlls'])
340 paths.append(['game_shared'])
342 paths.append(['public', 'game', 'server'])
343 paths.append(['public', 'toolframework'])
344 paths.append(['game', 'shared'])
345 paths.append(['common'])
347 info = self.sdkInfo[sdk]
348 sdkPath = AMBuild.cache[info['sdk']]
350 compiler['CDEFINES'].append('SOURCE_ENGINE=' + info['def'])
352 if sdk == 'swarm' and AMBuild.target['platform'] == 'windows':
353 compiler['CDEFINES'].extend(['COMPILER_MSVC', 'COMPILER_MSVC32'])
356 if AMBuild.target['platform'] == 'linux':
357 staticLibs = os.path.join(sdkPath, 'linux_sdk')
359 if AMBuild.target['platform'] == 'linux':
360 staticLibs = os.path.join(sdkPath, 'lib', 'linux')
361 elif AMBuild.target['platform'] == 'darwin':
362 staticLibs = os.path.join(sdkPath, 'lib', 'mac')
365 compiler['CXXINCLUDES'].append(os.path.join(sdkPath, *i))
368 if AMBuild.target['platform'] == 'linux':
369 compiler['POSTLINKFLAGS'][0:0] = ['-lm']
370 if sdk in ['ep2v', 'l4d', 'l4d2']:
371 compiler['POSTLINKFLAGS'][0:0] = ['libtier0.so']
372 compiler['POSTLINKFLAGS'][0:0] = ['libvstdlib.so']
374 compiler['POSTLINKFLAGS'][0:0] = ['tier0_i486.so']
375 compiler['POSTLINKFLAGS'][0:0] = ['vstdlib_i486.so']
376 elif AMBuild.target['platform'] == 'darwin':
377 compiler['POSTLINKFLAGS'][0:0] = ['libtier0.dylib']
378 compiler['POSTLINKFLAGS'][0:0] = ['libvstdlib.dylib']
387 AMBuild.Include(os.path.join('tools', 'buildbot', 'Versioning'), globals)
390 ['loader', 'AMBuilder'],
391 ['core', 'AMBuilder'],
392 ['core', 'logic', 'AMBuilder'],
393 ['extensions', 'bintools', 'AMBuilder'],
394 ['extensions', 'clientprefs', 'AMBuilder'],
395 ['extensions', 'cstrike', 'AMBuilder'],
396 ['extensions', 'curl', 'AMBuilder'],
397 ['extensions', 'geoip', 'AMBuilder'],
398 ['extensions', 'mysql', 'AMBuilder'],
399 ['extensions', 'sdktools', 'AMBuilder'],
400 ['extensions', 'topmenus', 'AMBuilder'],
401 ['extensions', 'updater', 'AMBuilder'],
402 ['extensions', 'sqlite', 'AMBuilder'],
403 ['extensions', 'regex', 'AMBuilder'],
404 ['extensions', 'tf2', 'AMBuilder'],
405 ['sourcepawn', 'jit', 'AMBuilder'],
406 ['sourcepawn', 'compiler', 'AMBuilder'],
407 ['plugins', 'AMBuilder'],
408 ['tools', 'buildbot', 'PackageScript'],
409 ['tools', 'buildbot', 'BreakpadSymbols']
412 for parts in FileList:
413 AMBuild.Include(os.path.join(*parts), globals)