dvander@2784: # vim: set ts=2 sw=2 tw=99 noet ft=python: dvander@2784: import os dvander@2784: import sys dvander@2784: from ambuild.command import SymlinkCommand dvander@2784: dvander@2784: class SM: dvander@2784: def __init__(self): dvander@2784: self.compiler = Cpp.Compiler() dvander@2784: dvander@2784: #Build SDK info dvander@2784: self.sdkInfo = { } dvander@2784: self.sdkInfo['ep1'] = {'sdk': 'HL2SDK', 'ext': '1.ep1', 'def': '1', dvander@2784: 'name': 'EPISODEONE'} dvander@2784: self.sdkInfo['ep2'] = {'sdk': 'HL2SDKOB', 'ext': '2.ep2', 'def': '3', dvander@2784: 'name': 'ORANGEBOX'} dvander@2784: self.sdkInfo['ep2v'] = {'sdk': 'HL2SDKOBVALVE', 'ext': '2.ep2v', 'def': '4', dvander@2784: 'name': 'ORANGEBOXVALVE'} dvander@2784: self.sdkInfo['l4d'] = {'sdk': 'HL2SDKL4D', 'ext': '2.l4d', 'def': '5', dvander@2784: 'name': 'LEFT4DEAD'} pred@2849: self.sdkInfo['l4d2'] = {'sdk': 'HL2SDKL4D2', 'ext': '2.l4d2', 'def': '6', pred@2849: 'name': 'LEFT4DEAD2'} dvander@2784: if AMBuild.target['platform'] == 'windows': dvander@2784: self.sdkInfo['darkm'] = {'sdk': 'HL2SDK-DARKM', 'ext': '2.darkm', 'def': '2', dvander@2784: 'name': 'DARKMESSIAH'} dvander@2784: dvander@2784: if AMBuild.mode == 'config': dvander@2784: #Detect compilers dvander@2784: self.compiler.DetectAll(AMBuild) dvander@2784: dvander@2784: #Detect variables pred@2852: envvars = { 'MMSOURCE18': 'mmsource-1.8', dvander@2784: 'HL2SDK': 'hl2sdk', dvander@2784: 'HL2SDKOB': 'hl2sdk-ob', dvander@2784: 'HL2SDKL4D': 'hl2sdk-l4d', dvander@2784: 'HL2SDKOBVALVE': 'hl2sdk-ob-valve', pred@2849: 'HL2SDKL4D2': 'hl2sdk-l4d2', dvander@2784: 'MYSQL5': 'mysql-5.0' dvander@2784: } dvander@2784: dvander@2784: #Dark Messiah is Windows-only dvander@2784: if AMBuild.target['platform'] == 'windows': dvander@2784: envvars['HL2SDK-DARKM'] = 'hl2sdk-darkm' dvander@2784: dvander@2784: #Must have a path for each envvar (file a bug if you don't like this) dvander@2784: for i in envvars: dvander@2784: if i in os.environ: dvander@2784: path = os.environ[i] dvander@2784: if not os.path.isdir(path): dvander@2784: raise Exception('Path for {0} was not found: {1}'.format(i, path)) dvander@2784: else: dvander@2784: head = os.getcwd() dvander@2877: oldhead = None dvander@2877: while head != None and head != oldhead: dvander@2784: path = os.path.join(head, envvars[i]) dvander@2784: if os.path.isdir(path): dvander@2784: break dvander@2877: oldhead = head dvander@2784: head, tail = os.path.split(head) dvander@2877: if head == None or head == oldhead: dvander@2784: raise Exception('Could not find a valid path for {0}'.format(i)) dvander@2784: AMBuild.cache.CacheVariable(i, path) dvander@2784: dvander@2784: #Set up defines dvander@2784: cxx = self.compiler.cxx dvander@2784: if isinstance(cxx, Cpp.GCC): dvander@2784: self.vendor = 'gcc' dvander@2784: self.compiler.AddToListVar('CDEFINES', 'stricmp=strcasecmp') dvander@2784: self.compiler.AddToListVar('CDEFINES', '_stricmp=strcasecmp') dvander@2784: self.compiler.AddToListVar('CDEFINES', '_snprintf=snprintf') dvander@2784: self.compiler.AddToListVar('CDEFINES', '_vsnprintf=vsnprintf') dvander@2784: self.compiler.AddToListVar('CFLAGS', '-pipe') dvander@2784: self.compiler.AddToListVar('CFLAGS', '-fno-strict-aliasing') dvander@2784: if cxx.majorVersion >= 4: dvander@2784: self.compiler.AddToListVar('CFLAGS', '-fvisibility=hidden') dvander@2784: self.compiler.AddToListVar('CXXFLAGS', '-fvisibility-inlines-hidden') dvander@2784: self.compiler.AddToListVar('CFLAGS', '-Wall') dvander@2784: self.compiler.AddToListVar('CFLAGS', '-Werror') dvander@2784: self.compiler.AddToListVar('CFLAGS', '-Wno-uninitialized') dvander@2784: self.compiler.AddToListVar('CFLAGS', '-Wno-unused') dvander@2784: self.compiler.AddToListVar('CFLAGS', '-Wno-switch') dvander@2784: self.compiler.AddToListVar('CFLAGS', '-mfpmath=sse') dvander@2784: self.compiler.AddToListVar('CFLAGS', '-msse') dvander@2784: self.compiler.AddToListVar('CFLAGS', '-m32') dvander@2784: self.compiler.AddToListVar('CFLAGS', '-static-libgcc') dvander@2784: self.compiler.AddToListVar('CXXFLAGS', '-fno-exceptions') dvander@2784: self.compiler.AddToListVar('CXXFLAGS', '-fno-rtti') dvander@2784: self.compiler.AddToListVar('CXXFLAGS', '-fno-threadsafe-statics') dvander@2784: self.compiler.AddToListVar('CXXFLAGS', '-Wno-non-virtual-dtor') dvander@2784: self.compiler.AddToListVar('CDEFINES', 'HAVE_STDINT_H') dvander@2784: elif isinstance(cxx, Cpp.MSVC): dvander@2784: self.vendor = 'msvc' dvander@2784: if AMBuild.options.debug == '1': dvander@2784: self.compiler.AddToListVar('CFLAGS', '/MTd') dvander@2784: else: dvander@2784: self.compiler.AddToListVar('CFLAGS', '/MT') dvander@2784: self.compiler.AddToListVar('CDEFINES', '_CRT_SECURE_NO_DEPRECATE') dvander@2784: self.compiler.AddToListVar('CDEFINES', '_CRT_SECURE_NO_WARNINGS') dvander@2784: self.compiler.AddToListVar('CDEFINES', '_CRT_NONSTDC_NO_DEPRECATE') dvander@2784: self.compiler.AddToListVar('CXXFLAGS', '/EHsc') dvander@2784: self.compiler.AddToListVar('CXXFLAGS', '/GR-') dvander@2784: self.compiler.AddToListVar('CFLAGS', '/W3') dvander@2784: self.compiler.AddToListVar('CFLAGS', '/nologo') dvander@2784: self.compiler.AddToListVar('CFLAGS', '/Zi') dvander@2784: self.compiler.AddToListVar('CXXFLAGS', '/TP') dvander@2815: self.compiler.AddToListVar('POSTLINKFLAGS', '/DEBUG') dvander@2784: self.compiler.AddToListVar('POSTLINKFLAGS', '/MACHINE:X86') dvander@2784: self.compiler.AddToListVar('POSTLINKFLAGS', '/SUBSYSTEM:WINDOWS') dvander@2784: self.compiler.AddToListVar('POSTLINKFLAGS', 'kernel32.lib') dvander@2784: self.compiler.AddToListVar('POSTLINKFLAGS', 'user32.lib') dvander@2784: self.compiler.AddToListVar('POSTLINKFLAGS', 'gdi32.lib') dvander@2784: self.compiler.AddToListVar('POSTLINKFLAGS', 'winspool.lib') dvander@2784: self.compiler.AddToListVar('POSTLINKFLAGS', 'comdlg32.lib') dvander@2784: self.compiler.AddToListVar('POSTLINKFLAGS', 'advapi32.lib') dvander@2784: self.compiler.AddToListVar('POSTLINKFLAGS', 'shell32.lib') dvander@2784: self.compiler.AddToListVar('POSTLINKFLAGS', 'ole32.lib') dvander@2784: self.compiler.AddToListVar('POSTLINKFLAGS', 'oleaut32.lib') dvander@2784: self.compiler.AddToListVar('POSTLINKFLAGS', 'uuid.lib') dvander@2784: self.compiler.AddToListVar('POSTLINKFLAGS', 'odbc32.lib') dvander@2784: self.compiler.AddToListVar('POSTLINKFLAGS', 'odbccp32.lib') dvander@2784: dvander@2784: #Optimization dvander@2784: if AMBuild.options.opt == '1': dvander@2784: self.compiler.AddToListVar('CDEFINES', 'NDEBUG') dvander@2784: if self.vendor == 'gcc': dvander@2784: self.compiler.AddToListVar('CFLAGS', '-O3') dvander@2784: elif self.vendor == 'msvc': dvander@2784: self.compiler.AddToListVar('CFLAGS', '/Ot') dvander@2784: self.compiler.AddToListVar('POSTLINKFLAGS', '/OPT:ICF') dvander@2784: dvander@2784: #Debugging dvander@2784: if AMBuild.options.debug == '1': dvander@2784: self.compiler.AddToListVar('CDEFINES', 'DEBUG') dvander@2784: self.compiler.AddToListVar('CDEFINES', '_DEBUG') dvander@2784: if self.vendor == 'gcc': dvander@2784: self.compiler.AddToListVar('CFLAGS', '-g3') dvander@2784: elif self.vendor == 'msvc': dvander@2784: self.compiler.AddToListVar('CFLAGS', '/Od') dvander@2784: self.compiler.AddToListVar('CFLAGS', '/RTC1') dvander@2784: dvander@2784: #Platform-specifics dvander@2784: if AMBuild.target['platform'] == 'linux': dvander@2784: self.compiler.AddToListVar('CDEFINES', '_LINUX') dvander@2784: elif AMBuild.target['platform'] == 'windows': dvander@2784: self.compiler.AddToListVar('CDEFINES', 'WIN32') dvander@2784: self.compiler.AddToListVar('CDEFINES', '_WINDOWS') dvander@2784: dvander@2784: #Finish up dvander@2784: self.compiler.AddToListVar('CDEFINES', 'SOURCEMOD_BUILD') dvander@2784: self.compiler.AddToListVar('CDEFINES', 'SM_GENERATED_BUILD') dvander@2784: self.compiler.AddToListVar('CINCLUDES', dvander@2784: os.path.join(AMBuild.outputFolder, 'includes')) dvander@2784: self.compiler.ToConfig(AMBuild, 'compiler') dvander@2784: AMBuild.cache.CacheVariable('vendor', self.vendor) dvander@2784: self.targetMap = { } dvander@2784: AMBuild.cache.CacheVariable('targetMap', self.targetMap) dvander@2784: else: dvander@2784: self.compiler.FromConfig(AMBuild, 'compiler') dvander@2784: self.targetMap = AMBuild.cache['targetMap'] dvander@2784: dvander@2784: if AMBuild.target['platform'] == 'windows': ds@2820: self.compiler.AddToListVar('RCINCLUDES', os.path.join(AMBuild.sourceFolder, 'public')) ds@2819: self.compiler.AddToListVar('RCINCLUDES', ds@2819: os.path.join(AMBuild.outputFolder, 'includes')) pred@2852: self.mmsPath = AMBuild.cache['MMSOURCE18'] dvander@2784: dvander@2784: def DefaultCompiler(self): dvander@2784: return self.compiler.Clone() dvander@2784: dvander@2784: def JobMatters(self, jobname): dvander@2784: file = sys._getframe().f_code.co_filename dvander@2784: if AMBuild.mode == 'config': dvander@2784: self.targetMap[jobname] = file dvander@2784: return True dvander@2784: if len(AMBuild.args) == 0: dvander@2784: return True dvander@2784: if not jobname in AMBuild.args: dvander@2784: return False dvander@2784: dvander@2784: def DefaultExtCompiler(self, path): dvander@2784: compiler = self.DefaultCompiler() dvander@2784: compiler['CXXINCLUDES'].append(os.path.join(AMBuild.sourceFolder, path)) dvander@2784: compiler['CXXINCLUDES'].append(os.path.join(AMBuild.sourceFolder, path, 'sdk')) dvander@2784: compiler['CXXINCLUDES'].append(os.path.join(AMBuild.sourceFolder, 'public')) dvander@2784: compiler['CXXINCLUDES'].append(os.path.join(AMBuild.sourceFolder, 'public', 'extensions')) dvander@2784: compiler['CXXINCLUDES'].append(os.path.join(AMBuild.sourceFolder, 'public', 'sourcepawn')) dvander@2784: return compiler dvander@2784: dvander@2784: def AutoVersion(self, folder, binary): dvander@2784: if AMBuild.target['platform'] != 'windows': dvander@2784: return ds@2819: env = {'RCDEFINES': ['BINARY_NAME="' + binary.binaryFile + '"', 'SM_GENERATED_BUILD']} dvander@2784: binary.AddResourceFile(os.path.join(folder, 'version.rc' ), env) dvander@2784: dvander@2784: def PreSetupHL2Job(self, job, builder, sdk): dvander@2784: info = self.sdkInfo[sdk] dvander@2784: sdkPath = AMBuild.cache[info['sdk']] dvander@2784: if AMBuild.target['platform'] == 'linux': dvander@2784: if sdk == 'ep1': dvander@2784: staticLibs = os.path.join(sdkPath, 'linux_sdk') dvander@2784: else: dvander@2784: staticLibs = os.path.join(sdkPath, 'lib', 'linux') dvander@2784: workFolder = os.path.join(AMBuild.outputFolder, job.workFolder) fyrenmoo@2962: if sdk == 'ep2v' or sdk == 'l4d2': fyrenmoo@2953: for i in ['tier1_i486.a', 'mathlib_i486.a', 'libvstdlib.so', 'libtier0.so']: pred@2854: link = os.path.join(workFolder, i) pred@2854: target = os.path.join(staticLibs, i) pred@2854: try: pred@2854: os.lstat(link) pred@2854: except: pred@2854: job.AddCommand(SymlinkCommand(link, target)) pred@2854: else: pred@2854: for i in ['tier1_i486.a', 'mathlib_i486.a', 'vstdlib_i486.so', 'tier0_i486.so']: pred@2854: link = os.path.join(workFolder, i) pred@2854: target = os.path.join(staticLibs, i) pred@2854: try: pred@2854: os.lstat(link) pred@2854: except: pred@2854: job.AddCommand(SymlinkCommand(link, target)) dvander@2784: elif AMBuild.target['platform'] == 'windows': dvander@2784: for lib in ['tier0', 'tier1', 'vstdlib', 'mathlib']: dvander@2784: libPath = os.path.join(sdkPath, 'lib', 'public', lib) + '.lib' dvander@2784: builder.RebuildIfNewer(libPath) dvander@2784: builder['POSTLINKFLAGS'].append(libPath) dvander@2784: dvander@2784: def PostSetupHL2Job(self, job, builder, sdk): dvander@2784: if AMBuild.target['platform'] == 'linux': dvander@2784: builder.AddObjectFiles(['tier1_i486.a', 'mathlib_i486.a']) dvander@2784: dvander@2784: def DefaultHL2Compiler(self, path, sdk, noLink = False, oldMms = '-legacy'): dvander@2784: compiler = self.DefaultExtCompiler(path) dvander@2784: dvander@2784: mms = 'core' dvander@2784: if sdk == 'ep1': dvander@2784: mms += oldMms dvander@2784: dvander@2784: compiler['CXXINCLUDES'].append(os.path.join(self.mmsPath, mms)) dvander@2784: compiler['CXXINCLUDES'].append(os.path.join(self.mmsPath, mms, 'sourcehook')) dvander@2784: dvander@2784: info = self.sdkInfo dvander@2784: compiler['CDEFINES'].extend(['SE_' + info[i]['name'] + '=' + info[i]['def'] for i in info]) dvander@2784: compiler['CDEFINES'].append('SE_DARKMESSIAH=2') dvander@2784: dvander@2784: paths = [['public'], ['public', 'engine'], ['public', 'mathlib'], ['public', 'vstdlib'], dvander@2784: ['public', 'tier0'], ['public', 'tier1']] dvander@2784: if sdk == 'ep1' or sdk == 'darkm': dvander@2784: paths.append(['public', 'dlls']) dvander@2784: paths.append(['game_shared']) dvander@2784: else: dvander@2784: paths.append(['public', 'game', 'server']) dvander@2785: paths.append(['game', 'shared']) dvander@2784: paths.append(['common']) dvander@2784: dvander@2784: info = self.sdkInfo[sdk] dvander@2784: sdkPath = AMBuild.cache[info['sdk']] dvander@2784: dvander@2784: compiler['CDEFINES'].append('SOURCE_ENGINE=' + info['def']) dvander@2784: dvander@2784: if sdk == 'ep1': dvander@2784: if AMBuild.target['platform'] == 'linux': dvander@2784: staticLibs = os.path.join(sdkPath, 'linux_sdk') dvander@2784: else: dvander@2784: if AMBuild.target['platform'] == 'linux': dvander@2784: staticLibs = os.path.join(sdkPath, 'lib', 'linux') dvander@2784: dvander@2784: for i in paths: dvander@2784: compiler['CXXINCLUDES'].append(os.path.join(sdkPath, *i)) dvander@2784: dvander@2784: if not noLink: dvander@2784: if AMBuild.target['platform'] == 'linux': dvander@2784: compiler['POSTLINKFLAGS'][0:0] = ['-lm'] fyrenmoo@2962: if sdk == 'ep2v' or sdk == 'l4d2': fyrenmoo@2953: compiler['POSTLINKFLAGS'][0:0] = ['libtier0.so'] fyrenmoo@2953: compiler['POSTLINKFLAGS'][0:0] = ['libvstdlib.so'] pred@2854: else: pred@2854: compiler['POSTLINKFLAGS'][0:0] = ['tier0_i486.so'] pred@2854: compiler['POSTLINKFLAGS'][0:0] = ['vstdlib_i486.so'] dvander@2784: dvander@2784: return compiler dvander@2784: dvander@2784: sm = SM() dvander@2784: globals = { dvander@2784: 'SM': sm dvander@2784: } dvander@2784: dvander@2784: AMBuild.Include(os.path.join('tools', 'buildbot', 'Versioning'), globals) dvander@2784: dvander@2784: FileList = [ dvander@2784: ['loader', 'AMBuilder'], dvander@2784: ['core', 'AMBuilder'], dvander@2784: ['core', 'logic', 'AMBuilder'], dvander@2784: ['extensions', 'bintools', 'AMBuilder'], dvander@2784: ['extensions', 'clientprefs', 'AMBuilder'], dvander@2784: ['extensions', 'cstrike', 'AMBuilder'], dvander@2784: ['extensions', 'curl', 'AMBuilder'], dvander@2784: ['extensions', 'geoip', 'AMBuilder'], dvander@2784: ['extensions', 'mysql', 'AMBuilder'], dvander@2784: ['extensions', 'sdktools', 'AMBuilder'], dvander@2784: ['extensions', 'topmenus', 'AMBuilder'], dvander@2784: ['extensions', 'updater', 'AMBuilder'], dvander@2784: ['extensions', 'sqlite', 'AMBuilder'], dvander@2784: ['extensions', 'regex', 'AMBuilder'], dvander@2784: ['extensions', 'tf2', 'AMBuilder'], dvander@2784: ['sourcepawn', 'jit', 'AMBuilder'], dvander@2784: ['sourcepawn', 'compiler', 'AMBuilder'], dvander@2784: ['plugins', 'AMBuilder'], dvander@2784: ['tools', 'buildbot', 'PackageScript'] dvander@2784: ] dvander@2784: dvander@2784: for parts in FileList: dvander@2784: AMBuild.Include(os.path.join(*parts), globals) dvander@2784: