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