Updated cURL version.
1 # vim: set ts=2 sw=2 tw=99 noet ft=python:
4 from ambuild.command import Command
5 from ambuild.command import ShellCommand
6 from ambuild.command import SymlinkCommand
8 class ExtractDebugInfoCommand(Command):
9 def __init__(self, binary, outfile):
10 Command.__init__(self)
12 self.outfile = outfile
14 def run(self, runner, job):
15 if not self.binary.NeedsRelink(self.outfile):
18 if AMBuild.target['platform'] == 'linux':
19 job.AddCommand(ShellCommand('objcopy --only-keep-debug ' + self.outfile + ' ' + self.outfile + '.dbg'))
20 job.AddCommand(ShellCommand('objcopy --strip-debug ' + self.outfile))
21 job.AddCommand(ShellCommand('objcopy --add-gnu-debuglink=' + os.path.basename(self.outfile) + '.dbg ' + self.outfile))
22 elif AMBuild.target['platform'] == 'darwin':
23 job.AddCommand(ShellCommand('dsymutil ' + self.outfile))
24 job.AddCommand(ShellCommand('strip -S ' + self.outfile))
28 self.compiler = Cpp.Compiler()
31 self.possibleSdks = { }
32 self.possibleSdks['ep1'] = {'sdk': 'HL2SDK', 'ext': '1.ep1', 'def': '1',
33 'name': 'EPISODEONE', 'platform': ['windows', 'linux'],
35 self.possibleSdks['ep2'] = {'sdk': 'HL2SDKOB', 'ext': '2.ep2', 'def': '3',
36 'name': 'ORANGEBOX', 'platform': ['windows', 'linux'],
38 self.possibleSdks['css'] = {'sdk': 'HL2SDKCSS', 'ext': '2.css', 'def': '6',
39 'name': 'CSS', 'platform': ['windows', 'linux', 'darwin'],
41 self.possibleSdks['ep2v'] = {'sdk': 'HL2SDKOBVALVE', 'ext': '2.ep2v', 'def': '7',
42 'name': 'ORANGEBOXVALVE', 'platform': ['windows', 'linux', 'darwin'],
43 'dir': 'hl2sdk-ob-valve'}
44 self.possibleSdks['l4d'] = {'sdk': 'HL2SDKL4D', 'ext': '2.l4d', 'def': '8',
45 'name': 'LEFT4DEAD', 'platform': ['windows', 'linux', 'darwin'],
47 self.possibleSdks['l4d2'] = {'sdk': 'HL2SDKL4D2', 'ext': '2.l4d2', 'def': '9',
48 'name': 'LEFT4DEAD2', 'platform': ['windows', 'linux', 'darwin'],
50 self.possibleSdks['darkm'] = {'sdk': 'HL2SDK-DARKM', 'ext': '2.darkm', 'def': '2',
51 'name': 'DARKMESSIAH', 'platform': ['windows'],
52 'dir': 'hl2sdk-darkm'}
53 self.possibleSdks['swarm'] = {'sdk': 'HL2SDK-SWARM', 'ext': '2.swarm', 'def': '10',
54 'name': 'ALIENSWARM', 'platform': ['windows'],
55 'dir': 'hl2sdk-swarm'}
56 self.possibleSdks['bgt'] = {'sdk': 'HL2SDK-BGT', 'ext': '2.bgt', 'def': '4',
57 'name': 'BLOODYGOODTIME', 'platform': ['windows'],
59 self.possibleSdks['eye'] = {'sdk': 'HL2SDK-EYE', 'ext': '2.eye', 'def': '5',
60 'name': 'EYE', 'platform': ['windows'],
62 self.possibleSdks['csgo'] = {'sdk': 'HL2SDKCSGO', 'ext': '2.csgo', 'def': '12',
63 'name': 'CSGO', 'platform': ['windows', 'linux', 'darwin'],
65 # self.possibleSdks['portal2'] = {'sdk': 'HL2SDK-PORTAL2', 'ext': '2.portal2', 'def': '11',
66 # 'name': 'PORTAL2', 'platform': ['windows'],
67 # 'dir': 'hl2sdk-portal2'}
71 if AMBuild.mode == 'config':
73 self.compiler.DetectAll(AMBuild)
75 self.hasMySql = AMBuild.options.hasMySql
76 AMBuild.cache.CacheVariable('hasMySql', self.hasMySql)
78 #Environment variable paths to external headers
79 envvars = { 'MMSOURCE19': 'mmsource-1.9', 'MYSQL5': 'mysql-5.0' }
81 #Look for Metamod:Source and MySQL if not disabled
83 if not self.hasMySql and env == 'MYSQL5':
85 path = self.ResolveEnvPath(env, envvars[env])
87 raise Exception('Could not find a valid path for {0}'.format(env))
88 AMBuild.cache.CacheVariable(env, path)
90 #Look for SDK directories
91 for sdk in self.possibleSdks:
92 #Get list of SDKs to build against or 'all' or 'present'
93 sdkList = AMBuild.options.sdks.split(',')
94 #Build against all supported SDKs?
95 useAll = sdkList[0] == 'all'
96 #Build against supported SDKs that exist?
97 usePresent = sdkList[0] == 'present'
99 info = self.possibleSdks[sdk]
100 if AMBuild.target['platform'] in info['platform']:
103 sdkPath = self.ResolveEnvPath(env, dir)
105 if useAll or sdk in sdkList:
106 raise Exception('Could not find a valid path for {0}'.format(env))
109 if useAll or usePresent or sdk in sdkList:
110 self.sdkInfo[sdk] = info
111 AMBuild.cache.CacheVariable(env, sdkPath)
113 if len(self.sdkInfo) < 1:
114 raise Exception('At least one SDK must be available.')
116 AMBuild.cache.CacheVariable('sdkInfo', self.sdkInfo)
119 cxx = self.compiler.cxx
120 if isinstance(cxx, Cpp.CompatGCC):
121 if isinstance(cxx, Cpp.GCC):
123 elif isinstance(cxx, Cpp.Clang):
124 self.vendor = 'clang'
125 self.compiler.AddToListVar('CDEFINES', 'stricmp=strcasecmp')
126 self.compiler.AddToListVar('CDEFINES', '_stricmp=strcasecmp')
127 self.compiler.AddToListVar('CDEFINES', '_snprintf=snprintf')
128 self.compiler.AddToListVar('CDEFINES', '_vsnprintf=vsnprintf')
129 self.compiler.AddToListVar('CFLAGS', '-pipe')
130 self.compiler.AddToListVar('CFLAGS', '-fno-strict-aliasing')
131 if (self.vendor == 'gcc' and cxx.majorVersion >= 4) or self.vendor == 'clang':
132 self.compiler.AddToListVar('CFLAGS', '-fvisibility=hidden')
133 self.compiler.AddToListVar('CXXFLAGS', '-fvisibility-inlines-hidden')
134 self.compiler.AddToListVar('CFLAGS', '-Wall')
135 self.compiler.AddToListVar('CFLAGS', '-Werror')
136 self.compiler.AddToListVar('CFLAGS', '-Wno-uninitialized')
137 self.compiler.AddToListVar('CFLAGS', '-Wno-unused')
138 self.compiler.AddToListVar('CFLAGS', '-Wno-switch')
139 self.compiler.AddToListVar('CFLAGS', '-msse')
140 self.compiler.AddToListVar('CFLAGS', '-g3')
141 self.compiler.AddToListVar('CFLAGS', '-m32')
142 self.compiler.AddToListVar('POSTLINKFLAGS', '-m32')
143 self.compiler.AddToListVar('CXXFLAGS', '-fno-exceptions')
144 self.compiler.AddToListVar('CXXFLAGS', '-fno-threadsafe-statics')
145 self.compiler.AddToListVar('CXXFLAGS', '-Wno-non-virtual-dtor')
146 self.compiler.AddToListVar('CXXFLAGS', '-Wno-overloaded-virtual')
147 if (self.vendor == 'gcc' and cxx.majorVersion >= 4 and cxx.minorVersion >= 7) or \
148 (self.vendor == 'clang' and cxx.majorVersion >= 3):
149 self.compiler.AddToListVar('CXXFLAGS', '-Wno-delete-non-virtual-dtor')
150 self.compiler.AddToListVar('CDEFINES', 'HAVE_STDINT_H')
151 self.compiler.AddToListVar('CDEFINES', 'GNUC')
152 if self.vendor == 'gcc':
153 self.compiler.AddToListVar('CFLAGS', '-mfpmath=sse')
154 elif isinstance(cxx, Cpp.MSVC):
156 if AMBuild.options.debug == '1':
157 self.compiler.AddToListVar('CFLAGS', '/MTd')
158 self.compiler.AddToListVar('POSTLINKFLAGS', '/NODEFAULTLIB:libcmt')
160 self.compiler.AddToListVar('CFLAGS', '/MT')
161 self.compiler.AddToListVar('CDEFINES', '_CRT_SECURE_NO_DEPRECATE')
162 self.compiler.AddToListVar('CDEFINES', '_CRT_SECURE_NO_WARNINGS')
163 self.compiler.AddToListVar('CDEFINES', '_CRT_NONSTDC_NO_DEPRECATE')
164 self.compiler.AddToListVar('CXXFLAGS', '/EHsc')
165 self.compiler.AddToListVar('CXXFLAGS', '/GR-')
166 self.compiler.AddToListVar('CFLAGS', '/W3')
167 self.compiler.AddToListVar('CFLAGS', '/nologo')
168 self.compiler.AddToListVar('CFLAGS', '/Zi')
169 self.compiler.AddToListVar('CXXFLAGS', '/TP')
170 self.compiler.AddToListVar('POSTLINKFLAGS', '/DEBUG')
171 self.compiler.AddToListVar('POSTLINKFLAGS', '/MACHINE:X86')
172 self.compiler.AddToListVar('POSTLINKFLAGS', '/SUBSYSTEM:WINDOWS')
173 self.compiler.AddToListVar('POSTLINKFLAGS', 'kernel32.lib')
174 self.compiler.AddToListVar('POSTLINKFLAGS', 'user32.lib')
175 self.compiler.AddToListVar('POSTLINKFLAGS', 'gdi32.lib')
176 self.compiler.AddToListVar('POSTLINKFLAGS', 'winspool.lib')
177 self.compiler.AddToListVar('POSTLINKFLAGS', 'comdlg32.lib')
178 self.compiler.AddToListVar('POSTLINKFLAGS', 'advapi32.lib')
179 self.compiler.AddToListVar('POSTLINKFLAGS', 'shell32.lib')
180 self.compiler.AddToListVar('POSTLINKFLAGS', 'ole32.lib')
181 self.compiler.AddToListVar('POSTLINKFLAGS', 'oleaut32.lib')
182 self.compiler.AddToListVar('POSTLINKFLAGS', 'uuid.lib')
183 self.compiler.AddToListVar('POSTLINKFLAGS', 'odbc32.lib')
184 self.compiler.AddToListVar('POSTLINKFLAGS', 'odbccp32.lib')
187 if AMBuild.options.opt == '1':
188 self.compiler.AddToListVar('CDEFINES', 'NDEBUG')
189 if self.vendor == 'gcc' or self.vendor == 'clang':
190 self.compiler.AddToListVar('CFLAGS', '-O3')
191 elif self.vendor == 'msvc':
192 self.compiler.AddToListVar('CFLAGS', '/Ox')
193 self.compiler.AddToListVar('POSTLINKFLAGS', '/OPT:ICF')
194 self.compiler.AddToListVar('POSTLINKFLAGS', '/OPT:REF')
197 if AMBuild.options.debug == '1':
198 self.compiler.AddToListVar('CDEFINES', 'DEBUG')
199 self.compiler.AddToListVar('CDEFINES', '_DEBUG')
200 if self.vendor == 'msvc':
201 self.compiler.AddToListVar('CFLAGS', '/Od')
202 self.compiler.AddToListVar('CFLAGS', '/RTC1')
205 if AMBuild.target['platform'] == 'linux':
206 self.compiler.AddToListVar('CDEFINES', '_LINUX')
207 if self.vendor == 'gcc':
208 self.compiler.AddToListVar('POSTLINKFLAGS', '-static-libgcc')
209 if self.vendor == 'clang':
210 self.compiler.AddToListVar('POSTLINKFLAGS', '-lgcc_eh')
211 elif AMBuild.target['platform'] == 'darwin':
212 self.compiler.AddToListVar('CDEFINES', 'OSX')
213 self.compiler.AddToListVar('CDEFINES', '_OSX')
214 self.compiler.AddToListVar('POSTLINKFLAGS', '-mmacosx-version-min=10.5')
215 self.compiler.AddToListVar('POSTLINKFLAGS', ['-arch', 'i386'])
216 self.compiler.AddToListVar('POSTLINKFLAGS', '-lstdc++')
218 # For OS X dylib versioning
220 productFile = open(os.path.join(AMBuild.sourceFolder, 'product.version'), 'r')
221 productContents = productFile.read()
223 m = re.match('(\d+)\.(\d+)\.(\d+).*', productContents)
225 self.version = '1.0.0'
227 major, minor, release = m.groups()
228 self.version = '{0}.{1}.{2}'.format(major, minor, release)
229 AMBuild.cache.CacheVariable('version', self.version)
230 elif AMBuild.target['platform'] == 'windows':
231 self.compiler.AddToListVar('CDEFINES', 'WIN32')
232 self.compiler.AddToListVar('CDEFINES', '_WINDOWS')
235 self.compiler.AddToListVar('CDEFINES', 'SOURCEMOD_BUILD')
236 self.compiler.AddToListVar('CDEFINES', 'SM_GENERATED_BUILD')
237 self.compiler.AddToListVar('CINCLUDES',
238 os.path.join(AMBuild.outputFolder, 'includes'))
239 self.compiler.ToConfig(AMBuild, 'compiler')
240 AMBuild.cache.CacheVariable('vendor', self.vendor)
242 AMBuild.cache.CacheVariable('targetMap', self.targetMap)
244 self.sdkInfo = AMBuild.cache['sdkInfo']
245 self.compiler.FromConfig(AMBuild, 'compiler')
246 self.targetMap = AMBuild.cache['targetMap']
247 self.hasMySql = AMBuild.cache['hasMySql']
249 if AMBuild.target['platform'] == 'windows':
250 self.compiler.AddToListVar('RCINCLUDES', os.path.join(AMBuild.sourceFolder, 'public'))
251 self.compiler.AddToListVar('RCINCLUDES',
252 os.path.join(AMBuild.outputFolder, 'includes'))
253 self.mmsPath = AMBuild.cache['MMSOURCE19']
255 def DefaultCompiler(self):
256 return self.compiler.Clone()
258 def JobMatters(self, jobname):
259 file = sys._getframe().f_code.co_filename
260 if AMBuild.mode == 'config':
261 self.targetMap[jobname] = file
263 if len(AMBuild.args) == 0:
265 if not jobname in AMBuild.args:
268 def DefaultExtCompiler(self, path):
269 compiler = self.DefaultCompiler()
270 compiler['CXXINCLUDES'].append(os.path.join(AMBuild.sourceFolder, path))
271 compiler['CXXINCLUDES'].append(os.path.join(AMBuild.sourceFolder, path, 'sdk'))
272 compiler['CXXINCLUDES'].append(os.path.join(AMBuild.sourceFolder, 'public'))
273 compiler['CXXINCLUDES'].append(os.path.join(AMBuild.sourceFolder, 'public', 'extensions'))
274 compiler['CXXINCLUDES'].append(os.path.join(AMBuild.sourceFolder, 'public', 'sourcepawn'))
277 def AutoVersion(self, folder, binary):
278 if AMBuild.target['platform'] == 'windows':
279 env = {'RCDEFINES': ['BINARY_NAME="' + binary.binaryFile + '"', 'SM_GENERATED_BUILD']}
280 binary.AddResourceFile(os.path.join(folder, 'version.rc' ), env)
281 elif AMBuild.target['platform'] == 'darwin' and isinstance(binary, Cpp.LibraryBuilder):
282 binary.compiler['POSTLINKFLAGS'].extend(['-compatibility_version', '1.0.0'])
283 binary.compiler['POSTLINKFLAGS'].extend(['-current_version', AMBuild.cache['version']])
287 def ExtractDebugInfo(self, job, binary):
288 src = os.path.join('..', AMBuild.outputFolder, job.workFolder, binary.binaryFile)
289 job.AddCommand(ExtractDebugInfoCommand(binary, src))
291 def PreSetupHL2Job(self, job, builder, sdk):
292 info = self.sdkInfo[sdk]
293 sdkPath = AMBuild.cache[info['sdk']]
294 if AMBuild.target['platform'] == 'linux':
296 staticLibs = os.path.join(sdkPath, 'linux_sdk')
298 staticLibs = os.path.join(sdkPath, 'lib', 'linux')
299 workFolder = os.path.join(AMBuild.outputFolder, job.workFolder)
300 if sdk in ['ep2v', 'css']:
301 libs = ['tier1_i486.a', 'mathlib_i486.a', 'libvstdlib_srv.so', 'libtier0_srv.so']
303 link = os.path.join(workFolder, lib)
304 target = os.path.join(staticLibs, lib)
308 job.AddCommand(SymlinkCommand(link, target))
309 elif sdk in ['l4d', 'l4d2', 'csgo']:
310 libs = ['tier1_i486.a', 'mathlib_i486.a', 'libvstdlib.so', 'libtier0.so']
312 libs.append('interfaces_i486.a')
314 link = os.path.join(workFolder, lib)
315 target = os.path.join(staticLibs, lib)
319 job.AddCommand(SymlinkCommand(link, target))
321 libs = ['tier1_i486.a', 'mathlib_i486.a', 'vstdlib_i486.so', 'tier0_i486.so']
323 link = os.path.join(workFolder, lib)
324 target = os.path.join(staticLibs, lib)
328 job.AddCommand(SymlinkCommand(link, target))
329 elif AMBuild.target['platform'] == 'darwin':
330 staticLibs = os.path.join(sdkPath, 'lib', 'mac')
331 workFolder = os.path.join(AMBuild.outputFolder, job.workFolder)
332 libs = ['tier1_i486.a', 'mathlib_i486.a', 'libvstdlib.dylib', 'libtier0.dylib']
334 libs.append('interfaces_i486.a')
336 link = os.path.join(workFolder, lib)
337 target = os.path.join(staticLibs, lib)
341 job.AddCommand(SymlinkCommand(link, target))
342 elif AMBuild.target['platform'] == 'windows':
343 libs = ['tier0', 'tier1', 'vstdlib', 'mathlib']
344 if sdk in ['swarm', 'csgo']:
345 libs.append('interfaces')
347 libPath = os.path.join(sdkPath, 'lib', 'public', lib) + '.lib'
348 builder.RebuildIfNewer(libPath)
349 builder['POSTLINKFLAGS'].append(libPath)
351 def PostSetupHL2Job(self, job, builder, sdk):
352 if AMBuild.target['platform'] in ['linux', 'darwin']:
353 builder.AddObjectFiles(['tier1_i486.a', 'mathlib_i486.a'])
355 builder.AddObjectFiles(['interfaces_i486.a'])
357 def DefaultHL2Compiler(self, path, sdk, noLink = False, oldMms = '-legacy'):
358 compiler = self.DefaultExtCompiler(path)
364 compiler['CXXINCLUDES'].append(os.path.join(self.mmsPath, mms))
365 compiler['CXXINCLUDES'].append(os.path.join(self.mmsPath, mms, 'sourcehook'))
367 info = self.possibleSdks
368 compiler['CDEFINES'].extend(['SE_' + info[i]['name'] + '=' + info[i]['def'] for i in info])
370 # We don't build for Portal 2 (yet?, ever?), but using this define in code as
371 # it saves trouble if we ever need to
372 compiler['CDEFINES'].append('SE_PORTAL2=11')
374 paths = [['public'], ['public', 'engine'], ['public', 'mathlib'], ['public', 'vstdlib'],
375 ['public', 'tier0'], ['public', 'tier1']]
376 if sdk == 'ep1' or sdk == 'darkm':
377 paths.append(['public', 'dlls'])
378 paths.append(['game_shared'])
380 paths.append(['public', 'game', 'server'])
381 paths.append(['public', 'toolframework'])
382 paths.append(['game', 'shared'])
383 paths.append(['common'])
385 info = self.sdkInfo[sdk]
386 sdkPath = AMBuild.cache[info['sdk']]
388 compiler['CDEFINES'].append('SOURCE_ENGINE=' + info['def'])
390 if sdk in ['swarm','csgo']:
391 if AMBuild.target['platform'] == 'windows':
392 compiler['CDEFINES'].extend(['COMPILER_MSVC', 'COMPILER_MSVC32'])
394 compiler['CDEFINES'].extend(['COMPILER_GCC', 'POSIX'])
397 if AMBuild.target['platform'] == 'linux':
398 staticLibs = os.path.join(sdkPath, 'linux_sdk')
400 if AMBuild.target['platform'] == 'linux':
401 staticLibs = os.path.join(sdkPath, 'lib', 'linux')
402 elif AMBuild.target['platform'] == 'darwin':
403 staticLibs = os.path.join(sdkPath, 'lib', 'mac')
406 compiler['CXXINCLUDES'].append(os.path.join(sdkPath, *i))
409 if AMBuild.target['platform'] == 'linux':
410 compiler['POSTLINKFLAGS'][0:0] = ['-lm']
411 if sdk in ['ep2v', 'css']:
412 compiler['POSTLINKFLAGS'][0:0] = ['libtier0_srv.so']
413 compiler['POSTLINKFLAGS'][0:0] = ['libvstdlib_srv.so']
414 elif sdk in ['l4d', 'l4d2', 'csgo']:
415 compiler['POSTLINKFLAGS'][0:0] = ['libtier0.so']
416 compiler['POSTLINKFLAGS'][0:0] = ['libvstdlib.so']
418 compiler['POSTLINKFLAGS'][0:0] = ['tier0_i486.so']
419 compiler['POSTLINKFLAGS'][0:0] = ['vstdlib_i486.so']
420 elif AMBuild.target['platform'] == 'darwin':
421 compiler['POSTLINKFLAGS'][0:0] = ['libtier0.dylib']
422 compiler['POSTLINKFLAGS'][0:0] = ['libvstdlib.dylib']
426 def ResolveEnvPath(self, env, defaultDir):
427 if env in os.environ:
428 path = os.environ[env]
429 if os.path.isdir(path):
434 while head != None and head != oldhead:
435 path = os.path.join(head, defaultDir)
436 if os.path.isdir(path):
439 head, tail = os.path.split(head)
447 AMBuild.Include(os.path.join('tools', 'buildbot', 'Versioning'), globals)
450 ['loader', 'AMBuilder'],
451 ['core', 'AMBuilder'],
452 ['core', 'logic', 'AMBuilder'],
453 ['extensions', 'bintools', 'AMBuilder'],
454 ['extensions', 'clientprefs', 'AMBuilder'],
455 ['extensions', 'cstrike', 'AMBuilder'],
456 ['extensions', 'curl', 'AMBuilder'],
457 ['extensions', 'geoip', 'AMBuilder'],
458 ['extensions', 'mysql', 'AMBuilder'],
459 ['extensions', 'sdkhooks', 'AMBuilder'],
460 ['extensions', 'sdktools', 'AMBuilder'],
461 ['extensions', 'topmenus', 'AMBuilder'],
462 ['extensions', 'updater', 'AMBuilder'],
463 ['extensions', 'sqlite', 'AMBuilder'],
464 ['extensions', 'regex', 'AMBuilder'],
465 ['extensions', 'tf2', 'AMBuilder'],
466 ['sourcepawn', 'jit', 'AMBuilder'],
467 ['sourcepawn', 'compiler', 'AMBuilder'],
468 ['plugins', 'AMBuilder'],
469 ['tools', 'buildbot', 'PackageScript'],
470 ['tools', 'buildbot', 'BreakpadSymbols']
474 FileList.remove(['extensions', 'mysql', 'AMBuilder'])
476 for parts in FileList:
477 AMBuild.Include(os.path.join(*parts), globals)