AMBuildScript
author Asher Baker <asherkin@gmail.com>
Thu Feb 16 19:26:49 2012 +0000 (2012-02-16)
changeset 3457 387b27fb575b
parent 3388 cbee39527756
child 3458 62ad320dd01a
permissions -rw-r--r--
Generate debugging information during compilation. (bug 5227, 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 						(info, sdk) = findDictByKey(self.possibleSdks, 'sdk', i)
    84 						self.sdkInfo[sdk] = info	
    85 					elif head == None or head == oldhead:
    86 						raise Exception('Could not find a valid path for {0}'.format(i))
    87 				AMBuild.cache.CacheVariable(i, path)
    88 
    89 			if len(self.sdkInfo) < 1:
    90 				raise Exception('At least one SDK must be available.')
    91 				
    92 			AMBuild.cache.CacheVariable('sdkInfo', self.sdkInfo)
    93 
    94 			#Set up defines
    95 			cxx = self.compiler.cxx
    96 			if isinstance(cxx, Cpp.CompatGCC):
    97 				if isinstance(cxx, Cpp.GCC):
    98 					self.vendor = 'gcc'
    99 				elif isinstance(cxx, Cpp.Clang):
   100 					self.vendor = 'clang'
   101 				self.compiler.AddToListVar('CDEFINES', 'stricmp=strcasecmp')
   102 				self.compiler.AddToListVar('CDEFINES', '_stricmp=strcasecmp')
   103 				self.compiler.AddToListVar('CDEFINES', '_snprintf=snprintf')
   104 				self.compiler.AddToListVar('CDEFINES', '_vsnprintf=vsnprintf')
   105 				self.compiler.AddToListVar('CFLAGS', '-pipe')
   106 				self.compiler.AddToListVar('CFLAGS', '-fno-strict-aliasing')
   107 				if (self.vendor == 'gcc' and cxx.majorVersion >= 4) or self.vendor == 'clang':
   108 					self.compiler.AddToListVar('CFLAGS', '-fvisibility=hidden')
   109 					self.compiler.AddToListVar('CXXFLAGS', '-fvisibility-inlines-hidden')
   110 				self.compiler.AddToListVar('CFLAGS', '-Wall')
   111 				self.compiler.AddToListVar('CFLAGS', '-Werror')
   112 				self.compiler.AddToListVar('CFLAGS', '-Wno-uninitialized')
   113 				self.compiler.AddToListVar('CFLAGS', '-Wno-unused')
   114 				self.compiler.AddToListVar('CFLAGS', '-Wno-switch')
   115 				self.compiler.AddToListVar('CFLAGS', '-msse')
   116 				self.compiler.AddToListVar('CFLAGS', '-m32')
   117 				self.compiler.AddToListVar('CFLAGS', '-g3')
   118 				self.compiler.AddToListVar('POSTLINKFLAGS', '-m32')
   119 				self.compiler.AddToListVar('CXXFLAGS', '-fno-exceptions')
   120 				self.compiler.AddToListVar('CXXFLAGS', '-fno-rtti')
   121 				self.compiler.AddToListVar('CXXFLAGS', '-fno-threadsafe-statics')
   122 				self.compiler.AddToListVar('CXXFLAGS', '-Wno-non-virtual-dtor')
   123 				self.compiler.AddToListVar('CXXFLAGS', '-Wno-overloaded-virtual')
   124 				self.compiler.AddToListVar('CDEFINES', 'HAVE_STDINT_H')
   125 				self.compiler.AddToListVar('CDEFINES', 'GNUC')
   126 				if self.vendor == 'gcc':
   127 					self.compiler.AddToListVar('CFLAGS', '-mfpmath=sse')
   128 			elif isinstance(cxx, Cpp.MSVC):
   129 				self.vendor = 'msvc'
   130 				if AMBuild.options.debug == '1':
   131 					self.compiler.AddToListVar('CFLAGS', '/MTd')
   132 					self.compiler.AddToListVar('POSTLINKFLAGS', '/NODEFAULTLIB:libcmt')
   133 				else:
   134 					self.compiler.AddToListVar('CFLAGS', '/MT')
   135 				self.compiler.AddToListVar('CDEFINES', '_CRT_SECURE_NO_DEPRECATE')
   136 				self.compiler.AddToListVar('CDEFINES', '_CRT_SECURE_NO_WARNINGS')
   137 				self.compiler.AddToListVar('CDEFINES', '_CRT_NONSTDC_NO_DEPRECATE')
   138 				self.compiler.AddToListVar('CXXFLAGS', '/EHsc')
   139 				self.compiler.AddToListVar('CXXFLAGS', '/GR-')
   140 				self.compiler.AddToListVar('CFLAGS', '/W3')
   141 				self.compiler.AddToListVar('CFLAGS', '/nologo')
   142 				self.compiler.AddToListVar('CFLAGS', '/Zi')
   143 				self.compiler.AddToListVar('CXXFLAGS', '/TP')
   144 				self.compiler.AddToListVar('POSTLINKFLAGS', '/DEBUG')
   145 				self.compiler.AddToListVar('POSTLINKFLAGS', '/MACHINE:X86')
   146 				self.compiler.AddToListVar('POSTLINKFLAGS', '/SUBSYSTEM:WINDOWS')
   147 				self.compiler.AddToListVar('POSTLINKFLAGS', 'kernel32.lib')
   148 				self.compiler.AddToListVar('POSTLINKFLAGS', 'user32.lib')
   149 				self.compiler.AddToListVar('POSTLINKFLAGS', 'gdi32.lib')
   150 				self.compiler.AddToListVar('POSTLINKFLAGS', 'winspool.lib')
   151 				self.compiler.AddToListVar('POSTLINKFLAGS', 'comdlg32.lib')
   152 				self.compiler.AddToListVar('POSTLINKFLAGS', 'advapi32.lib')
   153 				self.compiler.AddToListVar('POSTLINKFLAGS', 'shell32.lib')
   154 				self.compiler.AddToListVar('POSTLINKFLAGS', 'ole32.lib')
   155 				self.compiler.AddToListVar('POSTLINKFLAGS', 'oleaut32.lib')
   156 				self.compiler.AddToListVar('POSTLINKFLAGS', 'uuid.lib')
   157 				self.compiler.AddToListVar('POSTLINKFLAGS', 'odbc32.lib')
   158 				self.compiler.AddToListVar('POSTLINKFLAGS', 'odbccp32.lib')
   159 
   160 			#Optimization
   161 			if AMBuild.options.opt == '1':
   162 				self.compiler.AddToListVar('CDEFINES', 'NDEBUG')
   163 				if self.vendor == 'gcc' or self.vendor == 'clang':
   164 					self.compiler.AddToListVar('CFLAGS', '-O3')
   165 				elif self.vendor == 'msvc':
   166 					self.compiler.AddToListVar('CFLAGS', '/Ox')
   167 					self.compiler.AddToListVar('POSTLINKFLAGS', '/OPT:ICF')
   168 					self.compiler.AddToListVar('POSTLINKFLAGS', '/OPT:REF')
   169 
   170 			#Debugging
   171 			if AMBuild.options.debug == '1':
   172 				self.compiler.AddToListVar('CDEFINES', 'DEBUG')
   173 				self.compiler.AddToListVar('CDEFINES', '_DEBUG')
   174 				if self.vendor == 'msvc':
   175 					self.compiler.AddToListVar('CFLAGS', '/Od')
   176 					self.compiler.AddToListVar('CFLAGS', '/RTC1')
   177 
   178 			#Platform-specifics
   179 			if AMBuild.target['platform'] == 'linux':
   180 				self.compiler.AddToListVar('CDEFINES', '_LINUX')
   181 				if self.vendor == 'gcc':
   182 					self.compiler.AddToListVar('POSTLINKFLAGS', '-static-libgcc')
   183 				if self.vendor == 'clang':
   184 					self.compiler.AddToListVar('POSTLINKFLAGS', '-lgcc_eh')
   185 			elif AMBuild.target['platform'] == 'darwin':
   186 				self.compiler.AddToListVar('CFLAGS', ['-isysroot',
   187 				                                      '/Developer/SDKs/MacOSX10.5.sdk'])
   188 				self.compiler.AddToListVar('POSTLINKFLAGS', '-mmacosx-version-min=10.5')
   189 				self.compiler.AddToListVar('POSTLINKFLAGS', ['-arch', 'i386'])
   190 				self.compiler.AddToListVar('POSTLINKFLAGS', '-lstdc++')
   191 
   192 				# For OS X dylib versioning
   193 				import re
   194 				productFile = open(os.path.join(AMBuild.sourceFolder, 'product.version'), 'r')
   195 				productContents = productFile.read()
   196 				productFile.close()
   197 				m = re.match('(\d+)\.(\d+)\.(\d+).*', productContents)
   198 				if m == None:
   199 					self.version = '1.0.0'
   200 				else:
   201 					major, minor, release = m.groups()
   202 					self.version = '{0}.{1}.{2}'.format(major, minor, release)
   203 				AMBuild.cache.CacheVariable('version', self.version)
   204 			elif AMBuild.target['platform'] == 'windows':
   205 				self.compiler.AddToListVar('CDEFINES', 'WIN32')
   206 				self.compiler.AddToListVar('CDEFINES', '_WINDOWS')
   207 
   208 			#Finish up
   209 			self.compiler.AddToListVar('CDEFINES', 'SOURCEMOD_BUILD')
   210 			self.compiler.AddToListVar('CDEFINES', 'SM_GENERATED_BUILD')
   211 			self.compiler.AddToListVar('CINCLUDES',
   212 			                           os.path.join(AMBuild.outputFolder, 'includes'))
   213 			self.compiler.ToConfig(AMBuild, 'compiler')
   214 			AMBuild.cache.CacheVariable('vendor', self.vendor)
   215 			self.targetMap = { }
   216 			AMBuild.cache.CacheVariable('targetMap', self.targetMap)
   217 		else:
   218 			self.sdkInfo = AMBuild.cache['sdkInfo']
   219 			self.compiler.FromConfig(AMBuild, 'compiler')
   220 			self.targetMap = AMBuild.cache['targetMap']
   221 
   222 		if AMBuild.target['platform'] == 'windows':
   223 			self.compiler.AddToListVar('RCINCLUDES', os.path.join(AMBuild.sourceFolder, 'public'))
   224 			self.compiler.AddToListVar('RCINCLUDES',
   225 			                           os.path.join(AMBuild.outputFolder, 'includes'))
   226 		self.mmsPath = AMBuild.cache['MMSOURCE18']
   227 
   228 	def DefaultCompiler(self):
   229 		return self.compiler.Clone()
   230 
   231 	def JobMatters(self, jobname):
   232 		file = sys._getframe().f_code.co_filename
   233 		if AMBuild.mode == 'config':
   234 			self.targetMap[jobname] = file
   235 			return True
   236 		if len(AMBuild.args) == 0:
   237 			return True
   238 		if not jobname in AMBuild.args:
   239 			return False
   240 
   241 	def DefaultExtCompiler(self, path):
   242 		compiler = self.DefaultCompiler()
   243 		compiler['CXXINCLUDES'].append(os.path.join(AMBuild.sourceFolder, path))
   244 		compiler['CXXINCLUDES'].append(os.path.join(AMBuild.sourceFolder, path, 'sdk'))
   245 		compiler['CXXINCLUDES'].append(os.path.join(AMBuild.sourceFolder, 'public'))
   246 		compiler['CXXINCLUDES'].append(os.path.join(AMBuild.sourceFolder, 'public', 'extensions'))
   247 		compiler['CXXINCLUDES'].append(os.path.join(AMBuild.sourceFolder, 'public', 'sourcepawn'))
   248 		return compiler
   249 
   250 	def AutoVersion(self, folder, binary):
   251 		if AMBuild.target['platform'] == 'windows':
   252 			env = {'RCDEFINES': ['BINARY_NAME="' + binary.binaryFile + '"', 'SM_GENERATED_BUILD']}
   253 			binary.AddResourceFile(os.path.join(folder, 'version.rc' ), env)
   254 		elif AMBuild.target['platform'] == 'darwin' and isinstance(binary, Cpp.LibraryBuilder):
   255 			binary.compiler['POSTLINKFLAGS'].extend(['-compatibility_version', '1.0.0'])
   256 			binary.compiler['POSTLINKFLAGS'].extend(['-current_version', AMBuild.cache['version']])
   257 		else:
   258 			return
   259 
   260 	def StripBinary(self, job, binary):
   261 		workFolder = os.path.join(AMBuild.outputFolder, job.workFolder)
   262 		src = os.path.join('..', workFolder, binary.binaryFile)
   263 		if AMBuild.target['platform'] == 'linux':
   264 			job.AddCommand(ShellCommand('objcopy --only-keep-debug ' + src + ' ' + src + '.dbg'))
   265 			job.AddCommand(ShellCommand('objcopy --strip-debug ' + src))
   266 			job.AddCommand(ShellCommand('objcopy --add-gnu-debuglink=' + src + '.dbg ' + src))
   267 		elif AMBuild.target['platform'] == 'darwin':
   268 			job.AddCommand(ShellCommand('dsymutil ' + src))
   269 			job.AddCommand(ShellCommand('strip -S ' + src))
   270 
   271 	def PreSetupHL2Job(self, job, builder, sdk):
   272 		info = self.sdkInfo[sdk]
   273 		sdkPath = AMBuild.cache[info['sdk']]
   274 		if AMBuild.target['platform'] == 'linux':
   275 			if sdk == 'ep1':
   276 				staticLibs = os.path.join(sdkPath, 'linux_sdk')
   277 			else:
   278 				staticLibs = os.path.join(sdkPath, 'lib', 'linux')
   279 			workFolder = os.path.join(AMBuild.outputFolder, job.workFolder)
   280 			if sdk in ['ep2v', 'l4d', 'l4d2']:
   281 				for i in ['tier1_i486.a', 'mathlib_i486.a', 'libvstdlib.so', 'libtier0.so']:
   282 					link = os.path.join(workFolder, i)
   283 					target = os.path.join(staticLibs, i)
   284 					try:
   285 						os.lstat(link)
   286 					except:
   287 						job.AddCommand(SymlinkCommand(link, target))
   288 			else:
   289 				for i in ['tier1_i486.a', 'mathlib_i486.a', 'vstdlib_i486.so', 'tier0_i486.so']:
   290 					link = os.path.join(workFolder, i)
   291 					target = os.path.join(staticLibs, i)
   292 					try:
   293 						os.lstat(link)
   294 					except:
   295 						job.AddCommand(SymlinkCommand(link, target))
   296 		elif AMBuild.target['platform'] == 'darwin':
   297 			staticLibs = os.path.join(sdkPath, 'lib', 'mac')
   298 			workFolder = os.path.join(AMBuild.outputFolder, job.workFolder)
   299 			for i in ['tier1_i486.a', 'mathlib_i486.a', 'libvstdlib.dylib', 'libtier0.dylib']:
   300 				link = os.path.join(workFolder, i)
   301 				target = os.path.join(staticLibs, i)
   302 				try:
   303 					os.lstat(link)
   304 				except:
   305 					job.AddCommand(SymlinkCommand(link, target))
   306 		elif AMBuild.target['platform'] == 'windows':
   307 			libs = ['tier0', 'tier1', 'vstdlib', 'mathlib']
   308 			if sdk == 'swarm':
   309 				libs.append('interfaces')
   310 			for lib in libs:
   311 				libPath = os.path.join(sdkPath, 'lib', 'public', lib) + '.lib'
   312 				builder.RebuildIfNewer(libPath)
   313 				builder['POSTLINKFLAGS'].append(libPath)
   314 
   315 	def PostSetupHL2Job(self, job, builder, sdk):
   316 		if AMBuild.target['platform'] in ['linux', 'darwin']:
   317 			builder.AddObjectFiles(['tier1_i486.a', 'mathlib_i486.a'])
   318 	
   319 	def DefaultHL2Compiler(self, path, sdk, noLink = False, oldMms = '-legacy'):
   320 		compiler = self.DefaultExtCompiler(path)
   321 
   322 		mms = 'core'
   323 		if sdk == 'ep1':
   324 			mms += oldMms
   325 
   326 		compiler['CXXINCLUDES'].append(os.path.join(self.mmsPath, mms))
   327 		compiler['CXXINCLUDES'].append(os.path.join(self.mmsPath, mms, 'sourcehook'))
   328 
   329 		info = self.possibleSdks
   330 		compiler['CDEFINES'].extend(['SE_' + info[i]['name'] + '=' + info[i]['def'] for i in info])
   331 
   332 		paths = [['public'], ['public', 'engine'], ['public', 'mathlib'], ['public', 'vstdlib'],
   333 						 ['public', 'tier0'], ['public', 'tier1']]
   334 		if sdk == 'ep1' or sdk == 'darkm':
   335 			paths.append(['public', 'dlls'])
   336 			paths.append(['game_shared'])
   337 		else:
   338 			paths.append(['public', 'game', 'server'])
   339 			paths.append(['public', 'toolframework'])
   340 			paths.append(['game', 'shared'])
   341 			paths.append(['common'])
   342 
   343 		info = self.sdkInfo[sdk]
   344 		sdkPath = AMBuild.cache[info['sdk']]
   345 
   346 		compiler['CDEFINES'].append('SOURCE_ENGINE=' + info['def'])
   347 
   348 		if sdk == 'swarm' and AMBuild.target['platform'] == 'windows':
   349 			compiler['CDEFINES'].extend(['COMPILER_MSVC', 'COMPILER_MSVC32'])
   350 
   351 		if sdk == 'ep1':
   352 			if AMBuild.target['platform'] == 'linux':
   353 				staticLibs = os.path.join(sdkPath, 'linux_sdk')
   354 		else:
   355 			if AMBuild.target['platform'] == 'linux':
   356 				staticLibs = os.path.join(sdkPath, 'lib', 'linux')
   357 			elif AMBuild.target['platform'] == 'darwin':
   358 				staticLibs = os.path.join(sdkPath, 'lib', 'mac')
   359 
   360 		for i in paths:
   361 			compiler['CXXINCLUDES'].append(os.path.join(sdkPath, *i))
   362 
   363 		if not noLink:
   364 			if AMBuild.target['platform'] == 'linux':
   365 				compiler['POSTLINKFLAGS'][0:0] = ['-lm']
   366 				if sdk in ['ep2v', 'l4d', 'l4d2']:
   367 					compiler['POSTLINKFLAGS'][0:0] = ['libtier0.so']
   368 					compiler['POSTLINKFLAGS'][0:0] = ['libvstdlib.so']
   369 				else:
   370 					compiler['POSTLINKFLAGS'][0:0] = ['tier0_i486.so']
   371 					compiler['POSTLINKFLAGS'][0:0] = ['vstdlib_i486.so']
   372 			elif AMBuild.target['platform'] == 'darwin':
   373 				compiler['POSTLINKFLAGS'][0:0] = ['libtier0.dylib']
   374 				compiler['POSTLINKFLAGS'][0:0] = ['libvstdlib.dylib']
   375 
   376 		return compiler
   377 
   378 sm = SM()
   379 globals = {
   380 	'SM': sm
   381 }
   382 
   383 AMBuild.Include(os.path.join('tools', 'buildbot', 'Versioning'), globals)
   384 
   385 FileList = [
   386 		['loader', 'AMBuilder'],
   387 		['core', 'AMBuilder'],
   388 		['core', 'logic', 'AMBuilder'],
   389 		['extensions', 'bintools', 'AMBuilder'],
   390 		['extensions', 'clientprefs', 'AMBuilder'],
   391 		['extensions', 'cstrike', 'AMBuilder'],
   392 		['extensions', 'curl', 'AMBuilder'],
   393 		['extensions', 'geoip', 'AMBuilder'],
   394 		['extensions', 'mysql', 'AMBuilder'],
   395 		['extensions', 'sdktools', 'AMBuilder'],
   396 		['extensions', 'topmenus', 'AMBuilder'],
   397 		['extensions', 'updater', 'AMBuilder'],
   398 		['extensions', 'sqlite', 'AMBuilder'],
   399 		['extensions', 'regex', 'AMBuilder'],
   400 		['extensions', 'tf2', 'AMBuilder'],
   401 		['sourcepawn', 'jit', 'AMBuilder'],
   402 		['sourcepawn', 'compiler', 'AMBuilder'],
   403 		['plugins', 'AMBuilder'],
   404 		['tools', 'buildbot', 'PackageScript']
   405 	]
   406 
   407 for parts in FileList:
   408 	AMBuild.Include(os.path.join(*parts), globals)
   409