AMBuildScript
author Nicholas Hastings <skamonkey@gmail.com>
Wed Nov 06 22:48:07 2013 -0500 (2013-11-06)
changeset 4170 f427c19b87c2
parent 4144 353e86f4c6ab
child 4182 8ef93b2feddf
permissions -rw-r--r--
Updated CS:GO gamedata.
     1 # vim: set ts=2 sw=2 tw=99 noet ft=python:
     2 import os
     3 import sys
     4 from ambuild.command import Command
     5 from ambuild.command import ShellCommand
     6 from ambuild.command import SymlinkCommand
     7 
     8 class ExtractDebugInfoCommand(Command):
     9 	def __init__(self, binary, outfile):
    10 		Command.__init__(self)
    11 		self.binary = binary
    12 		self.outfile = outfile
    13 
    14 	def run(self, runner, job):
    15 		if AMBuild.cache['debug']:
    16 			return
    17 
    18 		if not self.binary.NeedsRelink(self.outfile):
    19 			return
    20 
    21 		if AMBuild.target['platform'] == 'linux':
    22 			job.AddCommand(ShellCommand('objcopy --only-keep-debug ' + self.outfile + ' ' + self.outfile + '.dbg'))
    23 			job.AddCommand(ShellCommand('objcopy --strip-debug ' + self.outfile))
    24 			job.AddCommand(ShellCommand('objcopy --add-gnu-debuglink=' + os.path.basename(self.outfile) + '.dbg ' + self.outfile))
    25 		elif AMBuild.target['platform'] == 'darwin':
    26 			job.AddCommand(ShellCommand('dsymutil ' + self.outfile))
    27 			job.AddCommand(ShellCommand('strip -S ' + self.outfile))
    28 
    29 class SM:
    30 	def __init__(self):
    31 		self.compiler = Cpp.Compiler()
    32 
    33 		#Build SDK info
    34 		self.possibleSdks = { }
    35 		self.possibleSdks['ep1'] =   {'sdk': 'HL2SDK',          'ext': '1.ep1',   'def': '1',
    36 		                         'name': 'EPISODEONE',     'platform': ['windows', 'linux'],
    37 		                         'dir': 'hl2sdk'}
    38 		self.possibleSdks['ep2'] =   {'sdk': 'HL2SDKOB',        'ext': '2.ep2',   'def': '3',
    39 		                         'name': 'ORANGEBOX',      'platform': ['windows', 'linux'],
    40 		                         'dir': 'hl2sdk-ob'}
    41 		self.possibleSdks['css'] =   {'sdk': 'HL2SDKCSS',       'ext': '2.css',     'def': '6',
    42 		                         'name': 'CSS',            'platform': ['windows', 'linux', 'darwin'],
    43 		                         'dir': 'hl2sdk-css'}
    44 		self.possibleSdks['hl2dm'] = {'sdk': 'HL2SDKHL2DM',     'ext': '2.hl2dm',   'def': '7',
    45 		                         'name': 'HL2DM',          'platform': ['windows', 'linux', 'darwin'],
    46 		                        'dir': 'hl2sdk-hl2dm'}
    47 		self.possibleSdks['dods'] =  {'sdk': 'HL2SDKDODS',      'ext': '2.dods',    'def': '8',
    48 		                         'name': 'DODS',           'platform': ['windows', 'linux', 'darwin'],
    49 		                        'dir': 'hl2sdk-dods'}
    50 		self.possibleSdks['sdk2013'] =   {'sdk': 'HL2SDK2013',  'ext': '2.sdk2013', 'def': '9',
    51 		                         'name': 'SDK2013',        'platform': ['windows', 'linux', 'darwin'],
    52 		                        'dir': 'hl2sdk-2013'}
    53 		self.possibleSdks['tf2'] =   {'sdk': 'HL2SDKTF2',       'ext': '2.tf2',     'def': '10',
    54 		                         'name': 'TF2',            'platform': ['windows', 'linux', 'darwin'],
    55 		                        'dir': 'hl2sdk-tf2'}
    56 		self.possibleSdks['l4d'] =   {'sdk': 'HL2SDKL4D',       'ext': '2.l4d',     'def': '11',
    57 		                         'name': 'LEFT4DEAD',      'platform': ['windows', 'linux', 'darwin'],
    58 		                         'dir': 'hl2sdk-l4d'}
    59 		self.possibleSdks['nd'] =    {'sdk': 'HL2SDKND',        'ext': '2.nd',      'def': '12',
    60 		                         'name': 'NUCLEARDAWN',    'platform': ['windows', 'linux', 'darwin'],
    61 		                         'dir': 'hl2sdk-nd'}
    62 		self.possibleSdks['l4d2'] =  {'sdk': 'HL2SDKL4D2',      'ext': '2.l4d2',    'def': '13',
    63 		                         'name': 'LEFT4DEAD2',     'platform': ['windows', 'linux', 'darwin'],
    64 		                         'dir': 'hl2sdk-l4d2'}
    65 		self.possibleSdks['darkm'] = {'sdk': 'HL2SDK-DARKM',    'ext': '2.darkm',   'def': '2',
    66 		                         'name': 'DARKMESSIAH',    'platform': ['windows'],
    67 		                          'dir': 'hl2sdk-darkm'}
    68 		self.possibleSdks['swarm'] = {'sdk': 'HL2SDK-SWARM',    'ext': '2.swarm',   'def': '14',
    69 		                         'name': 'ALIENSWARM',     'platform': ['windows'],
    70 		                         'dir': 'hl2sdk-swarm'}
    71 		self.possibleSdks['bgt'] =   {'sdk': 'HL2SDK-BGT',      'ext': '2.bgt',     'def': '4',
    72 		                         'name': 'BLOODYGOODTIME', 'platform': ['windows'],
    73 		                         'dir': 'hl2sdk-bgt'}
    74 		self.possibleSdks['eye'] =   {'sdk': 'HL2SDK-EYE',      'ext': '2.eye',     'def': '5',
    75 		                         'name': 'EYE',            'platform': ['windows'],
    76 		                         'dir': 'hl2sdk-eye'}
    77 		self.possibleSdks['csgo'] =  {'sdk': 'HL2SDKCSGO',     'ext': '2.csgo',     'def': '18',
    78 		                         'name': 'CSGO',           'platform': ['windows', 'linux', 'darwin'],
    79 		                         'dir': 'hl2sdk-csgo'}
    80 		self.possibleSdks['dota'] =  {'sdk': 'HL2SDKDOTA',     'ext': '2.dota',     'def': '19',
    81 		                         'name': 'DOTA',           'platform': ['windows'],
    82 		                         'dir': 'hl2sdk-dota'}
    83 		self.possibleSdks['portal2'] = {'sdk': 'HL2SDKPORTAL2','ext': '2.portal2',  'def': '15',
    84 		                         'name': 'PORTAL2',           'platform': [],
    85 		                         'dir': 'hl2sdk-portal2'}
    86 		self.possibleSdks['blade'] = {'sdk': 'HL2SDKBLADE',    'ext': '2.blade',    'def': '16',
    87 		                         'name': 'BLADE',             'platform': ['windows', 'linux'],
    88 		                         'dir': 'hl2sdk-blade'}
    89 		self.possibleSdks['insurgency'] = {'sdk': 'HL2SDKINSURGENCY', 'ext': '2.insurgency', 'def': '17',
    90 		                         'name': 'INSURGENCY',        'platform': ['windows', 'linux', 'darwin'],
    91 		                         'dir': 'hl2sdk-insurgency'}
    92 		
    93 		self.sdkInfo = { }
    94 
    95 		if AMBuild.mode == 'config':
    96 			#Detect compilers
    97 			self.compiler.DetectAll(AMBuild)
    98 			
    99 			self.hasMySql = AMBuild.options.hasMySql
   100 			AMBuild.cache.CacheVariable('hasMySql', self.hasMySql)
   101 
   102 			AMBuild.cache.CacheVariable('debug', AMBuild.options.debug)
   103 			
   104 			#Environment variable paths to external headers
   105 			envvars = { 'MMSOURCE110': 'mmsource-1.10', 'MYSQL5': 'mysql-5.0' }
   106 			
   107 			#Look for Metamod:Source and MySQL if not disabled
   108 			for env in envvars:
   109 				if not self.hasMySql and env == 'MYSQL5':
   110 					continue
   111 				path = self.ResolveEnvPath(env, envvars[env])
   112 				if path == None:
   113 					raise Exception('Could not find a valid path for {0}'.format(env))
   114 				AMBuild.cache.CacheVariable(env, path)
   115 			
   116 			#Look for SDK directories
   117 			for sdk in self.possibleSdks:
   118 				#Get list of SDKs to build against or 'all' or 'present'
   119 				sdkList = AMBuild.options.sdks.split(',')
   120 				#Build against all supported SDKs?
   121 				useAll = sdkList[0] == 'all'
   122 				#Build against supported SDKs that exist?
   123 				usePresent = sdkList[0] == 'present'
   124 
   125 				info = self.possibleSdks[sdk]
   126 				if AMBuild.target['platform'] in info['platform']:
   127 					env = info['sdk']
   128 					dir = info['dir']
   129 					sdkPath = self.ResolveEnvPath(env, dir)
   130 					if sdkPath == None:
   131 						if useAll or sdk in sdkList:
   132 							raise Exception('Could not find a valid path for {0}'.format(env))
   133 						else:
   134 							continue
   135 					if useAll or usePresent or sdk in sdkList:
   136 						self.sdkInfo[sdk] = info
   137 						AMBuild.cache.CacheVariable(env, sdkPath)
   138 
   139 			if len(self.sdkInfo) < 1:
   140 				raise Exception('At least one SDK must be available.')
   141 				
   142 			AMBuild.cache.CacheVariable('sdkInfo', self.sdkInfo)
   143 
   144 			#Set up defines
   145 			cxx = self.compiler.cxx
   146 			if isinstance(cxx, Cpp.CompatGCC):
   147 				if isinstance(cxx, Cpp.GCC):
   148 					self.vendor = 'gcc'
   149 				elif isinstance(cxx, Cpp.Clang):
   150 					self.vendor = 'clang'
   151 				self.compiler.AddToListVar('CDEFINES', 'stricmp=strcasecmp')
   152 				self.compiler.AddToListVar('CDEFINES', '_stricmp=strcasecmp')
   153 				self.compiler.AddToListVar('CDEFINES', '_snprintf=snprintf')
   154 				self.compiler.AddToListVar('CDEFINES', '_vsnprintf=vsnprintf')
   155 				self.compiler.AddToListVar('CFLAGS', '-pipe')
   156 				self.compiler.AddToListVar('CFLAGS', '-fno-strict-aliasing')
   157 				if (self.vendor == 'gcc' and cxx.majorVersion >= 4) or self.vendor == 'clang':
   158 					self.compiler.AddToListVar('CFLAGS', '-fvisibility=hidden')
   159 					self.compiler.AddToListVar('CXXFLAGS', '-fvisibility-inlines-hidden')
   160 				self.compiler.AddToListVar('CFLAGS', '-Wall')
   161 				self.compiler.AddToListVar('CFLAGS', '-Werror')
   162 				if (self.vendor == 'gcc' and cxx.majorVersion >= 4 and cxx.minorVersion >= 6) or self.vendor == 'clang':
   163 					self.compiler.AddToListVar('CFLAGS', '-Wno-narrowing')
   164 				self.compiler.AddToListVar('CFLAGS', '-Wno-uninitialized')
   165 				self.compiler.AddToListVar('CFLAGS', '-Wno-unused')
   166 				self.compiler.AddToListVar('CFLAGS', '-Wno-switch')
   167 				self.compiler.AddToListVar('CFLAGS', '-msse')
   168 				self.compiler.AddToListVar('CFLAGS', '-g3')
   169 				self.compiler.AddToListVar('CFLAGS', '-m32')
   170 				self.compiler.AddToListVar('POSTLINKFLAGS', '-m32')
   171 				self.compiler.AddToListVar('CXXFLAGS', '-fno-exceptions')
   172 				self.compiler.AddToListVar('CXXFLAGS', '-fno-threadsafe-statics')
   173 				self.compiler.AddToListVar('CXXFLAGS', '-Wno-non-virtual-dtor')
   174 				self.compiler.AddToListVar('CXXFLAGS', '-Wno-overloaded-virtual')
   175 				if (self.vendor == 'gcc' and cxx.majorVersion >= 4 and cxx.minorVersion >= 7) or \
   176 						(self.vendor == 'clang' and cxx.majorVersion >= 3):
   177 					self.compiler.AddToListVar('CXXFLAGS', '-Wno-delete-non-virtual-dtor')
   178 				self.compiler.AddToListVar('CDEFINES', 'HAVE_STDINT_H')
   179 				self.compiler.AddToListVar('CDEFINES', 'GNUC')
   180 				if self.vendor == 'gcc':
   181 					self.compiler.AddToListVar('CFLAGS', '-mfpmath=sse')
   182 			elif isinstance(cxx, Cpp.MSVC):
   183 				self.vendor = 'msvc'
   184 				if AMBuild.options.debug == '1':
   185 					self.compiler.AddToListVar('CFLAGS', '/MTd')
   186 					self.compiler.AddToListVar('POSTLINKFLAGS', '/NODEFAULTLIB:libcmt')
   187 				else:
   188 					self.compiler.AddToListVar('CFLAGS', '/MT')
   189 				self.compiler.AddToListVar('CDEFINES', '_CRT_SECURE_NO_DEPRECATE')
   190 				self.compiler.AddToListVar('CDEFINES', '_CRT_SECURE_NO_WARNINGS')
   191 				self.compiler.AddToListVar('CDEFINES', '_CRT_NONSTDC_NO_DEPRECATE')
   192 				self.compiler.AddToListVar('CDEFINES', '_ITERATOR_DEBUG_LEVEL=0')
   193 				self.compiler.AddToListVar('CXXFLAGS', '/EHsc')
   194 				self.compiler.AddToListVar('CXXFLAGS', '/GR-')
   195 				self.compiler.AddToListVar('CFLAGS', '/W3')
   196 				self.compiler.AddToListVar('CFLAGS', '/nologo')
   197 				self.compiler.AddToListVar('CFLAGS', '/Zi')
   198 				self.compiler.AddToListVar('CXXFLAGS', '/TP')
   199 				self.compiler.AddToListVar('POSTLINKFLAGS', '/DEBUG')
   200 				self.compiler.AddToListVar('POSTLINKFLAGS', '/MACHINE:X86')
   201 				self.compiler.AddToListVar('POSTLINKFLAGS', '/SUBSYSTEM:WINDOWS')
   202 				self.compiler.AddToListVar('POSTLINKFLAGS', 'kernel32.lib')
   203 				self.compiler.AddToListVar('POSTLINKFLAGS', 'user32.lib')
   204 				self.compiler.AddToListVar('POSTLINKFLAGS', 'gdi32.lib')
   205 				self.compiler.AddToListVar('POSTLINKFLAGS', 'winspool.lib')
   206 				self.compiler.AddToListVar('POSTLINKFLAGS', 'comdlg32.lib')
   207 				self.compiler.AddToListVar('POSTLINKFLAGS', 'advapi32.lib')
   208 				self.compiler.AddToListVar('POSTLINKFLAGS', 'shell32.lib')
   209 				self.compiler.AddToListVar('POSTLINKFLAGS', 'ole32.lib')
   210 				self.compiler.AddToListVar('POSTLINKFLAGS', 'oleaut32.lib')
   211 				self.compiler.AddToListVar('POSTLINKFLAGS', 'uuid.lib')
   212 				self.compiler.AddToListVar('POSTLINKFLAGS', 'odbc32.lib')
   213 				self.compiler.AddToListVar('POSTLINKFLAGS', 'odbccp32.lib')
   214 
   215 			#Optimization
   216 			if AMBuild.options.opt == '1':
   217 				self.compiler.AddToListVar('CDEFINES', 'NDEBUG')
   218 				if self.vendor == 'gcc' or self.vendor == 'clang':
   219 					self.compiler.AddToListVar('CFLAGS', '-O3')
   220 				elif self.vendor == 'msvc':
   221 					self.compiler.AddToListVar('CFLAGS', '/Ox')
   222 					self.compiler.AddToListVar('POSTLINKFLAGS', '/OPT:ICF')
   223 					self.compiler.AddToListVar('POSTLINKFLAGS', '/OPT:REF')
   224 
   225 			#Debugging
   226 			if AMBuild.options.debug == '1':
   227 				self.compiler.AddToListVar('CDEFINES', 'DEBUG')
   228 				self.compiler.AddToListVar('CDEFINES', '_DEBUG')
   229 				if self.vendor == 'msvc':
   230 					self.compiler.AddToListVar('CFLAGS', '/Od')
   231 					self.compiler.AddToListVar('CFLAGS', '/RTC1')
   232 			
   233 			#This needs to be after our optimization flags which could otherwise disable it.
   234 			if self.vendor == 'msvc':
   235 				# Don't omit frame pointer
   236 				self.compiler.AddToListVar('CFLAGS', '/Oy-')
   237 
   238 			#Platform-specifics
   239 			if AMBuild.target['platform'] == 'linux':
   240 				self.compiler.AddToListVar('CDEFINES', '_LINUX')
   241 				self.compiler.AddToListVar('CDEFINES', 'POSIX')
   242 				if self.vendor == 'gcc':
   243 					self.compiler.AddToListVar('POSTLINKFLAGS', '-static-libgcc')
   244 				if self.vendor == 'clang':
   245 					self.compiler.AddToListVar('POSTLINKFLAGS', '-lgcc_eh')
   246 			elif AMBuild.target['platform'] == 'darwin':
   247 				self.compiler.AddToListVar('CDEFINES', 'OSX')
   248 				self.compiler.AddToListVar('CDEFINES', '_OSX')
   249 				self.compiler.AddToListVar('CDEFINES', 'POSIX')
   250 				self.compiler.AddToListVar('POSTLINKFLAGS', '-mmacosx-version-min=10.5')
   251 				self.compiler.AddToListVar('POSTLINKFLAGS', ['-arch', 'i386'])
   252 				self.compiler.AddToListVar('POSTLINKFLAGS', '-lstdc++')
   253 
   254 				# For OS X dylib versioning
   255 				import re
   256 				productFile = open(os.path.join(AMBuild.sourceFolder, 'product.version'), 'r')
   257 				productContents = productFile.read()
   258 				productFile.close()
   259 				m = re.match('(\d+)\.(\d+)\.(\d+).*', productContents)
   260 				if m == None:
   261 					self.version = '1.0.0'
   262 				else:
   263 					major, minor, release = m.groups()
   264 					self.version = '{0}.{1}.{2}'.format(major, minor, release)
   265 				AMBuild.cache.CacheVariable('version', self.version)
   266 			elif AMBuild.target['platform'] == 'windows':
   267 				self.compiler.AddToListVar('CDEFINES', 'WIN32')
   268 				self.compiler.AddToListVar('CDEFINES', '_WINDOWS')
   269 
   270 			#Finish up
   271 			self.compiler.AddToListVar('CDEFINES', 'SOURCEMOD_BUILD')
   272 			self.compiler.AddToListVar('CDEFINES', 'SM_GENERATED_BUILD')
   273 			self.compiler.AddToListVar('CINCLUDES',
   274 			                           os.path.join(AMBuild.outputFolder, 'includes'))
   275 			self.compiler.ToConfig(AMBuild, 'compiler')
   276 			AMBuild.cache.CacheVariable('vendor', self.vendor)
   277 			self.targetMap = { }
   278 			AMBuild.cache.CacheVariable('targetMap', self.targetMap)
   279 		else:
   280 			self.sdkInfo = AMBuild.cache['sdkInfo']
   281 			self.compiler.FromConfig(AMBuild, 'compiler')
   282 			self.targetMap = AMBuild.cache['targetMap']
   283 			self.hasMySql = AMBuild.cache['hasMySql']
   284 
   285 		if AMBuild.target['platform'] == 'windows':
   286 			self.compiler.AddToListVar('RCINCLUDES', os.path.join(AMBuild.sourceFolder, 'public'))
   287 			self.compiler.AddToListVar('RCINCLUDES',
   288 			                           os.path.join(AMBuild.outputFolder, 'includes'))
   289 		self.mmsPath = AMBuild.cache['MMSOURCE110']
   290 
   291 	def DefaultCompiler(self):
   292 		return self.compiler.Clone()
   293 
   294 	def JobMatters(self, jobname):
   295 		file = sys._getframe().f_code.co_filename
   296 		if AMBuild.mode == 'config':
   297 			self.targetMap[jobname] = file
   298 			return True
   299 		if len(AMBuild.args) == 0:
   300 			return True
   301 		if not jobname in AMBuild.args:
   302 			return False
   303 
   304 	def DefaultExtCompiler(self, path):
   305 		compiler = self.DefaultCompiler()
   306 		compiler['CXXINCLUDES'].append(os.path.join(AMBuild.sourceFolder, path))
   307 		compiler['CXXINCLUDES'].append(os.path.join(AMBuild.sourceFolder, path, 'sdk'))
   308 		compiler['CXXINCLUDES'].append(os.path.join(AMBuild.sourceFolder, 'public'))
   309 		compiler['CXXINCLUDES'].append(os.path.join(AMBuild.sourceFolder, 'public', 'extensions'))
   310 		compiler['CXXINCLUDES'].append(os.path.join(AMBuild.sourceFolder, 'public', 'sourcepawn'))
   311 		compiler['CXXINCLUDES'].append(os.path.join(AMBuild.sourceFolder, 'public', 'amtl'))
   312 		return compiler
   313 
   314 	def AutoVersion(self, folder, binary):
   315 		if AMBuild.target['platform'] == 'windows':
   316 			env = {'RCDEFINES': ['BINARY_NAME="' + binary.binaryFile + '"', 'SM_GENERATED_BUILD']}
   317 			binary.AddResourceFile(os.path.join(folder, 'version.rc' ), env)
   318 		elif AMBuild.target['platform'] == 'darwin' and isinstance(binary, Cpp.LibraryBuilder):
   319 			binary.compiler['POSTLINKFLAGS'].extend(['-compatibility_version', '1.0.0'])
   320 			binary.compiler['POSTLINKFLAGS'].extend(['-current_version', AMBuild.cache['version']])
   321 		else:
   322 			return
   323 
   324 	def ExtractDebugInfo(self, job, binary):
   325 		src = os.path.join('..', AMBuild.outputFolder, job.workFolder, binary.binaryFile)
   326 		job.AddCommand(ExtractDebugInfoCommand(binary, src))
   327 
   328 	def PreSetupHL2Job(self, job, builder, sdk):
   329 		info = self.sdkInfo[sdk]
   330 		sdkPath = AMBuild.cache[info['sdk']]
   331 		if AMBuild.target['platform'] == 'linux':
   332 			if sdk == 'ep1':
   333 				staticLibs = os.path.join(sdkPath, 'linux_sdk')
   334 			elif sdk == 'sdk2013':
   335 				staticLibs = os.path.join(sdkPath, 'lib', 'public', 'linux32')
   336 			else:
   337 				staticLibs = os.path.join(sdkPath, 'lib', 'linux')
   338 			workFolder = os.path.join(AMBuild.outputFolder, job.workFolder)
   339 			libs = []
   340 			if sdk in ['css', 'hl2dm', 'dods', 'tf2', 'l4d2']:
   341 				libs = ['tier1_i486.a', 'mathlib_i486.a', 'libvstdlib_srv.so', 'libtier0_srv.so']
   342 			elif sdk in ['l4d', 'nd', 'blade', 'insurgency', 'csgo']:
   343 				libs = ['tier1_i486.a', 'mathlib_i486.a', 'libvstdlib.so', 'libtier0.so']
   344 				if sdk in ['blade', 'insurgency', 'csgo']:
   345 					libs.append('interfaces_i486.a')
   346 			elif sdk == 'sdk2013':
   347 				libs = ['tier1.a', 'mathlib.a', 'libvstdlib_srv.so', 'libtier0_srv.so']
   348 			else:
   349 				libs = ['tier1_i486.a', 'mathlib_i486.a', 'vstdlib_i486.so', 'tier0_i486.so']
   350 			
   351 			for lib in libs:
   352 				link = os.path.join(workFolder, lib)
   353 				target = os.path.join(staticLibs, lib)
   354 				try:
   355 					os.lstat(link)
   356 				except:
   357 					job.AddCommand(SymlinkCommand(link, target))
   358 		elif AMBuild.target['platform'] == 'darwin':
   359 			if sdk == 'sdk2013':
   360 				staticLibs = os.path.join(sdkPath, 'lib', 'public', 'osx32')
   361 				libs = ['tier1.a', 'mathlib.a', 'libvstdlib.dylib', 'libtier0.dylib']
   362 			else:
   363 				staticLibs = os.path.join(sdkPath, 'lib', 'mac')
   364 				libs = ['tier1_i486.a', 'mathlib_i486.a', 'libvstdlib.dylib', 'libtier0.dylib']
   365 			workFolder = os.path.join(AMBuild.outputFolder, job.workFolder)
   366 			if sdk in ['insurgency', 'csgo']:
   367 				libs.append('interfaces_i486.a')
   368 			for lib in libs:
   369 				link = os.path.join(workFolder, lib)
   370 				target = os.path.join(staticLibs, lib)
   371 				try:
   372 					os.lstat(link)
   373 				except:
   374 					job.AddCommand(SymlinkCommand(link, target))
   375 		elif AMBuild.target['platform'] == 'windows':
   376 			libs = ['tier0', 'tier1', 'vstdlib', 'mathlib']
   377 			if sdk in ['swarm', 'blade', 'insurgency', 'csgo', 'dota']:
   378 				libs.append('interfaces')
   379 			for lib in libs:
   380 				libPath = os.path.join(sdkPath, 'lib', 'public', lib) + '.lib'
   381 				builder.RebuildIfNewer(libPath)
   382 				builder['POSTLINKFLAGS'].append(libPath)
   383 
   384 	def PostSetupHL2Job(self, job, builder, sdk):
   385 		if AMBuild.target['platform'] in ['linux', 'darwin']:
   386 			if sdk == 'sdk2013':
   387 				builder.AddObjectFiles(['tier1.a', 'mathlib.a'])
   388 			else:
   389 				builder.AddObjectFiles(['tier1_i486.a', 'mathlib_i486.a'])
   390 			
   391 			if sdk in ['blade', 'insurgency', 'csgo']:
   392 				builder.AddObjectFiles(['interfaces_i486.a'])
   393 	
   394 	def DefaultHL2Compiler(self, path, sdk, noLink = False, oldMms = '-legacy'):
   395 		compiler = self.DefaultExtCompiler(path)
   396 
   397 		mms = 'core'
   398 		if sdk == 'ep1':
   399 			mms += oldMms
   400 
   401 		compiler['CXXINCLUDES'].append(os.path.join(self.mmsPath, mms))
   402 		compiler['CXXINCLUDES'].append(os.path.join(self.mmsPath, mms, 'sourcehook'))
   403 
   404 		info = self.possibleSdks
   405 		compiler['CDEFINES'].extend(['SE_' + info[i]['name'] + '=' + info[i]['def'] for i in info])
   406 
   407 		paths = [['public'], ['public', 'engine'], ['public', 'mathlib'], ['public', 'vstdlib'],
   408 						 ['public', 'tier0'], ['public', 'tier1']]
   409 		if sdk == 'ep1' or sdk == 'darkm':
   410 			paths.append(['public', 'dlls'])
   411 			paths.append(['game_shared'])
   412 		else:
   413 			paths.append(['public', 'game', 'server'])
   414 			paths.append(['public', 'toolframework'])
   415 			paths.append(['game', 'shared'])
   416 			paths.append(['common'])
   417 
   418 		info = self.sdkInfo[sdk]
   419 		sdkPath = AMBuild.cache[info['sdk']]
   420 
   421 		compiler['CDEFINES'].append('SOURCE_ENGINE=' + info['def'])
   422 		
   423 		if sdk == 'sdk2013' and isinstance(compiler.cxx, Cpp.CompatGCC):
   424 			# The 2013 SDK already has these in public/tier0/basetypes.h
   425 			compiler['CDEFINES'].remove('stricmp=strcasecmp')
   426 			compiler['CDEFINES'].remove('_stricmp=strcasecmp')
   427 			compiler['CDEFINES'].remove('_snprintf=snprintf')
   428 			compiler['CDEFINES'].remove('_vsnprintf=vsnprintf')
   429 
   430 		if sdk in ['swarm', 'blade', 'insurgency', 'csgo', 'dota']:
   431 			if AMBuild.target['platform'] == 'windows':
   432 				compiler['CDEFINES'].extend(['COMPILER_MSVC', 'COMPILER_MSVC32'])
   433 			else:
   434 				compiler['CDEFINES'].extend(['COMPILER_GCC'])
   435 
   436 		if sdk == 'sdk2013' and AMBuild.target['platform'] == 'darwin':
   437 			compiler['POSTLINKFLAGS'].append('-liconv')
   438 		
   439 		if sdk in ['css','hl2dm','dods','sdk2013','tf2','l4d2']:
   440 			if AMBuild.target['platform'] == 'linux' or AMBuild.target['platform'] == 'darwin':
   441 				compiler['CDEFINES'].append('NO_MALLOC_OVERRIDE')
   442 
   443 		if AMBuild.target['platform'] == 'linux':
   444 			if sdk == 'ep1':
   445 				staticLibs = os.path.join(sdkPath, 'linux_sdk')
   446 			elif sdk == 'sdk2013':
   447 				staticLibs = os.path.join(sdkPath, 'lib', 'public', 'linux32')
   448 			else:
   449 				staticLibs = os.path.join(sdkPath, 'lib', 'linux')
   450 		elif AMBuild.target['platform'] == 'darwin':
   451 			if sdk == 'sdk2013':
   452 				staticLibs = os.path.join(sdkPath, 'lib', 'public', 'osx32')
   453 			else:
   454 				staticLibs = os.path.join(sdkPath, 'lib', 'mac')
   455 
   456 		for i in paths:
   457 			compiler['CXXINCLUDES'].append(os.path.join(sdkPath, *i))
   458 
   459 		if not noLink:
   460 			if AMBuild.target['platform'] == 'linux':
   461 				compiler['POSTLINKFLAGS'][0:0] = ['-lm']
   462 				if sdk in ['css', 'hl2dm', 'dods', 'tf2', 'sdk2013', 'l4d2']:
   463 					compiler['POSTLINKFLAGS'][0:0] = ['libtier0_srv.so']
   464 					compiler['POSTLINKFLAGS'][0:0] = ['libvstdlib_srv.so']
   465 				elif sdk in ['l4d', 'nd', 'blade', 'insurgency', 'csgo']:
   466 					compiler['POSTLINKFLAGS'][0:0] = ['libtier0.so']
   467 					compiler['POSTLINKFLAGS'][0:0] = ['libvstdlib.so']
   468 				else:
   469 					compiler['POSTLINKFLAGS'][0:0] = ['tier0_i486.so']
   470 					compiler['POSTLINKFLAGS'][0:0] = ['vstdlib_i486.so']
   471 			elif AMBuild.target['platform'] == 'darwin':
   472 				compiler['POSTLINKFLAGS'][0:0] = ['libtier0.dylib']
   473 				compiler['POSTLINKFLAGS'][0:0] = ['libvstdlib.dylib']
   474 
   475 		return compiler
   476 		
   477 	def ResolveEnvPath(self, env, defaultDir):
   478 		if env in os.environ:
   479 			path = os.environ[env]
   480 			if os.path.isdir(path):
   481 				return path
   482 		else:
   483 			head = os.getcwd()
   484 			oldhead = None
   485 			while head != None and head != oldhead:
   486 				path = os.path.join(head, defaultDir)
   487 				if os.path.isdir(path):
   488 					return path
   489 				oldhead = head
   490 				head, tail = os.path.split(head)
   491 		return None
   492 
   493 sm = SM()
   494 globals = {
   495 	'SM': sm
   496 }
   497 
   498 AMBuild.Include(os.path.join('tools', 'buildbot', 'Versioning'), globals)
   499 
   500 FileList = [
   501 		['loader', 'AMBuilder'],
   502 		['core', 'AMBuilder'],
   503 		['core', 'logic', 'AMBuilder'],
   504 		['extensions', 'bintools', 'AMBuilder'],
   505 		['extensions', 'clientprefs', 'AMBuilder'],
   506 		['extensions', 'cstrike', 'AMBuilder'],
   507 		['extensions', 'curl', 'AMBuilder'],
   508 		['extensions', 'geoip', 'AMBuilder'],
   509 		['extensions', 'mysql', 'AMBuilder'],
   510 		['extensions', 'sdkhooks', 'AMBuilder'],
   511 		['extensions', 'sdktools', 'AMBuilder'],
   512 		['extensions', 'topmenus', 'AMBuilder'],
   513 		['extensions', 'updater', 'AMBuilder'],
   514 		['extensions', 'sqlite', 'AMBuilder'],
   515 		['extensions', 'regex', 'AMBuilder'],
   516 		['extensions', 'tf2', 'AMBuilder'],
   517 		['sourcepawn', 'jit', 'AMBuilder'],
   518 		['sourcepawn', 'compiler', 'AMBuilder'],
   519 		['plugins', 'AMBuilder'],
   520 		['tools', 'buildbot', 'PackageScript'],
   521 		['tools', 'buildbot', 'BreakpadSymbols']
   522 	]
   523 
   524 if not sm.hasMySql:
   525 	FileList.remove(['extensions', 'mysql', 'AMBuilder'])
   526 
   527 for parts in FileList:
   528 	AMBuild.Include(os.path.join(*parts), globals)
   529