AMBuildScript
author Nicholas Hastings <skamonkey@gmail.com>
Wed May 26 08:30:13 2010 -0400 (2010-05-26)
changeset 3018 5850c7c4f594
parent 2998 94e008ed3db9
child 3023 354fefa5ff02
permissions -rw-r--r--
Fixed SDKTools sm_dump_datamaps crash on improperly created entities (bug 4424, r=pred)
     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 
     6 class SM:
     7 	def __init__(self):
     8 		self.compiler = Cpp.Compiler()
     9 
    10 		#Build SDK info
    11 		self.sdkInfo = { }
    12 		self.sdkInfo['ep1'] =   {'sdk': 'HL2SDK',          'ext': '1.ep1',   'def': '1',
    13 		                         'name': 'EPISODEONE',     'platform': ['windows', 'linux']}
    14 		self.sdkInfo['ep2'] =   {'sdk': 'HL2SDKOB',        'ext': '2.ep2',   'def': '3',
    15 		                         'name': 'ORANGEBOX',      'platform': ['windows', 'linux']}
    16 		self.sdkInfo['ep2v'] =  {'sdk': 'HL2SDKOBVALVE',   'ext': '2.ep2v',  'def': '4',
    17 		                         'name': 'ORANGEBOXVALVE', 'platform': ['windows', 'linux', 'darwin']}
    18 		self.sdkInfo['l4d'] =   {'sdk': 'HL2SDKL4D',       'ext': '2.l4d',   'def': '5',
    19 		                         'name': 'LEFT4DEAD',      'platform': ['windows', 'linux']}
    20 		self.sdkInfo['l4d2'] =  {'sdk': 'HL2SDKL4D2',      'ext': '2.l4d2',  'def': '6',
    21 		                         'name': 'LEFT4DEAD2',     'platform': ['windows', 'linux']}
    22 		self.sdkInfo['darkm'] = {'sdk': 'HL2SDK-DARKM',    'ext': '2.darkm', 'def': '2',
    23 		                         'name': 'DARKMESSIAH',    'platform': ['windows']}
    24 
    25 		if AMBuild.mode == 'config':
    26 			#Detect compilers
    27 			self.compiler.DetectAll(AMBuild)
    28 
    29 			#Detect variables
    30 			envvars = { 'MMSOURCE18':    'mmsource-1.8',
    31 									'HL2SDKOBVALVE': 'hl2sdk-ob-valve',
    32 									'MYSQL5':        'mysql-5.0'
    33 			}
    34 
    35 			if AMBuild.target['platform'] != 'darwin':
    36 				envvars['HL2SDK'] = 'hl2sdk'
    37 				envvars['HL2SDKOB'] = 'hl2sdk-ob'
    38 				envvars['HL2SDKL4D'] = 'hl2sdk-l4d'
    39 				envvars['HL2SDKL4D2'] = 'hl2sdk-l4d2'
    40 
    41 			#Dark Messiah is Windows-only
    42 			if AMBuild.target['platform'] == 'windows':
    43 				envvars['HL2SDK-DARKM'] = 'hl2sdk-darkm'
    44 
    45 			#Must have a path for each envvar (file a bug if you don't like this)
    46 			for i in envvars:
    47 				if i in os.environ:
    48 					path = os.environ[i]
    49 					if not os.path.isdir(path):
    50 						raise Exception('Path for {0} was not found: {1}'.format(i, path))
    51 				else:
    52 					head = os.getcwd()
    53 					oldhead = None
    54 					while head != None and head != oldhead:
    55 						path = os.path.join(head, envvars[i])
    56 						if os.path.isdir(path):
    57 							break
    58 						oldhead = head
    59 						head, tail = os.path.split(head)
    60 					if head == None or head == oldhead:
    61 						raise Exception('Could not find a valid path for {0}'.format(i))
    62 				AMBuild.cache.CacheVariable(i, path)
    63 
    64 			#Set up defines
    65 			cxx = self.compiler.cxx
    66 			if isinstance(cxx, Cpp.GCC):
    67 				self.vendor = 'gcc'
    68 				self.compiler.AddToListVar('CDEFINES', 'stricmp=strcasecmp')
    69 				self.compiler.AddToListVar('CDEFINES', '_stricmp=strcasecmp')
    70 				self.compiler.AddToListVar('CDEFINES', '_snprintf=snprintf')
    71 				self.compiler.AddToListVar('CDEFINES', '_vsnprintf=vsnprintf')
    72 				self.compiler.AddToListVar('CFLAGS', '-pipe')
    73 				self.compiler.AddToListVar('CFLAGS', '-fno-strict-aliasing')
    74 				if cxx.majorVersion >= 4:
    75 					self.compiler.AddToListVar('CFLAGS', '-fvisibility=hidden')
    76 					self.compiler.AddToListVar('CXXFLAGS', '-fvisibility-inlines-hidden')
    77 				self.compiler.AddToListVar('CFLAGS', '-Wall')
    78 				self.compiler.AddToListVar('CFLAGS', '-Werror')
    79 				self.compiler.AddToListVar('CFLAGS', '-Wno-uninitialized')
    80 				self.compiler.AddToListVar('CFLAGS', '-Wno-unused')
    81 				self.compiler.AddToListVar('CFLAGS', '-Wno-switch')
    82 				self.compiler.AddToListVar('CFLAGS', '-mfpmath=sse')
    83 				self.compiler.AddToListVar('CFLAGS', '-msse')
    84 				self.compiler.AddToListVar('CFLAGS', '-m32')
    85 				self.compiler.AddToListVar('POSTLINKFLAGS', '-m32')
    86 				self.compiler.AddToListVar('CFLAGS', '-static-libgcc')
    87 				self.compiler.AddToListVar('CXXFLAGS', '-fno-exceptions')
    88 				self.compiler.AddToListVar('CXXFLAGS', '-fno-rtti')
    89 				self.compiler.AddToListVar('CXXFLAGS', '-fno-threadsafe-statics')
    90 				self.compiler.AddToListVar('CXXFLAGS', '-Wno-non-virtual-dtor')
    91 				self.compiler.AddToListVar('CDEFINES', 'HAVE_STDINT_H')
    92 			elif isinstance(cxx, Cpp.MSVC):
    93 				self.vendor = 'msvc'
    94 				if AMBuild.options.debug == '1':
    95 					self.compiler.AddToListVar('CFLAGS', '/MTd')
    96 				else:
    97 					self.compiler.AddToListVar('CFLAGS', '/MT')
    98 				self.compiler.AddToListVar('CDEFINES', '_CRT_SECURE_NO_DEPRECATE')
    99 				self.compiler.AddToListVar('CDEFINES', '_CRT_SECURE_NO_WARNINGS')
   100 				self.compiler.AddToListVar('CDEFINES', '_CRT_NONSTDC_NO_DEPRECATE')
   101 				self.compiler.AddToListVar('CXXFLAGS', '/EHsc')
   102 				self.compiler.AddToListVar('CXXFLAGS', '/GR-')
   103 				self.compiler.AddToListVar('CFLAGS', '/W3')
   104 				self.compiler.AddToListVar('CFLAGS', '/nologo')
   105 				self.compiler.AddToListVar('CFLAGS', '/Zi')
   106 				self.compiler.AddToListVar('CXXFLAGS', '/TP')
   107 				self.compiler.AddToListVar('POSTLINKFLAGS', '/DEBUG')
   108 				self.compiler.AddToListVar('POSTLINKFLAGS', '/MACHINE:X86')
   109 				self.compiler.AddToListVar('POSTLINKFLAGS', '/SUBSYSTEM:WINDOWS')
   110 				self.compiler.AddToListVar('POSTLINKFLAGS', 'kernel32.lib')
   111 				self.compiler.AddToListVar('POSTLINKFLAGS', 'user32.lib')
   112 				self.compiler.AddToListVar('POSTLINKFLAGS', 'gdi32.lib')
   113 				self.compiler.AddToListVar('POSTLINKFLAGS', 'winspool.lib')
   114 				self.compiler.AddToListVar('POSTLINKFLAGS', 'comdlg32.lib')
   115 				self.compiler.AddToListVar('POSTLINKFLAGS', 'advapi32.lib')
   116 				self.compiler.AddToListVar('POSTLINKFLAGS', 'shell32.lib')
   117 				self.compiler.AddToListVar('POSTLINKFLAGS', 'ole32.lib')
   118 				self.compiler.AddToListVar('POSTLINKFLAGS', 'oleaut32.lib')
   119 				self.compiler.AddToListVar('POSTLINKFLAGS', 'uuid.lib')
   120 				self.compiler.AddToListVar('POSTLINKFLAGS', 'odbc32.lib')
   121 				self.compiler.AddToListVar('POSTLINKFLAGS', 'odbccp32.lib')
   122 
   123 			#Optimization
   124 			if AMBuild.options.opt == '1':
   125 				self.compiler.AddToListVar('CDEFINES', 'NDEBUG')
   126 				if self.vendor == 'gcc':
   127 					self.compiler.AddToListVar('CFLAGS', '-O3')
   128 				elif self.vendor == 'msvc':
   129 					self.compiler.AddToListVar('CFLAGS', '/Ox')
   130 					self.compiler.AddToListVar('POSTLINKFLAGS', '/OPT:ICF')
   131 					self.compiler.AddToListVar('POSTLINKFLAGS', '/OPT:REF')
   132 
   133 			#Debugging
   134 			if AMBuild.options.debug == '1':
   135 				self.compiler.AddToListVar('CDEFINES', 'DEBUG')
   136 				self.compiler.AddToListVar('CDEFINES', '_DEBUG')
   137 				if self.vendor == 'gcc':
   138 					self.compiler.AddToListVar('CFLAGS', '-g3')
   139 				elif self.vendor == 'msvc':
   140 					self.compiler.AddToListVar('CFLAGS', '/Od')
   141 					self.compiler.AddToListVar('CFLAGS', '/RTC1')
   142 
   143 			#Platform-specifics
   144 			if AMBuild.target['platform'] == 'linux':
   145 				self.compiler.AddToListVar('CDEFINES', '_LINUX')
   146 			elif AMBuild.target['platform'] == 'darwin':
   147 				self.compiler.AddToListVar('CFLAGS', ['-isysroot',
   148 				                                      '/Developer/SDKs/MacOSX10.5.sdk'])
   149 				self.compiler.AddToListVar('POSTLINKFLAGS', '-mmacosx-version-min=10.5')
   150 				self.compiler.AddToListVar('POSTLINKFLAGS', ['-arch', 'i386'])
   151 				self.compiler.AddToListVar('POSTLINKFLAGS', '-lstdc++')
   152 			elif AMBuild.target['platform'] == 'windows':
   153 				self.compiler.AddToListVar('CDEFINES', 'WIN32')
   154 				self.compiler.AddToListVar('CDEFINES', '_WINDOWS')
   155 
   156 			#Finish up
   157 			self.compiler.AddToListVar('CDEFINES', 'SOURCEMOD_BUILD')
   158 			self.compiler.AddToListVar('CDEFINES', 'SM_GENERATED_BUILD')
   159 			self.compiler.AddToListVar('CINCLUDES',
   160 			                           os.path.join(AMBuild.outputFolder, 'includes'))
   161 			self.compiler.ToConfig(AMBuild, 'compiler')
   162 			AMBuild.cache.CacheVariable('vendor', self.vendor)
   163 			self.targetMap = { }
   164 			AMBuild.cache.CacheVariable('targetMap', self.targetMap)
   165 		else:
   166 			self.compiler.FromConfig(AMBuild, 'compiler')
   167 			self.targetMap = AMBuild.cache['targetMap']
   168 
   169 		if AMBuild.target['platform'] == 'windows':
   170 			self.compiler.AddToListVar('RCINCLUDES', os.path.join(AMBuild.sourceFolder, 'public'))
   171 			self.compiler.AddToListVar('RCINCLUDES',
   172 			                           os.path.join(AMBuild.outputFolder, 'includes'))
   173 		self.mmsPath = AMBuild.cache['MMSOURCE18']
   174 
   175 	def DefaultCompiler(self):
   176 		return self.compiler.Clone()
   177 
   178 	def JobMatters(self, jobname):
   179 		file = sys._getframe().f_code.co_filename
   180 		if AMBuild.mode == 'config':
   181 			self.targetMap[jobname] = file
   182 			return True
   183 		if len(AMBuild.args) == 0:
   184 			return True
   185 		if not jobname in AMBuild.args:
   186 			return False
   187 
   188 	def DefaultExtCompiler(self, path):
   189 		compiler = self.DefaultCompiler()
   190 		compiler['CXXINCLUDES'].append(os.path.join(AMBuild.sourceFolder, path))
   191 		compiler['CXXINCLUDES'].append(os.path.join(AMBuild.sourceFolder, path, 'sdk'))
   192 		compiler['CXXINCLUDES'].append(os.path.join(AMBuild.sourceFolder, 'public'))
   193 		compiler['CXXINCLUDES'].append(os.path.join(AMBuild.sourceFolder, 'public', 'extensions'))
   194 		compiler['CXXINCLUDES'].append(os.path.join(AMBuild.sourceFolder, 'public', 'sourcepawn'))
   195 		return compiler
   196 
   197 	def AutoVersion(self, folder, binary):
   198 		if AMBuild.target['platform'] != 'windows':
   199 			return
   200 		env = {'RCDEFINES': ['BINARY_NAME="' + binary.binaryFile + '"', 'SM_GENERATED_BUILD']}
   201 		binary.AddResourceFile(os.path.join(folder, 'version.rc' ), env)
   202 
   203 	def PreSetupHL2Job(self, job, builder, sdk):
   204 		info = self.sdkInfo[sdk]
   205 		sdkPath = AMBuild.cache[info['sdk']]
   206 		if AMBuild.target['platform'] == 'linux':
   207 			if sdk == 'ep1':
   208 				staticLibs = os.path.join(sdkPath, 'linux_sdk')
   209 			else:
   210 				staticLibs = os.path.join(sdkPath, 'lib', 'linux')
   211 			workFolder = os.path.join(AMBuild.outputFolder, job.workFolder)
   212 			if sdk == 'ep2v' or sdk == 'l4d2':
   213 				for i in ['tier1_i486.a', 'mathlib_i486.a', 'libvstdlib.so', 'libtier0.so']:
   214 					link = os.path.join(workFolder, i)
   215 					target = os.path.join(staticLibs, i)
   216 					try:
   217 						os.lstat(link)
   218 					except:
   219 						job.AddCommand(SymlinkCommand(link, target))
   220 			else:
   221 				for i in ['tier1_i486.a', 'mathlib_i486.a', 'vstdlib_i486.so', 'tier0_i486.so']:
   222 					link = os.path.join(workFolder, i)
   223 					target = os.path.join(staticLibs, i)
   224 					try:
   225 						os.lstat(link)
   226 					except:
   227 						job.AddCommand(SymlinkCommand(link, target))
   228 		elif AMBuild.target['platform'] == 'darwin':
   229 			staticLibs = os.path.join(sdkPath, 'lib', 'mac')
   230 			workFolder = os.path.join(AMBuild.outputFolder, job.workFolder)
   231 			for i in ['tier1_i486.a', 'mathlib_i486.a', 'libvstdlib.dylib', 'libtier0.dylib']:
   232 				link = os.path.join(workFolder, i)
   233 				target = os.path.join(staticLibs, i)
   234 				try:
   235 					os.lstat(link)
   236 				except:
   237 					job.AddCommand(SymlinkCommand(link, target))
   238 		elif AMBuild.target['platform'] == 'windows':
   239 			for lib in ['tier0', 'tier1', 'vstdlib', 'mathlib']:
   240 				libPath = os.path.join(sdkPath, 'lib', 'public', lib) + '.lib'
   241 				builder.RebuildIfNewer(libPath)
   242 				builder['POSTLINKFLAGS'].append(libPath)
   243 
   244 	def PostSetupHL2Job(self, job, builder, sdk):
   245 		if AMBuild.target['platform'] in ['linux', 'darwin']:
   246 			builder.AddObjectFiles(['tier1_i486.a', 'mathlib_i486.a'])
   247 
   248 	def DefaultHL2Compiler(self, path, sdk, noLink = False, oldMms = '-legacy'):
   249 		compiler = self.DefaultExtCompiler(path)
   250 
   251 		mms = 'core'
   252 		if sdk == 'ep1':
   253 			mms += oldMms
   254 
   255 		compiler['CXXINCLUDES'].append(os.path.join(self.mmsPath, mms))
   256 		compiler['CXXINCLUDES'].append(os.path.join(self.mmsPath, mms, 'sourcehook'))
   257 
   258 		info = self.sdkInfo
   259 		compiler['CDEFINES'].extend(['SE_' + info[i]['name'] + '=' + info[i]['def'] for i in info])
   260 
   261 		paths = [['public'], ['public', 'engine'], ['public', 'mathlib'], ['public', 'vstdlib'],
   262 						 ['public', 'tier0'], ['public', 'tier1']]
   263 		if sdk == 'ep1' or sdk == 'darkm':
   264 			paths.append(['public', 'dlls'])
   265 			paths.append(['game_shared'])
   266 		else:
   267 			paths.append(['public', 'game', 'server'])
   268 			paths.append(['game', 'shared'])
   269 			paths.append(['common'])
   270 
   271 		info = self.sdkInfo[sdk]
   272 		sdkPath = AMBuild.cache[info['sdk']]
   273 
   274 		compiler['CDEFINES'].append('SOURCE_ENGINE=' + info['def'])
   275 
   276 		if sdk == 'ep1':
   277 			if AMBuild.target['platform'] == 'linux':
   278 				staticLibs = os.path.join(sdkPath, 'linux_sdk')
   279 		else:
   280 			if AMBuild.target['platform'] == 'linux':
   281 				staticLibs = os.path.join(sdkPath, 'lib', 'linux')
   282 			elif AMBuild.target['platform'] == 'darwin':
   283 				staticLibs = os.path.join(sdkPath, 'lib', 'mac')
   284 
   285 		for i in paths:
   286 			compiler['CXXINCLUDES'].append(os.path.join(sdkPath, *i))
   287 
   288 		if not noLink:
   289 			if AMBuild.target['platform'] == 'linux':
   290 				compiler['POSTLINKFLAGS'][0:0] = ['-lm']
   291 				if sdk == 'ep2v' or sdk == 'l4d2':
   292 					compiler['POSTLINKFLAGS'][0:0] = ['libtier0.so']
   293 					compiler['POSTLINKFLAGS'][0:0] = ['libvstdlib.so']
   294 				else:
   295 					compiler['POSTLINKFLAGS'][0:0] = ['tier0_i486.so']
   296 					compiler['POSTLINKFLAGS'][0:0] = ['vstdlib_i486.so']
   297 			elif AMBuild.target['platform'] == 'darwin':
   298 				compiler['POSTLINKFLAGS'][0:0] = ['libtier0.dylib']
   299 				compiler['POSTLINKFLAGS'][0:0] = ['libvstdlib.dylib']
   300 
   301 		return compiler
   302 
   303 sm = SM()
   304 globals = {
   305 	'SM': sm
   306 }
   307 
   308 AMBuild.Include(os.path.join('tools', 'buildbot', 'Versioning'), globals)
   309 
   310 FileList = [
   311 		['loader', 'AMBuilder'],
   312 		['core', 'AMBuilder'],
   313 		['core', 'logic', 'AMBuilder'],
   314 		['extensions', 'bintools', 'AMBuilder'],
   315 		['extensions', 'clientprefs', 'AMBuilder'],
   316 		['extensions', 'cstrike', 'AMBuilder'],
   317 		['extensions', 'curl', 'AMBuilder'],
   318 		['extensions', 'geoip', 'AMBuilder'],
   319 		['extensions', 'mysql', 'AMBuilder'],
   320 		['extensions', 'sdktools', 'AMBuilder'],
   321 		['extensions', 'topmenus', 'AMBuilder'],
   322 		['extensions', 'updater', 'AMBuilder'],
   323 		['extensions', 'sqlite', 'AMBuilder'],
   324 		['extensions', 'regex', 'AMBuilder'],
   325 		['extensions', 'tf2', 'AMBuilder'],
   326 		['sourcepawn', 'jit', 'AMBuilder'],
   327 		['sourcepawn', 'compiler', 'AMBuilder'],
   328 		['plugins', 'AMBuilder'],
   329 		['tools', 'buildbot', 'PackageScript']
   330 	]
   331 
   332 for parts in FileList:
   333 	AMBuild.Include(os.path.join(*parts), globals)
   334