AMBuildScript
changeset 4182 8ef93b2feddf
parent 4144 353e86f4c6ab
child 4183 8cd5033099bb
     1.1 --- a/AMBuildScript	Sat Dec 28 08:42:50 2013 -0500
     1.2 +++ b/AMBuildScript	Mon Dec 30 17:50:56 2013 -0500
     1.3 @@ -1,529 +1,415 @@
     1.4 -# vim: set ts=2 sw=2 tw=99 noet ft=python:
     1.5 -import os
     1.6 -import sys
     1.7 -from ambuild.command import Command
     1.8 -from ambuild.command import ShellCommand
     1.9 -from ambuild.command import SymlinkCommand
    1.10 -
    1.11 -class ExtractDebugInfoCommand(Command):
    1.12 -	def __init__(self, binary, outfile):
    1.13 -		Command.__init__(self)
    1.14 -		self.binary = binary
    1.15 -		self.outfile = outfile
    1.16 -
    1.17 -	def run(self, runner, job):
    1.18 -		if AMBuild.cache['debug']:
    1.19 -			return
    1.20 -
    1.21 -		if not self.binary.NeedsRelink(self.outfile):
    1.22 -			return
    1.23 -
    1.24 -		if AMBuild.target['platform'] == 'linux':
    1.25 -			job.AddCommand(ShellCommand('objcopy --only-keep-debug ' + self.outfile + ' ' + self.outfile + '.dbg'))
    1.26 -			job.AddCommand(ShellCommand('objcopy --strip-debug ' + self.outfile))
    1.27 -			job.AddCommand(ShellCommand('objcopy --add-gnu-debuglink=' + os.path.basename(self.outfile) + '.dbg ' + self.outfile))
    1.28 -		elif AMBuild.target['platform'] == 'darwin':
    1.29 -			job.AddCommand(ShellCommand('dsymutil ' + self.outfile))
    1.30 -			job.AddCommand(ShellCommand('strip -S ' + self.outfile))
    1.31 -
    1.32 -class SM:
    1.33 -	def __init__(self):
    1.34 -		self.compiler = Cpp.Compiler()
    1.35 -
    1.36 -		#Build SDK info
    1.37 -		self.possibleSdks = { }
    1.38 -		self.possibleSdks['ep1'] =   {'sdk': 'HL2SDK',          'ext': '1.ep1',   'def': '1',
    1.39 -		                         'name': 'EPISODEONE',     'platform': ['windows', 'linux'],
    1.40 -		                         'dir': 'hl2sdk'}
    1.41 -		self.possibleSdks['ep2'] =   {'sdk': 'HL2SDKOB',        'ext': '2.ep2',   'def': '3',
    1.42 -		                         'name': 'ORANGEBOX',      'platform': ['windows', 'linux'],
    1.43 -		                         'dir': 'hl2sdk-ob'}
    1.44 -		self.possibleSdks['css'] =   {'sdk': 'HL2SDKCSS',       'ext': '2.css',     'def': '6',
    1.45 -		                         'name': 'CSS',            'platform': ['windows', 'linux', 'darwin'],
    1.46 -		                         'dir': 'hl2sdk-css'}
    1.47 -		self.possibleSdks['hl2dm'] = {'sdk': 'HL2SDKHL2DM',     'ext': '2.hl2dm',   'def': '7',
    1.48 -		                         'name': 'HL2DM',          'platform': ['windows', 'linux', 'darwin'],
    1.49 -		                        'dir': 'hl2sdk-hl2dm'}
    1.50 -		self.possibleSdks['dods'] =  {'sdk': 'HL2SDKDODS',      'ext': '2.dods',    'def': '8',
    1.51 -		                         'name': 'DODS',           'platform': ['windows', 'linux', 'darwin'],
    1.52 -		                        'dir': 'hl2sdk-dods'}
    1.53 -		self.possibleSdks['sdk2013'] =   {'sdk': 'HL2SDK2013',  'ext': '2.sdk2013', 'def': '9',
    1.54 -		                         'name': 'SDK2013',        'platform': ['windows', 'linux', 'darwin'],
    1.55 -		                        'dir': 'hl2sdk-2013'}
    1.56 -		self.possibleSdks['tf2'] =   {'sdk': 'HL2SDKTF2',       'ext': '2.tf2',     'def': '10',
    1.57 -		                         'name': 'TF2',            'platform': ['windows', 'linux', 'darwin'],
    1.58 -		                        'dir': 'hl2sdk-tf2'}
    1.59 -		self.possibleSdks['l4d'] =   {'sdk': 'HL2SDKL4D',       'ext': '2.l4d',     'def': '11',
    1.60 -		                         'name': 'LEFT4DEAD',      'platform': ['windows', 'linux', 'darwin'],
    1.61 -		                         'dir': 'hl2sdk-l4d'}
    1.62 -		self.possibleSdks['nd'] =    {'sdk': 'HL2SDKND',        'ext': '2.nd',      'def': '12',
    1.63 -		                         'name': 'NUCLEARDAWN',    'platform': ['windows', 'linux', 'darwin'],
    1.64 -		                         'dir': 'hl2sdk-nd'}
    1.65 -		self.possibleSdks['l4d2'] =  {'sdk': 'HL2SDKL4D2',      'ext': '2.l4d2',    'def': '13',
    1.66 -		                         'name': 'LEFT4DEAD2',     'platform': ['windows', 'linux', 'darwin'],
    1.67 -		                         'dir': 'hl2sdk-l4d2'}
    1.68 -		self.possibleSdks['darkm'] = {'sdk': 'HL2SDK-DARKM',    'ext': '2.darkm',   'def': '2',
    1.69 -		                         'name': 'DARKMESSIAH',    'platform': ['windows'],
    1.70 -		                          'dir': 'hl2sdk-darkm'}
    1.71 -		self.possibleSdks['swarm'] = {'sdk': 'HL2SDK-SWARM',    'ext': '2.swarm',   'def': '14',
    1.72 -		                         'name': 'ALIENSWARM',     'platform': ['windows'],
    1.73 -		                         'dir': 'hl2sdk-swarm'}
    1.74 -		self.possibleSdks['bgt'] =   {'sdk': 'HL2SDK-BGT',      'ext': '2.bgt',     'def': '4',
    1.75 -		                         'name': 'BLOODYGOODTIME', 'platform': ['windows'],
    1.76 -		                         'dir': 'hl2sdk-bgt'}
    1.77 -		self.possibleSdks['eye'] =   {'sdk': 'HL2SDK-EYE',      'ext': '2.eye',     'def': '5',
    1.78 -		                         'name': 'EYE',            'platform': ['windows'],
    1.79 -		                         'dir': 'hl2sdk-eye'}
    1.80 -		self.possibleSdks['csgo'] =  {'sdk': 'HL2SDKCSGO',     'ext': '2.csgo',     'def': '18',
    1.81 -		                         'name': 'CSGO',           'platform': ['windows', 'linux', 'darwin'],
    1.82 -		                         'dir': 'hl2sdk-csgo'}
    1.83 -		self.possibleSdks['dota'] =  {'sdk': 'HL2SDKDOTA',     'ext': '2.dota',     'def': '19',
    1.84 -		                         'name': 'DOTA',           'platform': ['windows'],
    1.85 -		                         'dir': 'hl2sdk-dota'}
    1.86 -		self.possibleSdks['portal2'] = {'sdk': 'HL2SDKPORTAL2','ext': '2.portal2',  'def': '15',
    1.87 -		                         'name': 'PORTAL2',           'platform': [],
    1.88 -		                         'dir': 'hl2sdk-portal2'}
    1.89 -		self.possibleSdks['blade'] = {'sdk': 'HL2SDKBLADE',    'ext': '2.blade',    'def': '16',
    1.90 -		                         'name': 'BLADE',             'platform': ['windows', 'linux'],
    1.91 -		                         'dir': 'hl2sdk-blade'}
    1.92 -		self.possibleSdks['insurgency'] = {'sdk': 'HL2SDKINSURGENCY', 'ext': '2.insurgency', 'def': '17',
    1.93 -		                         'name': 'INSURGENCY',        'platform': ['windows', 'linux', 'darwin'],
    1.94 -		                         'dir': 'hl2sdk-insurgency'}
    1.95 -		
    1.96 -		self.sdkInfo = { }
    1.97 -
    1.98 -		if AMBuild.mode == 'config':
    1.99 -			#Detect compilers
   1.100 -			self.compiler.DetectAll(AMBuild)
   1.101 -			
   1.102 -			self.hasMySql = AMBuild.options.hasMySql
   1.103 -			AMBuild.cache.CacheVariable('hasMySql', self.hasMySql)
   1.104 +# vim: set sts=2 ts=8 sw=2 tw=99 et ft=python:
   1.105 +import os, sys
   1.106  
   1.107 -			AMBuild.cache.CacheVariable('debug', AMBuild.options.debug)
   1.108 -			
   1.109 -			#Environment variable paths to external headers
   1.110 -			envvars = { 'MMSOURCE110': 'mmsource-1.10', 'MYSQL5': 'mysql-5.0' }
   1.111 -			
   1.112 -			#Look for Metamod:Source and MySQL if not disabled
   1.113 -			for env in envvars:
   1.114 -				if not self.hasMySql and env == 'MYSQL5':
   1.115 -					continue
   1.116 -				path = self.ResolveEnvPath(env, envvars[env])
   1.117 -				if path == None:
   1.118 -					raise Exception('Could not find a valid path for {0}'.format(env))
   1.119 -				AMBuild.cache.CacheVariable(env, path)
   1.120 -			
   1.121 -			#Look for SDK directories
   1.122 -			for sdk in self.possibleSdks:
   1.123 -				#Get list of SDKs to build against or 'all' or 'present'
   1.124 -				sdkList = AMBuild.options.sdks.split(',')
   1.125 -				#Build against all supported SDKs?
   1.126 -				useAll = sdkList[0] == 'all'
   1.127 -				#Build against supported SDKs that exist?
   1.128 -				usePresent = sdkList[0] == 'present'
   1.129 -
   1.130 -				info = self.possibleSdks[sdk]
   1.131 -				if AMBuild.target['platform'] in info['platform']:
   1.132 -					env = info['sdk']
   1.133 -					dir = info['dir']
   1.134 -					sdkPath = self.ResolveEnvPath(env, dir)
   1.135 -					if sdkPath == None:
   1.136 -						if useAll or sdk in sdkList:
   1.137 -							raise Exception('Could not find a valid path for {0}'.format(env))
   1.138 -						else:
   1.139 -							continue
   1.140 -					if useAll or usePresent or sdk in sdkList:
   1.141 -						self.sdkInfo[sdk] = info
   1.142 -						AMBuild.cache.CacheVariable(env, sdkPath)
   1.143 -
   1.144 -			if len(self.sdkInfo) < 1:
   1.145 -				raise Exception('At least one SDK must be available.')
   1.146 -				
   1.147 -			AMBuild.cache.CacheVariable('sdkInfo', self.sdkInfo)
   1.148 -
   1.149 -			#Set up defines
   1.150 -			cxx = self.compiler.cxx
   1.151 -			if isinstance(cxx, Cpp.CompatGCC):
   1.152 -				if isinstance(cxx, Cpp.GCC):
   1.153 -					self.vendor = 'gcc'
   1.154 -				elif isinstance(cxx, Cpp.Clang):
   1.155 -					self.vendor = 'clang'
   1.156 -				self.compiler.AddToListVar('CDEFINES', 'stricmp=strcasecmp')
   1.157 -				self.compiler.AddToListVar('CDEFINES', '_stricmp=strcasecmp')
   1.158 -				self.compiler.AddToListVar('CDEFINES', '_snprintf=snprintf')
   1.159 -				self.compiler.AddToListVar('CDEFINES', '_vsnprintf=vsnprintf')
   1.160 -				self.compiler.AddToListVar('CFLAGS', '-pipe')
   1.161 -				self.compiler.AddToListVar('CFLAGS', '-fno-strict-aliasing')
   1.162 -				if (self.vendor == 'gcc' and cxx.majorVersion >= 4) or self.vendor == 'clang':
   1.163 -					self.compiler.AddToListVar('CFLAGS', '-fvisibility=hidden')
   1.164 -					self.compiler.AddToListVar('CXXFLAGS', '-fvisibility-inlines-hidden')
   1.165 -				self.compiler.AddToListVar('CFLAGS', '-Wall')
   1.166 -				self.compiler.AddToListVar('CFLAGS', '-Werror')
   1.167 -				if (self.vendor == 'gcc' and cxx.majorVersion >= 4 and cxx.minorVersion >= 6) or self.vendor == 'clang':
   1.168 -					self.compiler.AddToListVar('CFLAGS', '-Wno-narrowing')
   1.169 -				self.compiler.AddToListVar('CFLAGS', '-Wno-uninitialized')
   1.170 -				self.compiler.AddToListVar('CFLAGS', '-Wno-unused')
   1.171 -				self.compiler.AddToListVar('CFLAGS', '-Wno-switch')
   1.172 -				self.compiler.AddToListVar('CFLAGS', '-msse')
   1.173 -				self.compiler.AddToListVar('CFLAGS', '-g3')
   1.174 -				self.compiler.AddToListVar('CFLAGS', '-m32')
   1.175 -				self.compiler.AddToListVar('POSTLINKFLAGS', '-m32')
   1.176 -				self.compiler.AddToListVar('CXXFLAGS', '-fno-exceptions')
   1.177 -				self.compiler.AddToListVar('CXXFLAGS', '-fno-threadsafe-statics')
   1.178 -				self.compiler.AddToListVar('CXXFLAGS', '-Wno-non-virtual-dtor')
   1.179 -				self.compiler.AddToListVar('CXXFLAGS', '-Wno-overloaded-virtual')
   1.180 -				if (self.vendor == 'gcc' and cxx.majorVersion >= 4 and cxx.minorVersion >= 7) or \
   1.181 -						(self.vendor == 'clang' and cxx.majorVersion >= 3):
   1.182 -					self.compiler.AddToListVar('CXXFLAGS', '-Wno-delete-non-virtual-dtor')
   1.183 -				self.compiler.AddToListVar('CDEFINES', 'HAVE_STDINT_H')
   1.184 -				self.compiler.AddToListVar('CDEFINES', 'GNUC')
   1.185 -				if self.vendor == 'gcc':
   1.186 -					self.compiler.AddToListVar('CFLAGS', '-mfpmath=sse')
   1.187 -			elif isinstance(cxx, Cpp.MSVC):
   1.188 -				self.vendor = 'msvc'
   1.189 -				if AMBuild.options.debug == '1':
   1.190 -					self.compiler.AddToListVar('CFLAGS', '/MTd')
   1.191 -					self.compiler.AddToListVar('POSTLINKFLAGS', '/NODEFAULTLIB:libcmt')
   1.192 -				else:
   1.193 -					self.compiler.AddToListVar('CFLAGS', '/MT')
   1.194 -				self.compiler.AddToListVar('CDEFINES', '_CRT_SECURE_NO_DEPRECATE')
   1.195 -				self.compiler.AddToListVar('CDEFINES', '_CRT_SECURE_NO_WARNINGS')
   1.196 -				self.compiler.AddToListVar('CDEFINES', '_CRT_NONSTDC_NO_DEPRECATE')
   1.197 -				self.compiler.AddToListVar('CDEFINES', '_ITERATOR_DEBUG_LEVEL=0')
   1.198 -				self.compiler.AddToListVar('CXXFLAGS', '/EHsc')
   1.199 -				self.compiler.AddToListVar('CXXFLAGS', '/GR-')
   1.200 -				self.compiler.AddToListVar('CFLAGS', '/W3')
   1.201 -				self.compiler.AddToListVar('CFLAGS', '/nologo')
   1.202 -				self.compiler.AddToListVar('CFLAGS', '/Zi')
   1.203 -				self.compiler.AddToListVar('CXXFLAGS', '/TP')
   1.204 -				self.compiler.AddToListVar('POSTLINKFLAGS', '/DEBUG')
   1.205 -				self.compiler.AddToListVar('POSTLINKFLAGS', '/MACHINE:X86')
   1.206 -				self.compiler.AddToListVar('POSTLINKFLAGS', '/SUBSYSTEM:WINDOWS')
   1.207 -				self.compiler.AddToListVar('POSTLINKFLAGS', 'kernel32.lib')
   1.208 -				self.compiler.AddToListVar('POSTLINKFLAGS', 'user32.lib')
   1.209 -				self.compiler.AddToListVar('POSTLINKFLAGS', 'gdi32.lib')
   1.210 -				self.compiler.AddToListVar('POSTLINKFLAGS', 'winspool.lib')
   1.211 -				self.compiler.AddToListVar('POSTLINKFLAGS', 'comdlg32.lib')
   1.212 -				self.compiler.AddToListVar('POSTLINKFLAGS', 'advapi32.lib')
   1.213 -				self.compiler.AddToListVar('POSTLINKFLAGS', 'shell32.lib')
   1.214 -				self.compiler.AddToListVar('POSTLINKFLAGS', 'ole32.lib')
   1.215 -				self.compiler.AddToListVar('POSTLINKFLAGS', 'oleaut32.lib')
   1.216 -				self.compiler.AddToListVar('POSTLINKFLAGS', 'uuid.lib')
   1.217 -				self.compiler.AddToListVar('POSTLINKFLAGS', 'odbc32.lib')
   1.218 -				self.compiler.AddToListVar('POSTLINKFLAGS', 'odbccp32.lib')
   1.219 -
   1.220 -			#Optimization
   1.221 -			if AMBuild.options.opt == '1':
   1.222 -				self.compiler.AddToListVar('CDEFINES', 'NDEBUG')
   1.223 -				if self.vendor == 'gcc' or self.vendor == 'clang':
   1.224 -					self.compiler.AddToListVar('CFLAGS', '-O3')
   1.225 -				elif self.vendor == 'msvc':
   1.226 -					self.compiler.AddToListVar('CFLAGS', '/Ox')
   1.227 -					self.compiler.AddToListVar('POSTLINKFLAGS', '/OPT:ICF')
   1.228 -					self.compiler.AddToListVar('POSTLINKFLAGS', '/OPT:REF')
   1.229 -
   1.230 -			#Debugging
   1.231 -			if AMBuild.options.debug == '1':
   1.232 -				self.compiler.AddToListVar('CDEFINES', 'DEBUG')
   1.233 -				self.compiler.AddToListVar('CDEFINES', '_DEBUG')
   1.234 -				if self.vendor == 'msvc':
   1.235 -					self.compiler.AddToListVar('CFLAGS', '/Od')
   1.236 -					self.compiler.AddToListVar('CFLAGS', '/RTC1')
   1.237 -			
   1.238 -			#This needs to be after our optimization flags which could otherwise disable it.
   1.239 -			if self.vendor == 'msvc':
   1.240 -				# Don't omit frame pointer
   1.241 -				self.compiler.AddToListVar('CFLAGS', '/Oy-')
   1.242 +class SDK(object):
   1.243 +  def __init__(self, sdk, ext, aDef, name, platform, dir):
   1.244 +    if dir == 'ep1':
   1.245 +      folder = 'hl2sdk'
   1.246 +    else:
   1.247 +      folder = 'hl2sdk-' + dir
   1.248 +    self.envvar = sdk
   1.249 +    self.ext = ext
   1.250 +    self.code = aDef
   1.251 +    self.define = name
   1.252 +    self.platform = platform
   1.253 +    self.folder = folder # Default folder name.
   1.254 +    self.name = dir
   1.255 +    self.path = None # Actual path
   1.256  
   1.257 -			#Platform-specifics
   1.258 -			if AMBuild.target['platform'] == 'linux':
   1.259 -				self.compiler.AddToListVar('CDEFINES', '_LINUX')
   1.260 -				self.compiler.AddToListVar('CDEFINES', 'POSIX')
   1.261 -				if self.vendor == 'gcc':
   1.262 -					self.compiler.AddToListVar('POSTLINKFLAGS', '-static-libgcc')
   1.263 -				if self.vendor == 'clang':
   1.264 -					self.compiler.AddToListVar('POSTLINKFLAGS', '-lgcc_eh')
   1.265 -			elif AMBuild.target['platform'] == 'darwin':
   1.266 -				self.compiler.AddToListVar('CDEFINES', 'OSX')
   1.267 -				self.compiler.AddToListVar('CDEFINES', '_OSX')
   1.268 -				self.compiler.AddToListVar('CDEFINES', 'POSIX')
   1.269 -				self.compiler.AddToListVar('POSTLINKFLAGS', '-mmacosx-version-min=10.5')
   1.270 -				self.compiler.AddToListVar('POSTLINKFLAGS', ['-arch', 'i386'])
   1.271 -				self.compiler.AddToListVar('POSTLINKFLAGS', '-lstdc++')
   1.272 -
   1.273 -				# For OS X dylib versioning
   1.274 -				import re
   1.275 -				productFile = open(os.path.join(AMBuild.sourceFolder, 'product.version'), 'r')
   1.276 -				productContents = productFile.read()
   1.277 -				productFile.close()
   1.278 -				m = re.match('(\d+)\.(\d+)\.(\d+).*', productContents)
   1.279 -				if m == None:
   1.280 -					self.version = '1.0.0'
   1.281 -				else:
   1.282 -					major, minor, release = m.groups()
   1.283 -					self.version = '{0}.{1}.{2}'.format(major, minor, release)
   1.284 -				AMBuild.cache.CacheVariable('version', self.version)
   1.285 -			elif AMBuild.target['platform'] == 'windows':
   1.286 -				self.compiler.AddToListVar('CDEFINES', 'WIN32')
   1.287 -				self.compiler.AddToListVar('CDEFINES', '_WINDOWS')
   1.288 -
   1.289 -			#Finish up
   1.290 -			self.compiler.AddToListVar('CDEFINES', 'SOURCEMOD_BUILD')
   1.291 -			self.compiler.AddToListVar('CDEFINES', 'SM_GENERATED_BUILD')
   1.292 -			self.compiler.AddToListVar('CINCLUDES',
   1.293 -			                           os.path.join(AMBuild.outputFolder, 'includes'))
   1.294 -			self.compiler.ToConfig(AMBuild, 'compiler')
   1.295 -			AMBuild.cache.CacheVariable('vendor', self.vendor)
   1.296 -			self.targetMap = { }
   1.297 -			AMBuild.cache.CacheVariable('targetMap', self.targetMap)
   1.298 -		else:
   1.299 -			self.sdkInfo = AMBuild.cache['sdkInfo']
   1.300 -			self.compiler.FromConfig(AMBuild, 'compiler')
   1.301 -			self.targetMap = AMBuild.cache['targetMap']
   1.302 -			self.hasMySql = AMBuild.cache['hasMySql']
   1.303 -
   1.304 -		if AMBuild.target['platform'] == 'windows':
   1.305 -			self.compiler.AddToListVar('RCINCLUDES', os.path.join(AMBuild.sourceFolder, 'public'))
   1.306 -			self.compiler.AddToListVar('RCINCLUDES',
   1.307 -			                           os.path.join(AMBuild.outputFolder, 'includes'))
   1.308 -		self.mmsPath = AMBuild.cache['MMSOURCE110']
   1.309 -
   1.310 -	def DefaultCompiler(self):
   1.311 -		return self.compiler.Clone()
   1.312 -
   1.313 -	def JobMatters(self, jobname):
   1.314 -		file = sys._getframe().f_code.co_filename
   1.315 -		if AMBuild.mode == 'config':
   1.316 -			self.targetMap[jobname] = file
   1.317 -			return True
   1.318 -		if len(AMBuild.args) == 0:
   1.319 -			return True
   1.320 -		if not jobname in AMBuild.args:
   1.321 -			return False
   1.322 -
   1.323 -	def DefaultExtCompiler(self, path):
   1.324 -		compiler = self.DefaultCompiler()
   1.325 -		compiler['CXXINCLUDES'].append(os.path.join(AMBuild.sourceFolder, path))
   1.326 -		compiler['CXXINCLUDES'].append(os.path.join(AMBuild.sourceFolder, path, 'sdk'))
   1.327 -		compiler['CXXINCLUDES'].append(os.path.join(AMBuild.sourceFolder, 'public'))
   1.328 -		compiler['CXXINCLUDES'].append(os.path.join(AMBuild.sourceFolder, 'public', 'extensions'))
   1.329 -		compiler['CXXINCLUDES'].append(os.path.join(AMBuild.sourceFolder, 'public', 'sourcepawn'))
   1.330 -		compiler['CXXINCLUDES'].append(os.path.join(AMBuild.sourceFolder, 'public', 'amtl'))
   1.331 -		return compiler
   1.332 -
   1.333 -	def AutoVersion(self, folder, binary):
   1.334 -		if AMBuild.target['platform'] == 'windows':
   1.335 -			env = {'RCDEFINES': ['BINARY_NAME="' + binary.binaryFile + '"', 'SM_GENERATED_BUILD']}
   1.336 -			binary.AddResourceFile(os.path.join(folder, 'version.rc' ), env)
   1.337 -		elif AMBuild.target['platform'] == 'darwin' and isinstance(binary, Cpp.LibraryBuilder):
   1.338 -			binary.compiler['POSTLINKFLAGS'].extend(['-compatibility_version', '1.0.0'])
   1.339 -			binary.compiler['POSTLINKFLAGS'].extend(['-current_version', AMBuild.cache['version']])
   1.340 -		else:
   1.341 -			return
   1.342 -
   1.343 -	def ExtractDebugInfo(self, job, binary):
   1.344 -		src = os.path.join('..', AMBuild.outputFolder, job.workFolder, binary.binaryFile)
   1.345 -		job.AddCommand(ExtractDebugInfoCommand(binary, src))
   1.346 +WinOnly = ['windows']
   1.347 +WinLinux = ['windows', 'linux']
   1.348 +WinLinuxMac = ['windows', 'linux', 'mac']
   1.349  
   1.350 -	def PreSetupHL2Job(self, job, builder, sdk):
   1.351 -		info = self.sdkInfo[sdk]
   1.352 -		sdkPath = AMBuild.cache[info['sdk']]
   1.353 -		if AMBuild.target['platform'] == 'linux':
   1.354 -			if sdk == 'ep1':
   1.355 -				staticLibs = os.path.join(sdkPath, 'linux_sdk')
   1.356 -			elif sdk == 'sdk2013':
   1.357 -				staticLibs = os.path.join(sdkPath, 'lib', 'public', 'linux32')
   1.358 -			else:
   1.359 -				staticLibs = os.path.join(sdkPath, 'lib', 'linux')
   1.360 -			workFolder = os.path.join(AMBuild.outputFolder, job.workFolder)
   1.361 -			libs = []
   1.362 -			if sdk in ['css', 'hl2dm', 'dods', 'tf2', 'l4d2']:
   1.363 -				libs = ['tier1_i486.a', 'mathlib_i486.a', 'libvstdlib_srv.so', 'libtier0_srv.so']
   1.364 -			elif sdk in ['l4d', 'nd', 'blade', 'insurgency', 'csgo']:
   1.365 -				libs = ['tier1_i486.a', 'mathlib_i486.a', 'libvstdlib.so', 'libtier0.so']
   1.366 -				if sdk in ['blade', 'insurgency', 'csgo']:
   1.367 -					libs.append('interfaces_i486.a')
   1.368 -			elif sdk == 'sdk2013':
   1.369 -				libs = ['tier1.a', 'mathlib.a', 'libvstdlib_srv.so', 'libtier0_srv.so']
   1.370 -			else:
   1.371 -				libs = ['tier1_i486.a', 'mathlib_i486.a', 'vstdlib_i486.so', 'tier0_i486.so']
   1.372 -			
   1.373 -			for lib in libs:
   1.374 -				link = os.path.join(workFolder, lib)
   1.375 -				target = os.path.join(staticLibs, lib)
   1.376 -				try:
   1.377 -					os.lstat(link)
   1.378 -				except:
   1.379 -					job.AddCommand(SymlinkCommand(link, target))
   1.380 -		elif AMBuild.target['platform'] == 'darwin':
   1.381 -			if sdk == 'sdk2013':
   1.382 -				staticLibs = os.path.join(sdkPath, 'lib', 'public', 'osx32')
   1.383 -				libs = ['tier1.a', 'mathlib.a', 'libvstdlib.dylib', 'libtier0.dylib']
   1.384 -			else:
   1.385 -				staticLibs = os.path.join(sdkPath, 'lib', 'mac')
   1.386 -				libs = ['tier1_i486.a', 'mathlib_i486.a', 'libvstdlib.dylib', 'libtier0.dylib']
   1.387 -			workFolder = os.path.join(AMBuild.outputFolder, job.workFolder)
   1.388 -			if sdk in ['insurgency', 'csgo']:
   1.389 -				libs.append('interfaces_i486.a')
   1.390 -			for lib in libs:
   1.391 -				link = os.path.join(workFolder, lib)
   1.392 -				target = os.path.join(staticLibs, lib)
   1.393 -				try:
   1.394 -					os.lstat(link)
   1.395 -				except:
   1.396 -					job.AddCommand(SymlinkCommand(link, target))
   1.397 -		elif AMBuild.target['platform'] == 'windows':
   1.398 -			libs = ['tier0', 'tier1', 'vstdlib', 'mathlib']
   1.399 -			if sdk in ['swarm', 'blade', 'insurgency', 'csgo', 'dota']:
   1.400 -				libs.append('interfaces')
   1.401 -			for lib in libs:
   1.402 -				libPath = os.path.join(sdkPath, 'lib', 'public', lib) + '.lib'
   1.403 -				builder.RebuildIfNewer(libPath)
   1.404 -				builder['POSTLINKFLAGS'].append(libPath)
   1.405 -
   1.406 -	def PostSetupHL2Job(self, job, builder, sdk):
   1.407 -		if AMBuild.target['platform'] in ['linux', 'darwin']:
   1.408 -			if sdk == 'sdk2013':
   1.409 -				builder.AddObjectFiles(['tier1.a', 'mathlib.a'])
   1.410 -			else:
   1.411 -				builder.AddObjectFiles(['tier1_i486.a', 'mathlib_i486.a'])
   1.412 -			
   1.413 -			if sdk in ['blade', 'insurgency', 'csgo']:
   1.414 -				builder.AddObjectFiles(['interfaces_i486.a'])
   1.415 -	
   1.416 -	def DefaultHL2Compiler(self, path, sdk, noLink = False, oldMms = '-legacy'):
   1.417 -		compiler = self.DefaultExtCompiler(path)
   1.418 -
   1.419 -		mms = 'core'
   1.420 -		if sdk == 'ep1':
   1.421 -			mms += oldMms
   1.422 -
   1.423 -		compiler['CXXINCLUDES'].append(os.path.join(self.mmsPath, mms))
   1.424 -		compiler['CXXINCLUDES'].append(os.path.join(self.mmsPath, mms, 'sourcehook'))
   1.425 -
   1.426 -		info = self.possibleSdks
   1.427 -		compiler['CDEFINES'].extend(['SE_' + info[i]['name'] + '=' + info[i]['def'] for i in info])
   1.428 -
   1.429 -		paths = [['public'], ['public', 'engine'], ['public', 'mathlib'], ['public', 'vstdlib'],
   1.430 -						 ['public', 'tier0'], ['public', 'tier1']]
   1.431 -		if sdk == 'ep1' or sdk == 'darkm':
   1.432 -			paths.append(['public', 'dlls'])
   1.433 -			paths.append(['game_shared'])
   1.434 -		else:
   1.435 -			paths.append(['public', 'game', 'server'])
   1.436 -			paths.append(['public', 'toolframework'])
   1.437 -			paths.append(['game', 'shared'])
   1.438 -			paths.append(['common'])
   1.439 -
   1.440 -		info = self.sdkInfo[sdk]
   1.441 -		sdkPath = AMBuild.cache[info['sdk']]
   1.442 -
   1.443 -		compiler['CDEFINES'].append('SOURCE_ENGINE=' + info['def'])
   1.444 -		
   1.445 -		if sdk == 'sdk2013' and isinstance(compiler.cxx, Cpp.CompatGCC):
   1.446 -			# The 2013 SDK already has these in public/tier0/basetypes.h
   1.447 -			compiler['CDEFINES'].remove('stricmp=strcasecmp')
   1.448 -			compiler['CDEFINES'].remove('_stricmp=strcasecmp')
   1.449 -			compiler['CDEFINES'].remove('_snprintf=snprintf')
   1.450 -			compiler['CDEFINES'].remove('_vsnprintf=vsnprintf')
   1.451 -
   1.452 -		if sdk in ['swarm', 'blade', 'insurgency', 'csgo', 'dota']:
   1.453 -			if AMBuild.target['platform'] == 'windows':
   1.454 -				compiler['CDEFINES'].extend(['COMPILER_MSVC', 'COMPILER_MSVC32'])
   1.455 -			else:
   1.456 -				compiler['CDEFINES'].extend(['COMPILER_GCC'])
   1.457 -
   1.458 -		if sdk == 'sdk2013' and AMBuild.target['platform'] == 'darwin':
   1.459 -			compiler['POSTLINKFLAGS'].append('-liconv')
   1.460 -		
   1.461 -		if sdk in ['css','hl2dm','dods','sdk2013','tf2','l4d2']:
   1.462 -			if AMBuild.target['platform'] == 'linux' or AMBuild.target['platform'] == 'darwin':
   1.463 -				compiler['CDEFINES'].append('NO_MALLOC_OVERRIDE')
   1.464 -
   1.465 -		if AMBuild.target['platform'] == 'linux':
   1.466 -			if sdk == 'ep1':
   1.467 -				staticLibs = os.path.join(sdkPath, 'linux_sdk')
   1.468 -			elif sdk == 'sdk2013':
   1.469 -				staticLibs = os.path.join(sdkPath, 'lib', 'public', 'linux32')
   1.470 -			else:
   1.471 -				staticLibs = os.path.join(sdkPath, 'lib', 'linux')
   1.472 -		elif AMBuild.target['platform'] == 'darwin':
   1.473 -			if sdk == 'sdk2013':
   1.474 -				staticLibs = os.path.join(sdkPath, 'lib', 'public', 'osx32')
   1.475 -			else:
   1.476 -				staticLibs = os.path.join(sdkPath, 'lib', 'mac')
   1.477 -
   1.478 -		for i in paths:
   1.479 -			compiler['CXXINCLUDES'].append(os.path.join(sdkPath, *i))
   1.480 -
   1.481 -		if not noLink:
   1.482 -			if AMBuild.target['platform'] == 'linux':
   1.483 -				compiler['POSTLINKFLAGS'][0:0] = ['-lm']
   1.484 -				if sdk in ['css', 'hl2dm', 'dods', 'tf2', 'sdk2013', 'l4d2']:
   1.485 -					compiler['POSTLINKFLAGS'][0:0] = ['libtier0_srv.so']
   1.486 -					compiler['POSTLINKFLAGS'][0:0] = ['libvstdlib_srv.so']
   1.487 -				elif sdk in ['l4d', 'nd', 'blade', 'insurgency', 'csgo']:
   1.488 -					compiler['POSTLINKFLAGS'][0:0] = ['libtier0.so']
   1.489 -					compiler['POSTLINKFLAGS'][0:0] = ['libvstdlib.so']
   1.490 -				else:
   1.491 -					compiler['POSTLINKFLAGS'][0:0] = ['tier0_i486.so']
   1.492 -					compiler['POSTLINKFLAGS'][0:0] = ['vstdlib_i486.so']
   1.493 -			elif AMBuild.target['platform'] == 'darwin':
   1.494 -				compiler['POSTLINKFLAGS'][0:0] = ['libtier0.dylib']
   1.495 -				compiler['POSTLINKFLAGS'][0:0] = ['libvstdlib.dylib']
   1.496 -
   1.497 -		return compiler
   1.498 -		
   1.499 -	def ResolveEnvPath(self, env, defaultDir):
   1.500 -		if env in os.environ:
   1.501 -			path = os.environ[env]
   1.502 -			if os.path.isdir(path):
   1.503 -				return path
   1.504 -		else:
   1.505 -			head = os.getcwd()
   1.506 -			oldhead = None
   1.507 -			while head != None and head != oldhead:
   1.508 -				path = os.path.join(head, defaultDir)
   1.509 -				if os.path.isdir(path):
   1.510 -					return path
   1.511 -				oldhead = head
   1.512 -				head, tail = os.path.split(head)
   1.513 -		return None
   1.514 -
   1.515 -sm = SM()
   1.516 -globals = {
   1.517 -	'SM': sm
   1.518 +PossibleSDKs = {
   1.519 +  'ep1':  SDK('HL2SDK', '1.ep1', '1', 'EPISODEONE', WinLinux, 'ep1'),
   1.520 +  'ep2':  SDK('HL2SDKOB', '2.ep2', '3', 'ORANGEBOX', WinLinux, 'ob'),
   1.521 +  'css':  SDK('HL2SDKCSS', '2.css', '6', 'CSS', WinLinuxMac, 'css'),
   1.522 +  'hl2dm':  SDK('HL2SDKHL2DM', '2.hl2dm', '7', 'HL2DM', WinLinuxMac, 'hl2dm'),
   1.523 +  'dods': SDK('HL2SDKDODS', '2.dods', '8', 'DODS', WinLinuxMac, 'dods'),
   1.524 +  'sdk2013': SDK('HL2SDK2013', '2.sdk2013', '9', 'SDK2013', WinLinuxMac, '2013'),
   1.525 +  'tf2':  SDK('HL2SDKTF2', '2.tf2', '10', 'TF2', WinLinuxMac, 'tf2'),
   1.526 +  'l4d':  SDK('HL2SDKL4D', '2.l4d', '11', 'LEFT4DEAD', WinLinuxMac, 'l4d'),
   1.527 +  'nd': SDK('HL2SDKND', '2.nd', '12', 'NUCLEARDAWN', WinLinuxMac, 'nd'),
   1.528 +  'l4d2': SDK('HL2SDKL4D2', '2.l4d2', '13', 'LEFT4DEAD2', WinLinuxMac, 'l4d2'),
   1.529 +  'darkm':  SDK('HL2SDK-DARKM', '2.darkm', '2', 'DARKMESSIAH', WinOnly, 'darkm'),
   1.530 +  'swarm':  SDK('HL2SDK-SWARM', '2.swarm', '14', 'ALIENSWARM', WinOnly, 'swarm'),
   1.531 +  'bgt':  SDK('HL2SDK-BGT', '2.bgt', '4', 'BLOODYGOODTIME', WinOnly, 'bgt'),
   1.532 +  'eye':  SDK('HL2SDK-EYE', '2.eye', '5', 'EYE', WinOnly, 'eye'),
   1.533 +  'csgo': SDK('HL2SDKCSGO', '2.csgo', '18', 'CSGO', WinLinuxMac, 'csgo'),
   1.534 +  'dota': SDK('HL2SDKDOTA', '2.dota', '19', 'DOTA', WinOnly, 'dota'),
   1.535 +  'portal2':  SDK('HL2SDKPORTAL2', '2.portal2', '15', 'PORTAL2', [], 'portal2'),
   1.536 +  'blade':  SDK('HL2SDKBLADE', '2.blade', '16', 'BLADE', WinLinux, 'blade'),
   1.537 +  'insurgency':  SDK('HL2SDKINSURGENCY', '2.insurgency', '17', 'INSURGENCY', WinLinuxMac, 'insurgency'),
   1.538  }
   1.539  
   1.540 -AMBuild.Include(os.path.join('tools', 'buildbot', 'Versioning'), globals)
   1.541 +def ResolveEnvPath(env, folder):
   1.542 +  if env in os.environ:
   1.543 +    path = os.environ[env]
   1.544 +    if os.path.isdir(path):
   1.545 +      return path
   1.546 +  else:
   1.547 +    head = os.getcwd()
   1.548 +    oldhead = None
   1.549 +    while head != None and head != oldhead:
   1.550 +      path = os.path.join(head, folder)
   1.551 +      if os.path.isdir(path):
   1.552 +        return path
   1.553 +      oldhead = head
   1.554 +      head, tail = os.path.split(head)
   1.555 +  return None
   1.556 +
   1.557 +class SMConfig(object):
   1.558 +  def __init__(self):
   1.559 +    self.sdks = {}
   1.560 +    self.binaries = []
   1.561 +    self.mms_root = None
   1.562 +    self.mysql_root = None
   1.563 +
   1.564 +  def detectSDKs(self):
   1.565 +    sdk_list = builder.options.sdks.split(',')
   1.566 +    use_all = sdk_list[0] == 'all'
   1.567 +    use_present = sdk_list[0] == 'present'
   1.568 +
   1.569 +    for sdk_name in PossibleSDKs:
   1.570 +      sdk = PossibleSDKs[sdk_name]
   1.571 +      if builder.target_platform in sdk.platform:
   1.572 +        sdk_path = ResolveEnvPath(sdk.envvar, sdk.folder)
   1.573 +        if sdk_path is None:
   1.574 +          if use_all or sdk_name in sdk_list:
   1.575 +            raise Exception('Could not find a valid path for {0}'.format(sdk.envvar))
   1.576 +          continue
   1.577 +        if use_all or use_present or sdk_name in sdk_list:
   1.578 +          sdk.path = sdk_path
   1.579 +          self.sdks[sdk_name] = sdk
   1.580 +
   1.581 +    if len(self.sdks) < 1:
   1.582 +      raise Exception('At least one SDK must be available.')
   1.583 +
   1.584 +    self.mms_root = ResolveEnvPath('MMSOURCE110', 'mmsource-1.10')
   1.585 +    if not self.mms_root:
   1.586 +      self.mms_root = ResolveEnvPath('MMSOURCE_DEV', 'mmsource-central')
   1.587 +      if not self.mms_root:
   1.588 +        raise Exception('Could not find a source copy of Metamod:Source')
   1.589 +
   1.590 +    if builder.options.hasMySql:
   1.591 +      for i in range(7):
   1.592 +        self.mysql_root = ResolveEnvPath('MYSQL5', 'mysql-5.' + str(i))
   1.593 +        if self.mysql_root:
   1.594 +          break
   1.595 +      if not self.mysql_root:
   1.596 +        raise Exception('Could not find a path to MySQL!')
   1.597 +
   1.598 +  def configure(self):
   1.599 +    cfg = builder.DetectCompilers()
   1.600 +    cxx = cfg.cxx
   1.601 +
   1.602 +    if cxx.behavior is 'gcc':
   1.603 +      cfg.defines += [
   1.604 +        'stricmp=strcasecmp',
   1.605 +        '_stricmp=strcasecmp',
   1.606 +        '_snprintf=snprintf',
   1.607 +        '_vsnprintf=vsnprintf',
   1.608 +        'HAVE_STDINT_H',
   1.609 +        'GNUC',
   1.610 +      ]
   1.611 +      cfg.cflags += [
   1.612 +        '-pipe',
   1.613 +        '-fno-strict-aliasing',
   1.614 +        '-Wall',
   1.615 +        '-Werror',
   1.616 +        '-Wno-uninitialized',
   1.617 +        '-Wno-unused',
   1.618 +        '-Wno-switch',
   1.619 +        '-msse',
   1.620 +        '-m32',
   1.621 +        '-g3',
   1.622 +      ]
   1.623 +
   1.624 +      have_gcc = cxx.name is 'gcc'
   1.625 +      have_clang = cxx.name is 'clang'
   1.626 +      if have_clang or (have_gcc and cxx.majorVersion >= 4):
   1.627 +        cfg.cflags += ['-fvisibility=hidden']
   1.628 +        cfg.cxxflags += ['-fvisibility-inlines-hidden']
   1.629 +        if have_clang or (have_gcc and cxx.minorVersion >= 6):
   1.630 +          cfg.cflags += ['-Wno-narrowing']
   1.631 +        if (have_gcc and cxx.minorVersion >= 7) or (have_clang and cxx.majorVersion >= 4):
   1.632 +          cfg.cxxflags += ['-Wno-delete-non-virtual-dtor']
   1.633 +
   1.634 +      cfg.linkflags += ['-m32']
   1.635 +      cfg.cxxflags += [
   1.636 +        '-fno-exceptions',
   1.637 +        '-fno-threadsafe-statics',
   1.638 +        '-Wno-non-virtual-dtor',
   1.639 +        '-Wno-overloaded-virtual',
   1.640 +      ]
   1.641 +
   1.642 +      if have_gcc:
   1.643 +        cfg.cflags += ['-mfpmath=sse']
   1.644 +    elif cxx.name == 'msvc':
   1.645 +      if builder.options.debug == '1':
   1.646 +        cfg.cflags += ['/MTd']
   1.647 +        cfg.linkflags += ['/NODEFAULTLIB:libcmt']
   1.648 +      else:
   1.649 +        cfg.cflags += ['/MT']
   1.650 +      cfg.defines += [
   1.651 +        '_CRT_SECURE_NO_DEPRECATE',
   1.652 +        '_CRT_SECURE_NO_WARNINGS',
   1.653 +        '_CRT_NONSTDC_NO_DEPRECATE',
   1.654 +        '_ITERATOR_DEBUG_LEVEL=0',
   1.655 +      ]
   1.656 +      cfg.cflags += [
   1.657 +        '/W3',
   1.658 +        '/Zi',
   1.659 +      ]
   1.660 +      cfg.cxxflags += [
   1.661 +        '/EHsc',
   1.662 +        '/GR-',
   1.663 +        '/TP',
   1.664 +      ]
   1.665 +      cfg.linkflags += [
   1.666 +        '/DEBUG',
   1.667 +        '/MACHINE:X86',
   1.668 +        '/SUBSYSTEM:WINDOWS',
   1.669 +        'kernel32.lib',
   1.670 +        'user32.lib',
   1.671 +        'gdi32.lib',
   1.672 +        'winspool.lib',
   1.673 +        'comdlg32.lib',
   1.674 +        'advapi32.lib',
   1.675 +        'shell32.lib',
   1.676 +        'ole32.lib',
   1.677 +        'oleaut32.lib',
   1.678 +        'uuid.lib',
   1.679 +        'odbc32.lib',
   1.680 +        'odbccp32.lib',
   1.681 +      ] 
   1.682 +
   1.683 +    # Optimization
   1.684 +    if builder.options.opt == '1':
   1.685 +      cfg.defines += ['NDEBUG']
   1.686 +      if cxx.behavior == 'gcc':
   1.687 +        cfg.cflags += ['-O3']
   1.688 +      elif cxx.behavior == 'msvc':
   1.689 +        cfg.cflags += ['/Ox']
   1.690 +        cfg.linkflags += ['/OPT:ICF', '/OPT:REF']
   1.691 +
   1.692 +    # Debugging
   1.693 +    if builder.options.debug == '1':
   1.694 +      cfg.defines += ['DEBUG', '_DEBUG']
   1.695 +      if cxx.behavior == 'gcc':
   1.696 +        cfg.cflags += ['-g3']
   1.697 +      elif cxx.behavior == 'msvc':
   1.698 +        cfg.cflags += ['/Od', '/RTC1']
   1.699 +
   1.700 +    # This needs to be after our optimization flags which could otherwise disable it.
   1.701 +    if cxx.name == 'msvc':
   1.702 +      # Don't omit the frame pointer.
   1.703 +      cfg.cflags += ['/Oy-']
   1.704 +
   1.705 +    # Platform-specifics
   1.706 +    if builder.target_platform == 'linux':
   1.707 +      cfg.defines += ['_LINUX', 'POSIX']
   1.708 +      if cxx.name == 'gcc':
   1.709 +        cfg.linkflags += ['-static-libgcc']
   1.710 +      elif cxx.name == 'clang':
   1.711 +        cfg.linkflags += ['-lgcc_eh']
   1.712 +    elif builder.target_platform == 'mac':
   1.713 +      cfg.defines += ['OSX', '_OSX', 'POSIX']
   1.714 +      cfg.linkflags += [
   1.715 +        '-mmacosx-version-min=10.5',
   1.716 +        '-arch', 'i386',
   1.717 +        '-lstdc++',
   1.718 +      ]
   1.719 +    elif builder.target_platform == 'windows':
   1.720 +      cfg.defines += ['WIN32', '_WINDOWS']
   1.721  
   1.722 -FileList = [
   1.723 -		['loader', 'AMBuilder'],
   1.724 -		['core', 'AMBuilder'],
   1.725 -		['core', 'logic', 'AMBuilder'],
   1.726 -		['extensions', 'bintools', 'AMBuilder'],
   1.727 -		['extensions', 'clientprefs', 'AMBuilder'],
   1.728 -		['extensions', 'cstrike', 'AMBuilder'],
   1.729 -		['extensions', 'curl', 'AMBuilder'],
   1.730 -		['extensions', 'geoip', 'AMBuilder'],
   1.731 -		['extensions', 'mysql', 'AMBuilder'],
   1.732 -		['extensions', 'sdkhooks', 'AMBuilder'],
   1.733 -		['extensions', 'sdktools', 'AMBuilder'],
   1.734 -		['extensions', 'topmenus', 'AMBuilder'],
   1.735 -		['extensions', 'updater', 'AMBuilder'],
   1.736 -		['extensions', 'sqlite', 'AMBuilder'],
   1.737 -		['extensions', 'regex', 'AMBuilder'],
   1.738 -		['extensions', 'tf2', 'AMBuilder'],
   1.739 -		['sourcepawn', 'jit', 'AMBuilder'],
   1.740 -		['sourcepawn', 'compiler', 'AMBuilder'],
   1.741 -		['plugins', 'AMBuilder'],
   1.742 -		['tools', 'buildbot', 'PackageScript'],
   1.743 -		['tools', 'buildbot', 'BreakpadSymbols']
   1.744 -	]
   1.745 +    # Finish up.
   1.746 +    cfg.defines += [
   1.747 +      'SOURCEMOD_BUILD',
   1.748 +    ]
   1.749 +    cfg.includes += [os.path.join(builder.buildPath, 'includes')]
   1.750 +
   1.751 +  def LibraryBuilder(self, compiler, name):
   1.752 +    binary = compiler.Library(name)
   1.753 +    return binary
   1.754 +
   1.755 +  def ProgramBuilder(self, compiler, name):
   1.756 +    binary = compiler.Program(name)
   1.757 +    return binary
   1.758 +
   1.759 +  def Library(self, context, name):
   1.760 +    compiler = context.compiler.clone()
   1.761 +    return self.LibraryBuilder(compiler, name)
   1.762 +
   1.763 +  def Program(self, context, name):
   1.764 +    compiler = context.compiler.clone()
   1.765 +    return self.ProgramBuilder(compiler, name)
   1.766 +
   1.767 +  def ExtCompiler(self, context):
   1.768 +    compiler = context.compiler.clone()
   1.769 +    compiler.cxxincludes += [
   1.770 +      os.path.join(context.currentSourcePath),
   1.771 +      os.path.join(context.currentSourcePath, 'sdk'),
   1.772 +      os.path.join(builder.sourcePath, 'public'),
   1.773 +      os.path.join(builder.sourcePath, 'public', 'extensions'),
   1.774 +      os.path.join(builder.sourcePath, 'public', 'sourcepawn'),
   1.775 +      os.path.join(builder.sourcePath, 'public', 'amtl'),
   1.776 +    ]
   1.777 +    return compiler
   1.778 +
   1.779 +  def HL2Compiler(self, context, sdk):
   1.780 +    compiler = self.ExtCompiler(context)
   1.781 +
   1.782 +    if sdk.name == 'ep1':
   1.783 +      mms_path = os.path.join(self.mms_root, 'core-legacy')
   1.784 +    else:
   1.785 +      mms_path = os.path.join(self.mms_root, 'core')
   1.786 +
   1.787 +    compiler.cxxincludes += [
   1.788 +      os.path.join(mms_path),
   1.789 +      os.path.join(mms_path, 'sourcehook'),
   1.790 +    ]
   1.791 +
   1.792 +    defines = ['SE_' + PossibleSDKs[i].define + '=' + PossibleSDKs[i].code for i in PossibleSDKs]
   1.793 +    compiler.defines += defines
   1.794 +    paths = [
   1.795 +      ['public'],
   1.796 +      ['public', 'engine'],
   1.797 +      ['public', 'mathlib'],
   1.798 +      ['public', 'vstdlib'],
   1.799 +      ['public', 'tier0'],
   1.800 +      ['public', 'tier1']
   1.801 +    ]
   1.802 +    if sdk.name == 'ep1' or sdk.name == 'darkm':
   1.803 +      paths.append(['public', 'dlls'])
   1.804 +      paths.append(['game_shared'])
   1.805 +    else:
   1.806 +      paths.append(['public', 'game', 'server'])
   1.807 +      paths.append(['public', 'toolframework'])
   1.808 +      paths.append(['game', 'shared'])
   1.809 +      paths.append(['common'])
   1.810 +
   1.811 +    compiler.defines += ['SOURCE_ENGINE=' + sdk.code]
   1.812 +
   1.813 +    if sdk.name == '2013' and compiler.cxx.behavior == 'gcc':
   1.814 +      # The 2013 SDK already has these in public/tier0/basetypes.h
   1.815 +      compiler.defines.remove('stricmp=strcasecmp')
   1.816 +      compiler.defines.remove('_stricmp=strcasecmp')
   1.817 +      compiler.defines.remove('_snprintf=snprintf')
   1.818 +      compiler.defines.remove('_vsnprintf=vsnprintf')
   1.819 +
   1.820 +    if sdk.name in ['swarm', 'blade', 'insurgency', 'csgo', 'dota']:
   1.821 +      if compiler.cc.behavior == 'msvc':
   1.822 +        compiler.defines += ['COMPILER_MSVC', 'COMPILER_MSVC32']
   1.823 +      else:
   1.824 +        compiler.defines += ['COMPILER_GCC']
   1.825 +
   1.826 +    if sdk.name in ['css', 'hl2dm', 'dods', '2013', 'tf2', 'l4d2']:
   1.827 +      if builder.target_platform in ['linux', 'mac']:
   1.828 +        compiler.defines += ['NO_MALLOC_OVERRIDE']
   1.829 +
   1.830 +    for path in paths:
   1.831 +      compiler.cxxincludes += [os.path.join(sdk.path, *path)]
   1.832 +
   1.833 +    return compiler
   1.834 +
   1.835 +  def ExtLibrary(self, context, name):
   1.836 +    compiler = self.ExtCompiler(context)
   1.837 +    return self.LibraryBuilder(compiler, name)
   1.838  
   1.839 -if not sm.hasMySql:
   1.840 -	FileList.remove(['extensions', 'mysql', 'AMBuilder'])
   1.841 +  def HL2Library(self, context, name, sdk):
   1.842 +    compiler = self.HL2Compiler(context, sdk)
   1.843 +
   1.844 +    if builder.target_platform is 'linux':
   1.845 +      if sdk.name is 'ep1':
   1.846 +        lib_folder = os.path.join(sdk.path, 'linux_sdk')
   1.847 +      elif sdk.name is '2013':
   1.848 +        lib_folder = os.path.join(sdk.path, 'lib', 'public', 'linux32')
   1.849 +      else:
   1.850 +        lib_folder = os.path.join(sdk.path, 'lib', 'linux')
   1.851 +    elif builder.target_platform == 'mac':
   1.852 +      if sdk.name is '2013':
   1.853 +        lib_folder = os.path.join(sdk.path, 'lib', 'public', 'osx32')
   1.854 +      else:
   1.855 +        lib_folder = os.path.join(sdk.path, 'lib', 'mac')
   1.856 +
   1.857 +    if builder.target_platform in ['linux', 'mac']:
   1.858 +      if sdk.name is '2013':
   1.859 +        compiler.postlink += [
   1.860 +          compiler.Dep(os.path.join(lib_folder, 'tier1.a')),
   1.861 +          compiler.Dep(os.path.join(lib_folder, 'mathlib.a'))
   1.862 +        ]
   1.863 +      else:
   1.864 +        compiler.postlink += [
   1.865 +          compiler.Dep(os.path.join(lib_folder, 'tier1_i486.a')),
   1.866 +          compiler.Dep(os.path.join(lib_folder, 'mathlib_i486.a'))
   1.867 +        ]
   1.868 +
   1.869 +      if sdk.name in ['blade', 'insurgency', 'csgo', 'dota']:
   1.870 +        compiler.postlink += [compiler.Dep(os.path.join(lib_folder, 'interfaces_i486.a'))]
   1.871 +
   1.872 +    binary = self.LibraryBuilder(compiler, name)
   1.873  
   1.874 -for parts in FileList:
   1.875 -	AMBuild.Include(os.path.join(*parts), globals)
   1.876 +    dynamic_libs = []
   1.877 +    if builder.target_platform == 'linux':
   1.878 +      compiler.linkflags[0:0] = ['-lm']
   1.879 +      if sdk.name in ['css', 'hl2dm', 'dods', 'tf2', '2013', 'l4d2']:
   1.880 +        dynamic_libs = ['libtier0_srv.so', 'libvstdlib_srv.so']
   1.881 +      elif sdk.name in ['l4d', 'nd', 'blade', 'insurgency', 'csgo']:
   1.882 +        dynamic_libs = ['libtier0.so', 'libvstdlib.so']
   1.883 +      else:
   1.884 +        dynamic_libs = ['tier0_i486.so', 'vstdlib_i486.so']
   1.885 +    elif builder.target_platform == 'mac':
   1.886 +      binary.compiler.linkflags.append('-liconv')
   1.887 +      dynamic_libs = ['libtier0.dylib', 'libvstdlib.dylib']
   1.888 +    elif builder.target_platform == 'windows':
   1.889 +      libs = ['tier0', 'tier1', 'vstdlib', 'mathlib']
   1.890 +      if sdk.name in ['swarm', 'blade', 'insurgency', 'csgo', 'dota']:
   1.891 +        libs.append('interfaces')
   1.892 +      for lib in libs:
   1.893 +        lib_path = os.path.join(sdk.path, 'lib', 'public', lib) + '.lib'
   1.894 +        binary.compiler.linkflags.append(binary.Dep(lib_path))
   1.895 +
   1.896 +    for library in dynamic_libs:
   1.897 +      source_path = os.path.join(lib_folder, library)
   1.898 +      output_path = os.path.join(binary.localFolder, library)
   1.899 +
   1.900 +      def make_linker(source_path, output_path):
   1.901 +        def link(context, binary):
   1.902 +          cmd_node, (output,) = context.AddSymlink(source_path, output_path)
   1.903 +          return output
   1.904 +        return link
   1.905  
   1.906 +      linker = make_linker(source_path, output_path)
   1.907 +      binary.compiler.linkflags[0:0] = [binary.Dep(library, linker)]
   1.908 +
   1.909 +    return binary
   1.910 +
   1.911 +SM = SMConfig()
   1.912 +SM.detectSDKs()
   1.913 +SM.configure()
   1.914 +
   1.915 +builder.RunBuildScripts(
   1.916 +  [
   1.917 +    'loader/AMBuilder',
   1.918 +    'core/AMBuilder',
   1.919 +    'core/logic/AMBuilder',
   1.920 +    'extensions/bintools/AMBuilder',
   1.921 +    'extensions/clientprefs/AMBuilder',
   1.922 +    'extensions/cstrike/AMBuilder',
   1.923 +    'extensions/geoip/AMBuilder',
   1.924 +    'extensions/mysql/AMBuilder',
   1.925 +    'extensions/regex/AMBuilder',
   1.926 +    'extensions/sdkhooks/AMBuilder',
   1.927 +    'extensions/sdktools/AMBuilder',
   1.928 +    'extensions/sqlite/AMBuilder',
   1.929 +    'extensions/tf2/AMBuilder',
   1.930 +    'extensions/topmenus/AMBuilder',
   1.931 +    'extensions/updater/AMBuilder',
   1.932 +    'sourcepawn/compiler/AMBuilder',
   1.933 +    'sourcepawn/jit/AMBuilder',
   1.934 +  ],
   1.935 +  {
   1.936 +    'SM': SM
   1.937 +  }
   1.938 +)