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