AMBuildScript
author David Anderson <danderson@mozilla.com>
Thu Aug 08 20:26:36 2013 -0700 (2013-08-08)
changeset 3979 bdad6d9c8351
parent 3976 bc77cfde7c5c
child 3981 af3681eade3f
permissions -rw-r--r--
Use SSE when available for floating-point operations (bug 5841, r=her).
     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 = { 'MMSOURCE110': 'mmsource-1.10', '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-narrowing')
   154 				self.compiler.AddToListVar('CFLAGS', '-Wno-uninitialized')
   155 				self.compiler.AddToListVar('CFLAGS', '-Wno-unused')
   156 				self.compiler.AddToListVar('CFLAGS', '-Wno-switch')
   157 				self.compiler.AddToListVar('CFLAGS', '-msse')
   158 				self.compiler.AddToListVar('CFLAGS', '-g3')
   159 				self.compiler.AddToListVar('CFLAGS', '-m32')
   160 				self.compiler.AddToListVar('POSTLINKFLAGS', '-m32')
   161 				self.compiler.AddToListVar('CXXFLAGS', '-fno-exceptions')
   162 				self.compiler.AddToListVar('CXXFLAGS', '-fno-threadsafe-statics')
   163 				self.compiler.AddToListVar('CXXFLAGS', '-Wno-non-virtual-dtor')
   164 				self.compiler.AddToListVar('CXXFLAGS', '-Wno-overloaded-virtual')
   165 				if (self.vendor == 'gcc' and cxx.majorVersion >= 4 and cxx.minorVersion >= 7) or \
   166 						(self.vendor == 'clang' and cxx.majorVersion >= 3):
   167 					self.compiler.AddToListVar('CXXFLAGS', '-Wno-delete-non-virtual-dtor')
   168 				self.compiler.AddToListVar('CDEFINES', 'HAVE_STDINT_H')
   169 				self.compiler.AddToListVar('CDEFINES', 'GNUC')
   170 				if self.vendor == 'gcc':
   171 					self.compiler.AddToListVar('CFLAGS', '-mfpmath=sse')
   172 			elif isinstance(cxx, Cpp.MSVC):
   173 				self.vendor = 'msvc'
   174 				if AMBuild.options.debug == '1':
   175 					self.compiler.AddToListVar('CFLAGS', '/MTd')
   176 					self.compiler.AddToListVar('POSTLINKFLAGS', '/NODEFAULTLIB:libcmt')
   177 				else:
   178 					self.compiler.AddToListVar('CFLAGS', '/MT')
   179 				self.compiler.AddToListVar('CDEFINES', '_CRT_SECURE_NO_DEPRECATE')
   180 				self.compiler.AddToListVar('CDEFINES', '_CRT_SECURE_NO_WARNINGS')
   181 				self.compiler.AddToListVar('CDEFINES', '_CRT_NONSTDC_NO_DEPRECATE')
   182 				self.compiler.AddToListVar('CXXFLAGS', '/EHsc')
   183 				self.compiler.AddToListVar('CXXFLAGS', '/GR-')
   184 				self.compiler.AddToListVar('CFLAGS', '/W3')
   185 				self.compiler.AddToListVar('CFLAGS', '/nologo')
   186 				self.compiler.AddToListVar('CFLAGS', '/Zi')
   187 				self.compiler.AddToListVar('CXXFLAGS', '/TP')
   188 				self.compiler.AddToListVar('POSTLINKFLAGS', '/DEBUG')
   189 				self.compiler.AddToListVar('POSTLINKFLAGS', '/MACHINE:X86')
   190 				self.compiler.AddToListVar('POSTLINKFLAGS', '/SUBSYSTEM:WINDOWS')
   191 				self.compiler.AddToListVar('POSTLINKFLAGS', 'kernel32.lib')
   192 				self.compiler.AddToListVar('POSTLINKFLAGS', 'user32.lib')
   193 				self.compiler.AddToListVar('POSTLINKFLAGS', 'gdi32.lib')
   194 				self.compiler.AddToListVar('POSTLINKFLAGS', 'winspool.lib')
   195 				self.compiler.AddToListVar('POSTLINKFLAGS', 'comdlg32.lib')
   196 				self.compiler.AddToListVar('POSTLINKFLAGS', 'advapi32.lib')
   197 				self.compiler.AddToListVar('POSTLINKFLAGS', 'shell32.lib')
   198 				self.compiler.AddToListVar('POSTLINKFLAGS', 'ole32.lib')
   199 				self.compiler.AddToListVar('POSTLINKFLAGS', 'oleaut32.lib')
   200 				self.compiler.AddToListVar('POSTLINKFLAGS', 'uuid.lib')
   201 				self.compiler.AddToListVar('POSTLINKFLAGS', 'odbc32.lib')
   202 				self.compiler.AddToListVar('POSTLINKFLAGS', 'odbccp32.lib')
   203 
   204 			#Optimization
   205 			if AMBuild.options.opt == '1':
   206 				self.compiler.AddToListVar('CDEFINES', 'NDEBUG')
   207 				if self.vendor == 'gcc' or self.vendor == 'clang':
   208 					self.compiler.AddToListVar('CFLAGS', '-O3')
   209 				elif self.vendor == 'msvc':
   210 					self.compiler.AddToListVar('CFLAGS', '/Ox')
   211 					self.compiler.AddToListVar('POSTLINKFLAGS', '/OPT:ICF')
   212 					self.compiler.AddToListVar('POSTLINKFLAGS', '/OPT:REF')
   213 
   214 			#Debugging
   215 			if AMBuild.options.debug == '1':
   216 				self.compiler.AddToListVar('CDEFINES', 'DEBUG')
   217 				self.compiler.AddToListVar('CDEFINES', '_DEBUG')
   218 				if self.vendor == 'msvc':
   219 					self.compiler.AddToListVar('CFLAGS', '/Od')
   220 					self.compiler.AddToListVar('CFLAGS', '/RTC1')
   221 			
   222 			#This needs to be after our optimization flags which could otherwise disable it.
   223 			if self.vendor == 'msvc':
   224 				# Don't omit frame pointer
   225 				self.compiler.AddToListVar('CFLAGS', '/Oy-')
   226 
   227 			#Platform-specifics
   228 			if AMBuild.target['platform'] == 'linux':
   229 				self.compiler.AddToListVar('CDEFINES', '_LINUX')
   230 				self.compiler.AddToListVar('CDEFINES', 'POSIX')
   231 				if self.vendor == 'gcc':
   232 					self.compiler.AddToListVar('POSTLINKFLAGS', '-static-libgcc')
   233 				if self.vendor == 'clang':
   234 					self.compiler.AddToListVar('POSTLINKFLAGS', '-lgcc_eh')
   235 			elif AMBuild.target['platform'] == 'darwin':
   236 				self.compiler.AddToListVar('CDEFINES', 'OSX')
   237 				self.compiler.AddToListVar('CDEFINES', '_OSX')
   238 				self.compiler.AddToListVar('CDEFINES', 'POSIX')
   239 				self.compiler.AddToListVar('POSTLINKFLAGS', '-mmacosx-version-min=10.5')
   240 				self.compiler.AddToListVar('POSTLINKFLAGS', ['-arch', 'i386'])
   241 				self.compiler.AddToListVar('POSTLINKFLAGS', '-lstdc++')
   242 
   243 				# For OS X dylib versioning
   244 				import re
   245 				productFile = open(os.path.join(AMBuild.sourceFolder, 'product.version'), 'r')
   246 				productContents = productFile.read()
   247 				productFile.close()
   248 				m = re.match('(\d+)\.(\d+)\.(\d+).*', productContents)
   249 				if m == None:
   250 					self.version = '1.0.0'
   251 				else:
   252 					major, minor, release = m.groups()
   253 					self.version = '{0}.{1}.{2}'.format(major, minor, release)
   254 				AMBuild.cache.CacheVariable('version', self.version)
   255 			elif AMBuild.target['platform'] == 'windows':
   256 				self.compiler.AddToListVar('CDEFINES', 'WIN32')
   257 				self.compiler.AddToListVar('CDEFINES', '_WINDOWS')
   258 
   259 			#Finish up
   260 			self.compiler.AddToListVar('CDEFINES', 'SOURCEMOD_BUILD')
   261 			self.compiler.AddToListVar('CDEFINES', 'SM_GENERATED_BUILD')
   262 			self.compiler.AddToListVar('CINCLUDES',
   263 			                           os.path.join(AMBuild.outputFolder, 'includes'))
   264 			self.compiler.ToConfig(AMBuild, 'compiler')
   265 			AMBuild.cache.CacheVariable('vendor', self.vendor)
   266 			self.targetMap = { }
   267 			AMBuild.cache.CacheVariable('targetMap', self.targetMap)
   268 		else:
   269 			self.sdkInfo = AMBuild.cache['sdkInfo']
   270 			self.compiler.FromConfig(AMBuild, 'compiler')
   271 			self.targetMap = AMBuild.cache['targetMap']
   272 			self.hasMySql = AMBuild.cache['hasMySql']
   273 
   274 		if AMBuild.target['platform'] == 'windows':
   275 			self.compiler.AddToListVar('RCINCLUDES', os.path.join(AMBuild.sourceFolder, 'public'))
   276 			self.compiler.AddToListVar('RCINCLUDES',
   277 			                           os.path.join(AMBuild.outputFolder, 'includes'))
   278 		self.mmsPath = AMBuild.cache['MMSOURCE110']
   279 
   280 	def DefaultCompiler(self):
   281 		return self.compiler.Clone()
   282 
   283 	def JobMatters(self, jobname):
   284 		file = sys._getframe().f_code.co_filename
   285 		if AMBuild.mode == 'config':
   286 			self.targetMap[jobname] = file
   287 			return True
   288 		if len(AMBuild.args) == 0:
   289 			return True
   290 		if not jobname in AMBuild.args:
   291 			return False
   292 
   293 	def DefaultExtCompiler(self, path):
   294 		compiler = self.DefaultCompiler()
   295 		compiler['CXXINCLUDES'].append(os.path.join(AMBuild.sourceFolder, path))
   296 		compiler['CXXINCLUDES'].append(os.path.join(AMBuild.sourceFolder, path, 'sdk'))
   297 		compiler['CXXINCLUDES'].append(os.path.join(AMBuild.sourceFolder, 'public'))
   298 		compiler['CXXINCLUDES'].append(os.path.join(AMBuild.sourceFolder, 'public', 'extensions'))
   299 		compiler['CXXINCLUDES'].append(os.path.join(AMBuild.sourceFolder, 'public', 'sourcepawn'))
   300 		return compiler
   301 
   302 	def AutoVersion(self, folder, binary):
   303 		if AMBuild.target['platform'] == 'windows':
   304 			env = {'RCDEFINES': ['BINARY_NAME="' + binary.binaryFile + '"', 'SM_GENERATED_BUILD']}
   305 			binary.AddResourceFile(os.path.join(folder, 'version.rc' ), env)
   306 		elif AMBuild.target['platform'] == 'darwin' and isinstance(binary, Cpp.LibraryBuilder):
   307 			binary.compiler['POSTLINKFLAGS'].extend(['-compatibility_version', '1.0.0'])
   308 			binary.compiler['POSTLINKFLAGS'].extend(['-current_version', AMBuild.cache['version']])
   309 		else:
   310 			return
   311 
   312 	def ExtractDebugInfo(self, job, binary):
   313 		src = os.path.join('..', AMBuild.outputFolder, job.workFolder, binary.binaryFile)
   314 		job.AddCommand(ExtractDebugInfoCommand(binary, src))
   315 
   316 	def PreSetupHL2Job(self, job, builder, sdk):
   317 		info = self.sdkInfo[sdk]
   318 		sdkPath = AMBuild.cache[info['sdk']]
   319 		if AMBuild.target['platform'] == 'linux':
   320 			if sdk == 'ep1':
   321 				staticLibs = os.path.join(sdkPath, 'linux_sdk')
   322 			else:
   323 				staticLibs = os.path.join(sdkPath, 'lib', 'linux')
   324 			workFolder = os.path.join(AMBuild.outputFolder, job.workFolder)
   325 			if sdk in ['css', 'hl2dm', 'dods', 'tf2', 'l4d2']:
   326 				libs = ['tier1_i486.a', 'mathlib_i486.a', 'libvstdlib_srv.so', 'libtier0_srv.so']
   327 				for lib in libs:
   328 					link = os.path.join(workFolder, lib)
   329 					target = os.path.join(staticLibs, lib)
   330 					try:
   331 						os.lstat(link)
   332 					except:
   333 						job.AddCommand(SymlinkCommand(link, target))
   334 			elif sdk in ['l4d', 'nd', 'csgo']:
   335 				libs = ['tier1_i486.a', 'mathlib_i486.a', 'libvstdlib.so', 'libtier0.so']
   336 				if sdk == 'csgo':
   337 					libs.append('interfaces_i486.a')
   338 				for lib in libs:
   339 					link = os.path.join(workFolder, lib)
   340 					target = os.path.join(staticLibs, lib)
   341 					try:
   342 						os.lstat(link)
   343 					except:
   344 						job.AddCommand(SymlinkCommand(link, target))
   345 			else:
   346 				libs = ['tier1_i486.a', 'mathlib_i486.a', 'vstdlib_i486.so', 'tier0_i486.so']
   347 				for lib in libs:
   348 					link = os.path.join(workFolder, lib)
   349 					target = os.path.join(staticLibs, lib)
   350 					try:
   351 						os.lstat(link)
   352 					except:
   353 						job.AddCommand(SymlinkCommand(link, target))
   354 		elif AMBuild.target['platform'] == 'darwin':
   355 			staticLibs = os.path.join(sdkPath, 'lib', 'mac')
   356 			workFolder = os.path.join(AMBuild.outputFolder, job.workFolder)
   357 			libs = ['tier1_i486.a', 'mathlib_i486.a', 'libvstdlib.dylib', 'libtier0.dylib']
   358 			if sdk == 'csgo':
   359 				libs.append('interfaces_i486.a')
   360 			for lib in libs:
   361 				link = os.path.join(workFolder, lib)
   362 				target = os.path.join(staticLibs, lib)
   363 				try:
   364 					os.lstat(link)
   365 				except:
   366 					job.AddCommand(SymlinkCommand(link, target))
   367 		elif AMBuild.target['platform'] == 'windows':
   368 			libs = ['tier0', 'tier1', 'vstdlib', 'mathlib']
   369 			if sdk in ['swarm', 'csgo', 'dota']:
   370 				libs.append('interfaces')
   371 			for lib in libs:
   372 				libPath = os.path.join(sdkPath, 'lib', 'public', lib) + '.lib'
   373 				builder.RebuildIfNewer(libPath)
   374 				builder['POSTLINKFLAGS'].append(libPath)
   375 
   376 	def PostSetupHL2Job(self, job, builder, sdk):
   377 		if AMBuild.target['platform'] in ['linux', 'darwin']:
   378 			builder.AddObjectFiles(['tier1_i486.a', 'mathlib_i486.a'])
   379 			if sdk == 'csgo':
   380 				builder.AddObjectFiles(['interfaces_i486.a'])
   381 	
   382 	def DefaultHL2Compiler(self, path, sdk, noLink = False, oldMms = '-legacy'):
   383 		compiler = self.DefaultExtCompiler(path)
   384 
   385 		mms = 'core'
   386 		if sdk == 'ep1':
   387 			mms += oldMms
   388 
   389 		compiler['CXXINCLUDES'].append(os.path.join(self.mmsPath, mms))
   390 		compiler['CXXINCLUDES'].append(os.path.join(self.mmsPath, mms, 'sourcehook'))
   391 
   392 		info = self.possibleSdks
   393 		compiler['CDEFINES'].extend(['SE_' + info[i]['name'] + '=' + info[i]['def'] for i in info])
   394 				
   395 		# We don't build for Portal 2 (yet?, ever?), but using this define in code as 
   396 		# it saves trouble if we ever need to
   397 		compiler['CDEFINES'].append('SE_PORTAL2=14')
   398 
   399 		paths = [['public'], ['public', 'engine'], ['public', 'mathlib'], ['public', 'vstdlib'],
   400 						 ['public', 'tier0'], ['public', 'tier1']]
   401 		if sdk == 'ep1' or sdk == 'darkm':
   402 			paths.append(['public', 'dlls'])
   403 			paths.append(['game_shared'])
   404 		else:
   405 			paths.append(['public', 'game', 'server'])
   406 			paths.append(['public', 'toolframework'])
   407 			paths.append(['game', 'shared'])
   408 			paths.append(['common'])
   409 
   410 		info = self.sdkInfo[sdk]
   411 		sdkPath = AMBuild.cache[info['sdk']]
   412 
   413 		compiler['CDEFINES'].append('SOURCE_ENGINE=' + info['def'])
   414 
   415 		if sdk in ['swarm','csgo','dota']:
   416 			if AMBuild.target['platform'] == 'windows':
   417 				compiler['CDEFINES'].extend(['COMPILER_MSVC', 'COMPILER_MSVC32'])
   418 			else:
   419 				compiler['CDEFINES'].extend(['COMPILER_GCC'])
   420 
   421 		if sdk == 'ep1':
   422 			if AMBuild.target['platform'] == 'linux':
   423 				staticLibs = os.path.join(sdkPath, 'linux_sdk')
   424 		else:
   425 			if AMBuild.target['platform'] == 'linux':
   426 				staticLibs = os.path.join(sdkPath, 'lib', 'linux')
   427 			elif AMBuild.target['platform'] == 'darwin':
   428 				staticLibs = os.path.join(sdkPath, 'lib', 'mac')
   429 
   430 		for i in paths:
   431 			compiler['CXXINCLUDES'].append(os.path.join(sdkPath, *i))
   432 
   433 		if not noLink:
   434 			if AMBuild.target['platform'] == 'linux':
   435 				compiler['POSTLINKFLAGS'][0:0] = ['-lm']
   436 				if sdk in ['css', 'hl2dm', 'dods', 'tf2', 'l4d2']:
   437 					compiler['POSTLINKFLAGS'][0:0] = ['libtier0_srv.so']
   438 					compiler['POSTLINKFLAGS'][0:0] = ['libvstdlib_srv.so']
   439 				elif sdk in ['l4d', 'nd', 'csgo']:
   440 					compiler['POSTLINKFLAGS'][0:0] = ['libtier0.so']
   441 					compiler['POSTLINKFLAGS'][0:0] = ['libvstdlib.so']
   442 				else:
   443 					compiler['POSTLINKFLAGS'][0:0] = ['tier0_i486.so']
   444 					compiler['POSTLINKFLAGS'][0:0] = ['vstdlib_i486.so']
   445 			elif AMBuild.target['platform'] == 'darwin':
   446 				compiler['POSTLINKFLAGS'][0:0] = ['libtier0.dylib']
   447 				compiler['POSTLINKFLAGS'][0:0] = ['libvstdlib.dylib']
   448 
   449 		return compiler
   450 		
   451 	def ResolveEnvPath(self, env, defaultDir):
   452 		if env in os.environ:
   453 			path = os.environ[env]
   454 			if os.path.isdir(path):
   455 				return path
   456 		else:
   457 			head = os.getcwd()
   458 			oldhead = None
   459 			while head != None and head != oldhead:
   460 				path = os.path.join(head, defaultDir)
   461 				if os.path.isdir(path):
   462 					return path
   463 				oldhead = head
   464 				head, tail = os.path.split(head)
   465 		return None
   466 
   467 sm = SM()
   468 globals = {
   469 	'SM': sm
   470 }
   471 
   472 AMBuild.Include(os.path.join('tools', 'buildbot', 'Versioning'), globals)
   473 
   474 FileList = [
   475 		['loader', 'AMBuilder'],
   476 		['core', 'AMBuilder'],
   477 		['core', 'logic', 'AMBuilder'],
   478 		['extensions', 'bintools', 'AMBuilder'],
   479 		['extensions', 'clientprefs', 'AMBuilder'],
   480 		['extensions', 'cstrike', 'AMBuilder'],
   481 		['extensions', 'curl', 'AMBuilder'],
   482 		['extensions', 'geoip', 'AMBuilder'],
   483 		['extensions', 'mysql', 'AMBuilder'],
   484 		['extensions', 'sdkhooks', 'AMBuilder'],
   485 		['extensions', 'sdktools', 'AMBuilder'],
   486 		['extensions', 'topmenus', 'AMBuilder'],
   487 		['extensions', 'updater', 'AMBuilder'],
   488 		['extensions', 'sqlite', 'AMBuilder'],
   489 		['extensions', 'regex', 'AMBuilder'],
   490 		['extensions', 'tf2', 'AMBuilder'],
   491 		['sourcepawn', 'jit', 'AMBuilder'],
   492 		['sourcepawn', 'compiler', 'AMBuilder'],
   493 		['plugins', 'AMBuilder'],
   494 		['tools', 'buildbot', 'PackageScript'],
   495 		['tools', 'buildbot', 'BreakpadSymbols']
   496 	]
   497 
   498 if not sm.hasMySql:
   499 	FileList.remove(['extensions', 'mysql', 'AMBuilder'])
   500 
   501 for parts in FileList:
   502 	AMBuild.Include(os.path.join(*parts), globals)
   503