AMBuildScript
author David Anderson <dvander@alliedmods.net>
Fri Oct 02 03:47:42 2009 -0700 (2009-10-02)
changeset 2815 2c7137f077fe
parent 2785 9e3d5ec34f33
child 2819 e392dfaf2c41
permissions -rw-r--r--
Re-enabled PDB files.
     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.mmsPath = AMBuild.cache['MMSOURCE17']
   158 
   159 	def DefaultCompiler(self):
   160 		return self.compiler.Clone()
   161 
   162 	def JobMatters(self, jobname):
   163 		file = sys._getframe().f_code.co_filename
   164 		if AMBuild.mode == 'config':
   165 			self.targetMap[jobname] = file
   166 			return True
   167 		if len(AMBuild.args) == 0:
   168 			return True
   169 		if not jobname in AMBuild.args:
   170 			return False
   171 
   172 	def DefaultExtCompiler(self, path):
   173 		compiler = self.DefaultCompiler()
   174 		compiler['CXXINCLUDES'].append(os.path.join(AMBuild.sourceFolder, path))
   175 		compiler['CXXINCLUDES'].append(os.path.join(AMBuild.sourceFolder, path, 'sdk'))
   176 		compiler['CXXINCLUDES'].append(os.path.join(AMBuild.sourceFolder, 'public'))
   177 		compiler['CXXINCLUDES'].append(os.path.join(AMBuild.sourceFolder, 'public', 'extensions'))
   178 		compiler['CXXINCLUDES'].append(os.path.join(AMBuild.sourceFolder, 'public', 'sourcepawn'))
   179 		return compiler
   180 
   181 	def AutoVersion(self, folder, binary):
   182 		if AMBuild.target['platform'] != 'windows':
   183 			return
   184 		env = {'RCDEFINES': ['BINARY_NAME="' + binary.binaryFile + '"']}
   185 		binary.AddResourceFile(os.path.join(folder, 'version.rc' ), env)
   186 
   187 	def PreSetupHL2Job(self, job, builder, sdk):
   188 		info = self.sdkInfo[sdk]
   189 		sdkPath = AMBuild.cache[info['sdk']]
   190 		if AMBuild.target['platform'] == 'linux':
   191 			if sdk == 'ep1':
   192 				staticLibs = os.path.join(sdkPath, 'linux_sdk')
   193 			else:
   194 				staticLibs = os.path.join(sdkPath, 'lib', 'linux')
   195 			workFolder = os.path.join(AMBuild.outputFolder, job.workFolder)
   196 			for i in ['tier1_i486.a', 'mathlib_i486.a', 'vstdlib_i486.so', 'tier0_i486.so']:
   197 				link = os.path.join(workFolder, i)
   198 				target = os.path.join(staticLibs, i)
   199 				try:
   200 					os.lstat(link)
   201 				except:
   202 					job.AddCommand(SymlinkCommand(link, target))
   203 		elif AMBuild.target['platform'] == 'windows':
   204 			for lib in ['tier0', 'tier1', 'vstdlib', 'mathlib']:
   205 				libPath = os.path.join(sdkPath, 'lib', 'public', lib) + '.lib'
   206 				builder.RebuildIfNewer(libPath)
   207 				builder['POSTLINKFLAGS'].append(libPath)
   208 
   209 	def PostSetupHL2Job(self, job, builder, sdk):
   210 		if AMBuild.target['platform'] == 'linux':
   211 			builder.AddObjectFiles(['tier1_i486.a', 'mathlib_i486.a'])
   212 
   213 	def DefaultHL2Compiler(self, path, sdk, noLink = False, oldMms = '-legacy'):
   214 		compiler = self.DefaultExtCompiler(path)
   215 
   216 		mms = 'core'
   217 		if sdk == 'ep1':
   218 			mms += oldMms
   219 
   220 		compiler['CXXINCLUDES'].append(os.path.join(self.mmsPath, mms))
   221 		compiler['CXXINCLUDES'].append(os.path.join(self.mmsPath, mms, 'sourcehook'))
   222 
   223 		info = self.sdkInfo
   224 		compiler['CDEFINES'].extend(['SE_' + info[i]['name'] + '=' + info[i]['def'] for i in info])
   225 		compiler['CDEFINES'].append('SE_DARKMESSIAH=2')
   226 
   227 		paths = [['public'], ['public', 'engine'], ['public', 'mathlib'], ['public', 'vstdlib'],
   228 						 ['public', 'tier0'], ['public', 'tier1']]
   229 		if sdk == 'ep1' or sdk == 'darkm':
   230 			paths.append(['public', 'dlls'])
   231 			paths.append(['game_shared'])
   232 		else:
   233 			paths.append(['public', 'game', 'server'])
   234 			paths.append(['game', 'shared'])
   235 			paths.append(['common'])
   236 
   237 		info = self.sdkInfo[sdk]
   238 		sdkPath = AMBuild.cache[info['sdk']]
   239 
   240 		compiler['CDEFINES'].append('SOURCE_ENGINE=' + info['def'])
   241 
   242 		if sdk == 'ep1':
   243 			if AMBuild.target['platform'] == 'linux':
   244 				staticLibs = os.path.join(sdkPath, 'linux_sdk')
   245 		else:
   246 			if AMBuild.target['platform'] == 'linux':
   247 				staticLibs = os.path.join(sdkPath, 'lib', 'linux')
   248 
   249 		for i in paths:
   250 			compiler['CXXINCLUDES'].append(os.path.join(sdkPath, *i))
   251 
   252 		if not noLink:
   253 			if AMBuild.target['platform'] == 'linux':
   254 				compiler['POSTLINKFLAGS'][0:0] = ['-lm']
   255 				compiler['POSTLINKFLAGS'][0:0] = ['tier0_i486.so']
   256 				compiler['POSTLINKFLAGS'][0:0] = ['vstdlib_i486.so']
   257 
   258 		return compiler
   259 
   260 sm = SM()
   261 globals = {
   262 	'SM': sm
   263 }
   264 
   265 AMBuild.Include(os.path.join('tools', 'buildbot', 'Versioning'), globals)
   266 
   267 FileList = [
   268 		['loader', 'AMBuilder'],
   269 		['core', 'AMBuilder'],
   270 		['core', 'logic', 'AMBuilder'],
   271 		['extensions', 'bintools', 'AMBuilder'],
   272 		['extensions', 'clientprefs', 'AMBuilder'],
   273 		['extensions', 'cstrike', 'AMBuilder'],
   274 		['extensions', 'curl', 'AMBuilder'],
   275 		['extensions', 'geoip', 'AMBuilder'],
   276 		['extensions', 'mysql', 'AMBuilder'],
   277 		['extensions', 'sdktools', 'AMBuilder'],
   278 		['extensions', 'topmenus', 'AMBuilder'],
   279 		['extensions', 'updater', 'AMBuilder'],
   280 		['extensions', 'sqlite', 'AMBuilder'],
   281 		['extensions', 'regex', 'AMBuilder'],
   282 		['extensions', 'tf2', 'AMBuilder'],
   283 		['sourcepawn', 'jit', 'AMBuilder'],
   284 		['sourcepawn', 'compiler', 'AMBuilder'],
   285 		['plugins', 'AMBuilder'],
   286 		['tools', 'buildbot', 'PackageScript']
   287 	]
   288 
   289 for parts in FileList:
   290 	AMBuild.Include(os.path.join(*parts), globals)
   291