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