AMBuildScript
author Reuben Morais <reuben.morais@gmail.com>
Wed Mar 21 21:27:26 2012 -0500 (2012-03-21)
changeset 3471 28726962259e
parent 3470 68c51e98aed8
child 3472 7c8bf140de6b
permissions -rw-r--r--
Removed hardcoded SDK path on OS X (bug 5032, r=ds).
     1 # vim: set ts=2 sw=2 tw=99 noet ft=python:
     2 import os
     3 import sys
     4 from ambuild.command import SymlinkCommand
     5 from ambuild.command import ShellCommand
     6 
     7 class SM:
     8 	def __init__(self):
     9 		self.compiler = Cpp.Compiler()
    10 
    11 		#Build SDK info
    12 		self.possibleSdks = { }
    13 		self.possibleSdks['ep1'] =   {'sdk': 'HL2SDK',          'ext': '1.ep1',   'def': '1',
    14 		                         'name': 'EPISODEONE',     'platform': ['windows', 'linux']}
    15 		self.possibleSdks['ep2'] =   {'sdk': 'HL2SDKOB',        'ext': '2.ep2',   'def': '3',
    16 		                         'name': 'ORANGEBOX',      'platform': ['windows', 'linux']}
    17 		self.possibleSdks['ep2v'] =  {'sdk': 'HL2SDKOBVALVE',   'ext': '2.ep2v',  'def': '6',
    18 		                         'name': 'ORANGEBOXVALVE', 'platform': ['windows', 'linux', 'darwin']}
    19 		self.possibleSdks['l4d'] =   {'sdk': 'HL2SDKL4D',       'ext': '2.l4d',   'def': '7',
    20 		                         'name': 'LEFT4DEAD',      'platform': ['windows', 'linux', 'darwin']}
    21 		self.possibleSdks['l4d2'] =  {'sdk': 'HL2SDKL4D2',      'ext': '2.l4d2',  'def': '8',
    22 		                         'name': 'LEFT4DEAD2',     'platform': ['windows', 'linux', 'darwin']}
    23 		self.possibleSdks['darkm'] = {'sdk': 'HL2SDK-DARKM',    'ext': '2.darkm', 'def': '2',
    24 		                         'name': 'DARKMESSIAH',    'platform': ['windows']}
    25 		self.possibleSdks['swarm'] = {'sdk': 'HL2SDK-SWARM',    'ext': '2.swarm', 'def': '9',
    26 		                         'name': 'ALIENSWARM',     'platform': ['windows']}
    27 		self.possibleSdks['bgt'] =   {'sdk': 'HL2SDK-BGT',      'ext': '2.bgt', 'def': '4',
    28 		                         'name': 'BLOODYGOODTIME', 'platform': ['windows']}
    29 		self.possibleSdks['eye'] =   {'sdk': 'HL2SDK-EYE',      'ext': '2.eye', 'def': '5',
    30 		                         'name': 'EYE', 'platform': ['windows']}
    31 		
    32 		self.sdkInfo = { }
    33 
    34 		if AMBuild.mode == 'config':
    35 			#Detect compilers
    36 			self.compiler.DetectAll(AMBuild)
    37 
    38 			#Detect variables
    39 			envvars = { 'MMSOURCE18':    'mmsource-1.8',
    40 									'HL2SDKOBVALVE': 'hl2sdk-ob-valve',
    41 									'HL2SDKL4D':     'hl2sdk-l4d',
    42 									'HL2SDKL4D2':    'hl2sdk-l4d2',
    43 									'MYSQL5':        'mysql-5.0'
    44 			}
    45 
    46 			if AMBuild.target['platform'] != 'darwin':
    47 				envvars['HL2SDK'] = 'hl2sdk'
    48 				envvars['HL2SDKOB'] = 'hl2sdk-ob'
    49 
    50 			#Dark Messiah is Windows-only
    51 			if AMBuild.target['platform'] == 'windows':
    52 				envvars['HL2SDK-DARKM'] = 'hl2sdk-darkm'
    53 				envvars['HL2SDK-SWARM'] = 'hl2sdk-swarm'
    54 				envvars['HL2SDK-BGT']   = 'hl2sdk-bgt'
    55 				envvars['HL2SDK-EYE']   = 'hl2sdk-eye'
    56 
    57 			# Finds if a dict with `key` set to `value` is present on the dict of dicts `dictionary`
    58 			def findDictByKey(dictionary, key, value):
    59 				for index in dictionary:
    60 					elem = dictionary[index]
    61 					if elem[key] == value:
    62 						return (elem, index)
    63 				return None
    64 
    65 			for i in envvars:
    66 				if i in os.environ:
    67 					path = os.environ[i]
    68 					if not os.path.isdir(path):
    69 						raise Exception('Path for {0} was not found: {1}'.format(i, path))
    70 					elif i.startswith('HL2SDK'):
    71 						(info, sdk) = findDictByKey(self.possibleSdks, 'sdk', i)
    72 						self.sdkInfo[sdk] = info
    73 				else:
    74 					head = os.getcwd()
    75 					oldhead = None
    76 					while head != None and head != oldhead:
    77 						path = os.path.join(head, envvars[i])
    78 						if os.path.isdir(path):
    79 							break
    80 						oldhead = head
    81 						head, tail = os.path.split(head)
    82 					if i.startswith('HL2SDK'):
    83 						if head != None and head != oldhead:
    84 							(info, sdk) = findDictByKey(self.possibleSdks, 'sdk', i)
    85 							self.sdkInfo[sdk] = info
    86 					elif head == None or head == oldhead:
    87 						raise Exception('Could not find a valid path for {0}'.format(i))
    88 				AMBuild.cache.CacheVariable(i, path)
    89 
    90 			if len(self.sdkInfo) < 1:
    91 				raise Exception('At least one SDK must be available.')
    92 				
    93 			AMBuild.cache.CacheVariable('sdkInfo', self.sdkInfo)
    94 
    95 			#Set up defines
    96 			cxx = self.compiler.cxx
    97 			if isinstance(cxx, Cpp.CompatGCC):
    98 				if isinstance(cxx, Cpp.GCC):
    99 					self.vendor = 'gcc'
   100 				elif isinstance(cxx, Cpp.Clang):
   101 					self.vendor = 'clang'
   102 				self.compiler.AddToListVar('CDEFINES', 'stricmp=strcasecmp')
   103 				self.compiler.AddToListVar('CDEFINES', '_stricmp=strcasecmp')
   104 				self.compiler.AddToListVar('CDEFINES', '_snprintf=snprintf')
   105 				self.compiler.AddToListVar('CDEFINES', '_vsnprintf=vsnprintf')
   106 				self.compiler.AddToListVar('CFLAGS', '-pipe')
   107 				self.compiler.AddToListVar('CFLAGS', '-fno-strict-aliasing')
   108 				if (self.vendor == 'gcc' and cxx.majorVersion >= 4) or self.vendor == 'clang':
   109 					self.compiler.AddToListVar('CFLAGS', '-fvisibility=hidden')
   110 					self.compiler.AddToListVar('CXXFLAGS', '-fvisibility-inlines-hidden')
   111 				self.compiler.AddToListVar('CFLAGS', '-Wall')
   112 				self.compiler.AddToListVar('CFLAGS', '-Werror')
   113 				self.compiler.AddToListVar('CFLAGS', '-Wno-uninitialized')
   114 				self.compiler.AddToListVar('CFLAGS', '-Wno-unused')
   115 				self.compiler.AddToListVar('CFLAGS', '-Wno-switch')
   116 				self.compiler.AddToListVar('CFLAGS', '-msse')
   117 				self.compiler.AddToListVar('CFLAGS', '-m32')
   118 				self.compiler.AddToListVar('CFLAGS', '-g3')
   119 				self.compiler.AddToListVar('POSTLINKFLAGS', '-m32')
   120 				self.compiler.AddToListVar('CXXFLAGS', '-fno-exceptions')
   121 				self.compiler.AddToListVar('CXXFLAGS', '-fno-rtti')
   122 				self.compiler.AddToListVar('CXXFLAGS', '-fno-threadsafe-statics')
   123 				self.compiler.AddToListVar('CXXFLAGS', '-Wno-non-virtual-dtor')
   124 				self.compiler.AddToListVar('CXXFLAGS', '-Wno-overloaded-virtual')
   125 				self.compiler.AddToListVar('CDEFINES', 'HAVE_STDINT_H')
   126 				self.compiler.AddToListVar('CDEFINES', 'GNUC')
   127 				if self.vendor == 'gcc':
   128 					self.compiler.AddToListVar('CFLAGS', '-mfpmath=sse')
   129 			elif isinstance(cxx, Cpp.MSVC):
   130 				self.vendor = 'msvc'
   131 				if AMBuild.options.debug == '1':
   132 					self.compiler.AddToListVar('CFLAGS', '/MTd')
   133 					self.compiler.AddToListVar('POSTLINKFLAGS', '/NODEFAULTLIB:libcmt')
   134 				else:
   135 					self.compiler.AddToListVar('CFLAGS', '/MT')
   136 				self.compiler.AddToListVar('CDEFINES', '_CRT_SECURE_NO_DEPRECATE')
   137 				self.compiler.AddToListVar('CDEFINES', '_CRT_SECURE_NO_WARNINGS')
   138 				self.compiler.AddToListVar('CDEFINES', '_CRT_NONSTDC_NO_DEPRECATE')
   139 				self.compiler.AddToListVar('CXXFLAGS', '/EHsc')
   140 				self.compiler.AddToListVar('CXXFLAGS', '/GR-')
   141 				self.compiler.AddToListVar('CFLAGS', '/W3')
   142 				self.compiler.AddToListVar('CFLAGS', '/nologo')
   143 				self.compiler.AddToListVar('CFLAGS', '/Zi')
   144 				self.compiler.AddToListVar('CXXFLAGS', '/TP')
   145 				self.compiler.AddToListVar('POSTLINKFLAGS', '/DEBUG')
   146 				self.compiler.AddToListVar('POSTLINKFLAGS', '/MACHINE:X86')
   147 				self.compiler.AddToListVar('POSTLINKFLAGS', '/SUBSYSTEM:WINDOWS')
   148 				self.compiler.AddToListVar('POSTLINKFLAGS', 'kernel32.lib')
   149 				self.compiler.AddToListVar('POSTLINKFLAGS', 'user32.lib')
   150 				self.compiler.AddToListVar('POSTLINKFLAGS', 'gdi32.lib')
   151 				self.compiler.AddToListVar('POSTLINKFLAGS', 'winspool.lib')
   152 				self.compiler.AddToListVar('POSTLINKFLAGS', 'comdlg32.lib')
   153 				self.compiler.AddToListVar('POSTLINKFLAGS', 'advapi32.lib')
   154 				self.compiler.AddToListVar('POSTLINKFLAGS', 'shell32.lib')
   155 				self.compiler.AddToListVar('POSTLINKFLAGS', 'ole32.lib')
   156 				self.compiler.AddToListVar('POSTLINKFLAGS', 'oleaut32.lib')
   157 				self.compiler.AddToListVar('POSTLINKFLAGS', 'uuid.lib')
   158 				self.compiler.AddToListVar('POSTLINKFLAGS', 'odbc32.lib')
   159 				self.compiler.AddToListVar('POSTLINKFLAGS', 'odbccp32.lib')
   160 
   161 			#Optimization
   162 			if AMBuild.options.opt == '1':
   163 				self.compiler.AddToListVar('CDEFINES', 'NDEBUG')
   164 				if self.vendor == 'gcc' or self.vendor == 'clang':
   165 					self.compiler.AddToListVar('CFLAGS', '-O3')
   166 				elif self.vendor == 'msvc':
   167 					self.compiler.AddToListVar('CFLAGS', '/Ox')
   168 					self.compiler.AddToListVar('POSTLINKFLAGS', '/OPT:ICF')
   169 					self.compiler.AddToListVar('POSTLINKFLAGS', '/OPT:REF')
   170 
   171 			#Debugging
   172 			if AMBuild.options.debug == '1':
   173 				self.compiler.AddToListVar('CDEFINES', 'DEBUG')
   174 				self.compiler.AddToListVar('CDEFINES', '_DEBUG')
   175 				if self.vendor == 'msvc':
   176 					self.compiler.AddToListVar('CFLAGS', '/Od')
   177 					self.compiler.AddToListVar('CFLAGS', '/RTC1')
   178 
   179 			#Platform-specifics
   180 			if AMBuild.target['platform'] == 'linux':
   181 				self.compiler.AddToListVar('CDEFINES', '_LINUX')
   182 				if self.vendor == 'gcc':
   183 					self.compiler.AddToListVar('POSTLINKFLAGS', '-static-libgcc')
   184 				if self.vendor == 'clang':
   185 					self.compiler.AddToListVar('POSTLINKFLAGS', '-lgcc_eh')
   186 			elif AMBuild.target['platform'] == 'darwin':
   187 				self.compiler.AddToListVar('POSTLINKFLAGS', '-mmacosx-version-min=10.5')
   188 				self.compiler.AddToListVar('POSTLINKFLAGS', ['-arch', 'i386'])
   189 				self.compiler.AddToListVar('POSTLINKFLAGS', '-lstdc++')
   190 
   191 				# For OS X dylib versioning
   192 				import re
   193 				productFile = open(os.path.join(AMBuild.sourceFolder, 'product.version'), 'r')
   194 				productContents = productFile.read()
   195 				productFile.close()
   196 				m = re.match('(\d+)\.(\d+)\.(\d+).*', productContents)
   197 				if m == None:
   198 					self.version = '1.0.0'
   199 				else:
   200 					major, minor, release = m.groups()
   201 					self.version = '{0}.{1}.{2}'.format(major, minor, release)
   202 				AMBuild.cache.CacheVariable('version', self.version)
   203 			elif AMBuild.target['platform'] == 'windows':
   204 				self.compiler.AddToListVar('CDEFINES', 'WIN32')
   205 				self.compiler.AddToListVar('CDEFINES', '_WINDOWS')
   206 
   207 			#Finish up
   208 			self.compiler.AddToListVar('CDEFINES', 'SOURCEMOD_BUILD')
   209 			self.compiler.AddToListVar('CDEFINES', 'SM_GENERATED_BUILD')
   210 			self.compiler.AddToListVar('CINCLUDES',
   211 			                           os.path.join(AMBuild.outputFolder, 'includes'))
   212 			self.compiler.ToConfig(AMBuild, 'compiler')
   213 			AMBuild.cache.CacheVariable('vendor', self.vendor)
   214 			self.targetMap = { }
   215 			AMBuild.cache.CacheVariable('targetMap', self.targetMap)
   216 		else:
   217 			self.sdkInfo = AMBuild.cache['sdkInfo']
   218 			self.compiler.FromConfig(AMBuild, 'compiler')
   219 			self.targetMap = AMBuild.cache['targetMap']
   220 
   221 		if AMBuild.target['platform'] == 'windows':
   222 			self.compiler.AddToListVar('RCINCLUDES', os.path.join(AMBuild.sourceFolder, 'public'))
   223 			self.compiler.AddToListVar('RCINCLUDES',
   224 			                           os.path.join(AMBuild.outputFolder, 'includes'))
   225 		self.mmsPath = AMBuild.cache['MMSOURCE18']
   226 
   227 	def DefaultCompiler(self):
   228 		return self.compiler.Clone()
   229 
   230 	def JobMatters(self, jobname):
   231 		file = sys._getframe().f_code.co_filename
   232 		if AMBuild.mode == 'config':
   233 			self.targetMap[jobname] = file
   234 			return True
   235 		if len(AMBuild.args) == 0:
   236 			return True
   237 		if not jobname in AMBuild.args:
   238 			return False
   239 
   240 	def DefaultExtCompiler(self, path):
   241 		compiler = self.DefaultCompiler()
   242 		compiler['CXXINCLUDES'].append(os.path.join(AMBuild.sourceFolder, path))
   243 		compiler['CXXINCLUDES'].append(os.path.join(AMBuild.sourceFolder, path, 'sdk'))
   244 		compiler['CXXINCLUDES'].append(os.path.join(AMBuild.sourceFolder, 'public'))
   245 		compiler['CXXINCLUDES'].append(os.path.join(AMBuild.sourceFolder, 'public', 'extensions'))
   246 		compiler['CXXINCLUDES'].append(os.path.join(AMBuild.sourceFolder, 'public', 'sourcepawn'))
   247 		return compiler
   248 
   249 	def AutoVersion(self, folder, binary):
   250 		if AMBuild.target['platform'] == 'windows':
   251 			env = {'RCDEFINES': ['BINARY_NAME="' + binary.binaryFile + '"', 'SM_GENERATED_BUILD']}
   252 			binary.AddResourceFile(os.path.join(folder, 'version.rc' ), env)
   253 		elif AMBuild.target['platform'] == 'darwin' and isinstance(binary, Cpp.LibraryBuilder):
   254 			binary.compiler['POSTLINKFLAGS'].extend(['-compatibility_version', '1.0.0'])
   255 			binary.compiler['POSTLINKFLAGS'].extend(['-current_version', AMBuild.cache['version']])
   256 		else:
   257 			return
   258 
   259 	def StripBinary(self, job, binary):
   260 		workFolder = os.path.join(AMBuild.outputFolder, job.workFolder)
   261 		src = os.path.join('..', workFolder, binary.binaryFile)
   262 		if not binary.NeedsRelink(src):
   263 			return;
   264 		if AMBuild.target['platform'] == 'linux':
   265 			job.AddCommand(ShellCommand('objcopy --only-keep-debug ' + src + ' ' + src + '.dbg'))
   266 			job.AddCommand(ShellCommand('objcopy --strip-debug ' + src))
   267 			job.AddCommand(ShellCommand('objcopy --add-gnu-debuglink=' + src + '.dbg ' + src))
   268 		elif AMBuild.target['platform'] == 'darwin':
   269 			job.AddCommand(ShellCommand('dsymutil ' + src))
   270 			job.AddCommand(ShellCommand('strip -S ' + src))
   271 
   272 	def PreSetupHL2Job(self, job, builder, sdk):
   273 		info = self.sdkInfo[sdk]
   274 		sdkPath = AMBuild.cache[info['sdk']]
   275 		if AMBuild.target['platform'] == 'linux':
   276 			if sdk == 'ep1':
   277 				staticLibs = os.path.join(sdkPath, 'linux_sdk')
   278 			else:
   279 				staticLibs = os.path.join(sdkPath, 'lib', 'linux')
   280 			workFolder = os.path.join(AMBuild.outputFolder, job.workFolder)
   281 			if sdk in ['ep2v', 'l4d', 'l4d2']:
   282 				for i in ['tier1_i486.a', 'mathlib_i486.a', 'libvstdlib.so', 'libtier0.so']:
   283 					link = os.path.join(workFolder, i)
   284 					target = os.path.join(staticLibs, i)
   285 					try:
   286 						os.lstat(link)
   287 					except:
   288 						job.AddCommand(SymlinkCommand(link, target))
   289 			else:
   290 				for i in ['tier1_i486.a', 'mathlib_i486.a', 'vstdlib_i486.so', 'tier0_i486.so']:
   291 					link = os.path.join(workFolder, i)
   292 					target = os.path.join(staticLibs, i)
   293 					try:
   294 						os.lstat(link)
   295 					except:
   296 						job.AddCommand(SymlinkCommand(link, target))
   297 		elif AMBuild.target['platform'] == 'darwin':
   298 			staticLibs = os.path.join(sdkPath, 'lib', 'mac')
   299 			workFolder = os.path.join(AMBuild.outputFolder, job.workFolder)
   300 			for i in ['tier1_i486.a', 'mathlib_i486.a', 'libvstdlib.dylib', 'libtier0.dylib']:
   301 				link = os.path.join(workFolder, i)
   302 				target = os.path.join(staticLibs, i)
   303 				try:
   304 					os.lstat(link)
   305 				except:
   306 					job.AddCommand(SymlinkCommand(link, target))
   307 		elif AMBuild.target['platform'] == 'windows':
   308 			libs = ['tier0', 'tier1', 'vstdlib', 'mathlib']
   309 			if sdk == 'swarm':
   310 				libs.append('interfaces')
   311 			for lib in libs:
   312 				libPath = os.path.join(sdkPath, 'lib', 'public', lib) + '.lib'
   313 				builder.RebuildIfNewer(libPath)
   314 				builder['POSTLINKFLAGS'].append(libPath)
   315 
   316 	def PostSetupHL2Job(self, job, builder, sdk):
   317 		if AMBuild.target['platform'] in ['linux', 'darwin']:
   318 			builder.AddObjectFiles(['tier1_i486.a', 'mathlib_i486.a'])
   319 	
   320 	def DefaultHL2Compiler(self, path, sdk, noLink = False, oldMms = '-legacy'):
   321 		compiler = self.DefaultExtCompiler(path)
   322 
   323 		mms = 'core'
   324 		if sdk == 'ep1':
   325 			mms += oldMms
   326 
   327 		compiler['CXXINCLUDES'].append(os.path.join(self.mmsPath, mms))
   328 		compiler['CXXINCLUDES'].append(os.path.join(self.mmsPath, mms, 'sourcehook'))
   329 
   330 		info = self.possibleSdks
   331 		compiler['CDEFINES'].extend(['SE_' + info[i]['name'] + '=' + info[i]['def'] for i in info])
   332 
   333 		paths = [['public'], ['public', 'engine'], ['public', 'mathlib'], ['public', 'vstdlib'],
   334 						 ['public', 'tier0'], ['public', 'tier1']]
   335 		if sdk == 'ep1' or sdk == 'darkm':
   336 			paths.append(['public', 'dlls'])
   337 			paths.append(['game_shared'])
   338 		else:
   339 			paths.append(['public', 'game', 'server'])
   340 			paths.append(['public', 'toolframework'])
   341 			paths.append(['game', 'shared'])
   342 			paths.append(['common'])
   343 
   344 		info = self.sdkInfo[sdk]
   345 		sdkPath = AMBuild.cache[info['sdk']]
   346 
   347 		compiler['CDEFINES'].append('SOURCE_ENGINE=' + info['def'])
   348 
   349 		if sdk == 'swarm' and AMBuild.target['platform'] == 'windows':
   350 			compiler['CDEFINES'].extend(['COMPILER_MSVC', 'COMPILER_MSVC32'])
   351 
   352 		if sdk == 'ep1':
   353 			if AMBuild.target['platform'] == 'linux':
   354 				staticLibs = os.path.join(sdkPath, 'linux_sdk')
   355 		else:
   356 			if AMBuild.target['platform'] == 'linux':
   357 				staticLibs = os.path.join(sdkPath, 'lib', 'linux')
   358 			elif AMBuild.target['platform'] == 'darwin':
   359 				staticLibs = os.path.join(sdkPath, 'lib', 'mac')
   360 
   361 		for i in paths:
   362 			compiler['CXXINCLUDES'].append(os.path.join(sdkPath, *i))
   363 
   364 		if not noLink:
   365 			if AMBuild.target['platform'] == 'linux':
   366 				compiler['POSTLINKFLAGS'][0:0] = ['-lm']
   367 				if sdk in ['ep2v', 'l4d', 'l4d2']:
   368 					compiler['POSTLINKFLAGS'][0:0] = ['libtier0.so']
   369 					compiler['POSTLINKFLAGS'][0:0] = ['libvstdlib.so']
   370 				else:
   371 					compiler['POSTLINKFLAGS'][0:0] = ['tier0_i486.so']
   372 					compiler['POSTLINKFLAGS'][0:0] = ['vstdlib_i486.so']
   373 			elif AMBuild.target['platform'] == 'darwin':
   374 				compiler['POSTLINKFLAGS'][0:0] = ['libtier0.dylib']
   375 				compiler['POSTLINKFLAGS'][0:0] = ['libvstdlib.dylib']
   376 
   377 		return compiler
   378 
   379 sm = SM()
   380 globals = {
   381 	'SM': sm
   382 }
   383 
   384 AMBuild.Include(os.path.join('tools', 'buildbot', 'Versioning'), globals)
   385 
   386 FileList = [
   387 		['loader', 'AMBuilder'],
   388 		['core', 'AMBuilder'],
   389 		['core', 'logic', 'AMBuilder'],
   390 		['extensions', 'bintools', 'AMBuilder'],
   391 		['extensions', 'clientprefs', 'AMBuilder'],
   392 		['extensions', 'cstrike', 'AMBuilder'],
   393 		['extensions', 'curl', 'AMBuilder'],
   394 		['extensions', 'geoip', 'AMBuilder'],
   395 		['extensions', 'mysql', 'AMBuilder'],
   396 		['extensions', 'sdktools', 'AMBuilder'],
   397 		['extensions', 'topmenus', 'AMBuilder'],
   398 		['extensions', 'updater', 'AMBuilder'],
   399 		['extensions', 'sqlite', 'AMBuilder'],
   400 		['extensions', 'regex', 'AMBuilder'],
   401 		['extensions', 'tf2', 'AMBuilder'],
   402 		['sourcepawn', 'jit', 'AMBuilder'],
   403 		['sourcepawn', 'compiler', 'AMBuilder'],
   404 		['plugins', 'AMBuilder'],
   405 		['tools', 'buildbot', 'PackageScript'],
   406 		['tools', 'buildbot', 'BreakpadSymbols']
   407 	]
   408 
   409 for parts in FileList:
   410 	AMBuild.Include(os.path.join(*parts), globals)
   411