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