AMBuildScript
author Scott Ehlert <ds@alliedmods.net>
Thu May 13 04:19:39 2010 -0500 (2010-05-13)
changeset 2991 4663c6df82ab
parent 2990 580796050687
parent 2989 e8b0605226ce
child 2993 76da4d93e0d6
permissions -rw-r--r--
Merge.
     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', '/Ot')
   130 					self.compiler.AddToListVar('POSTLINKFLAGS', '/OPT:ICF')
   131 
   132 			#Debugging
   133 			if AMBuild.options.debug == '1':
   134 				self.compiler.AddToListVar('CDEFINES', 'DEBUG')
   135 				self.compiler.AddToListVar('CDEFINES', '_DEBUG')
   136 				if self.vendor == 'gcc':
   137 					self.compiler.AddToListVar('CFLAGS', '-g3')
   138 				elif self.vendor == 'msvc':
   139 					self.compiler.AddToListVar('CFLAGS', '/Od')
   140 					self.compiler.AddToListVar('CFLAGS', '/RTC1')
   141 
   142 			#Platform-specifics
   143 			if AMBuild.target['platform'] == 'linux':
   144 				self.compiler.AddToListVar('CDEFINES', '_LINUX')
   145 			elif AMBuild.target['platform'] == 'darwin':
   146 				self.compiler.AddToListVar('CFLAGS', ['-isysroot',
   147 				                                      '/Developer/SDKs/MacOSX10.5.sdk'])
   148 				self.compiler.AddToListVar('POSTLINKFLAGS', '-mmacosx-version-min=10.5')
   149 				self.compiler.AddToListVar('POSTLINKFLAGS', ['-arch', 'i386'])
   150 			elif AMBuild.target['platform'] == 'windows':
   151 				self.compiler.AddToListVar('CDEFINES', 'WIN32')
   152 				self.compiler.AddToListVar('CDEFINES', '_WINDOWS')
   153 
   154 			#Finish up
   155 			self.compiler.AddToListVar('CDEFINES', 'SOURCEMOD_BUILD')
   156 			self.compiler.AddToListVar('CDEFINES', 'SM_GENERATED_BUILD')
   157 			self.compiler.AddToListVar('CINCLUDES',
   158 			                           os.path.join(AMBuild.outputFolder, 'includes'))
   159 			self.compiler.ToConfig(AMBuild, 'compiler')
   160 			AMBuild.cache.CacheVariable('vendor', self.vendor)
   161 			self.targetMap = { }
   162 			AMBuild.cache.CacheVariable('targetMap', self.targetMap)
   163 		else:
   164 			self.compiler.FromConfig(AMBuild, 'compiler')
   165 			self.targetMap = AMBuild.cache['targetMap']
   166 
   167 		if AMBuild.target['platform'] == 'windows':
   168 			self.compiler.AddToListVar('RCINCLUDES', os.path.join(AMBuild.sourceFolder, 'public'))
   169 			self.compiler.AddToListVar('RCINCLUDES',
   170 			                           os.path.join(AMBuild.outputFolder, 'includes'))
   171 		self.mmsPath = AMBuild.cache['MMSOURCE18']
   172 
   173 	def DefaultCompiler(self):
   174 		return self.compiler.Clone()
   175 
   176 	def JobMatters(self, jobname):
   177 		file = sys._getframe().f_code.co_filename
   178 		if AMBuild.mode == 'config':
   179 			self.targetMap[jobname] = file
   180 			return True
   181 		if len(AMBuild.args) == 0:
   182 			return True
   183 		if not jobname in AMBuild.args:
   184 			return False
   185 
   186 	def DefaultExtCompiler(self, path):
   187 		compiler = self.DefaultCompiler()
   188 		compiler['CXXINCLUDES'].append(os.path.join(AMBuild.sourceFolder, path))
   189 		compiler['CXXINCLUDES'].append(os.path.join(AMBuild.sourceFolder, path, 'sdk'))
   190 		compiler['CXXINCLUDES'].append(os.path.join(AMBuild.sourceFolder, 'public'))
   191 		compiler['CXXINCLUDES'].append(os.path.join(AMBuild.sourceFolder, 'public', 'extensions'))
   192 		compiler['CXXINCLUDES'].append(os.path.join(AMBuild.sourceFolder, 'public', 'sourcepawn'))
   193 		return compiler
   194 
   195 	def AutoVersion(self, folder, binary):
   196 		if AMBuild.target['platform'] != 'windows':
   197 			return
   198 		env = {'RCDEFINES': ['BINARY_NAME="' + binary.binaryFile + '"', 'SM_GENERATED_BUILD']}
   199 		binary.AddResourceFile(os.path.join(folder, 'version.rc' ), env)
   200 
   201 	def PreSetupHL2Job(self, job, builder, sdk):
   202 		info = self.sdkInfo[sdk]
   203 		sdkPath = AMBuild.cache[info['sdk']]
   204 		if AMBuild.target['platform'] == 'linux':
   205 			if sdk == 'ep1':
   206 				staticLibs = os.path.join(sdkPath, 'linux_sdk')
   207 			else:
   208 				staticLibs = os.path.join(sdkPath, 'lib', 'linux')
   209 			workFolder = os.path.join(AMBuild.outputFolder, job.workFolder)
   210 			if sdk == 'ep2v' or sdk == 'l4d2':
   211 				for i in ['tier1_i486.a', 'mathlib_i486.a', 'libvstdlib.so', 'libtier0.so']:
   212 					link = os.path.join(workFolder, i)
   213 					target = os.path.join(staticLibs, i)
   214 					try:
   215 						os.lstat(link)
   216 					except:
   217 						job.AddCommand(SymlinkCommand(link, target))
   218 			else:
   219 				for i in ['tier1_i486.a', 'mathlib_i486.a', 'vstdlib_i486.so', 'tier0_i486.so']:
   220 					link = os.path.join(workFolder, i)
   221 					target = os.path.join(staticLibs, i)
   222 					try:
   223 						os.lstat(link)
   224 					except:
   225 						job.AddCommand(SymlinkCommand(link, target))
   226 		elif AMBuild.target['platform'] == 'windows':
   227 			for lib in ['tier0', 'tier1', 'vstdlib', 'mathlib']:
   228 				libPath = os.path.join(sdkPath, 'lib', 'public', lib) + '.lib'
   229 				builder.RebuildIfNewer(libPath)
   230 				builder['POSTLINKFLAGS'].append(libPath)
   231 
   232 	def PostSetupHL2Job(self, job, builder, sdk):
   233 		if AMBuild.target['platform'] == 'linux':
   234 			builder.AddObjectFiles(['tier1_i486.a', 'mathlib_i486.a'])
   235 
   236 	def DefaultHL2Compiler(self, path, sdk, noLink = False, oldMms = '-legacy'):
   237 		compiler = self.DefaultExtCompiler(path)
   238 
   239 		mms = 'core'
   240 		if sdk == 'ep1':
   241 			mms += oldMms
   242 
   243 		compiler['CXXINCLUDES'].append(os.path.join(self.mmsPath, mms))
   244 		compiler['CXXINCLUDES'].append(os.path.join(self.mmsPath, mms, 'sourcehook'))
   245 
   246 		info = self.sdkInfo
   247 		compiler['CDEFINES'].extend(['SE_' + info[i]['name'] + '=' + info[i]['def'] for i in info])
   248 
   249 		paths = [['public'], ['public', 'engine'], ['public', 'mathlib'], ['public', 'vstdlib'],
   250 						 ['public', 'tier0'], ['public', 'tier1']]
   251 		if sdk == 'ep1' or sdk == 'darkm':
   252 			paths.append(['public', 'dlls'])
   253 			paths.append(['game_shared'])
   254 		else:
   255 			paths.append(['public', 'game', 'server'])
   256 			paths.append(['game', 'shared'])
   257 			paths.append(['common'])
   258 
   259 		info = self.sdkInfo[sdk]
   260 		sdkPath = AMBuild.cache[info['sdk']]
   261 
   262 		compiler['CDEFINES'].append('SOURCE_ENGINE=' + info['def'])
   263 
   264 		if sdk == 'ep1':
   265 			if AMBuild.target['platform'] == 'linux':
   266 				staticLibs = os.path.join(sdkPath, 'linux_sdk')
   267 		else:
   268 			if AMBuild.target['platform'] == 'linux':
   269 				staticLibs = os.path.join(sdkPath, 'lib', 'linux')
   270 
   271 		for i in paths:
   272 			compiler['CXXINCLUDES'].append(os.path.join(sdkPath, *i))
   273 
   274 		if not noLink:
   275 			if AMBuild.target['platform'] == 'linux':
   276 				compiler['POSTLINKFLAGS'][0:0] = ['-lm']
   277 				if sdk == 'ep2v' or sdk == 'l4d2':
   278 					compiler['POSTLINKFLAGS'][0:0] = ['libtier0.so']
   279 					compiler['POSTLINKFLAGS'][0:0] = ['libvstdlib.so']
   280 				else:
   281 					compiler['POSTLINKFLAGS'][0:0] = ['tier0_i486.so']
   282 					compiler['POSTLINKFLAGS'][0:0] = ['vstdlib_i486.so']				
   283 
   284 		return compiler
   285 
   286 sm = SM()
   287 globals = {
   288 	'SM': sm
   289 }
   290 
   291 AMBuild.Include(os.path.join('tools', 'buildbot', 'Versioning'), globals)
   292 
   293 FileList = [
   294 		['loader', 'AMBuilder'],
   295 		['core', 'AMBuilder'],
   296 		['core', 'logic', 'AMBuilder'],
   297 		['extensions', 'bintools', 'AMBuilder'],
   298 		['extensions', 'clientprefs', 'AMBuilder'],
   299 		['extensions', 'cstrike', 'AMBuilder'],
   300 		['extensions', 'curl', 'AMBuilder'],
   301 		['extensions', 'geoip', 'AMBuilder'],
   302 		['extensions', 'mysql', 'AMBuilder'],
   303 		['extensions', 'sdktools', 'AMBuilder'],
   304 		['extensions', 'topmenus', 'AMBuilder'],
   305 		['extensions', 'updater', 'AMBuilder'],
   306 		['extensions', 'sqlite', 'AMBuilder'],
   307 		['extensions', 'regex', 'AMBuilder'],
   308 		['extensions', 'tf2', 'AMBuilder'],
   309 		['sourcepawn', 'jit', 'AMBuilder'],
   310 		['sourcepawn', 'compiler', 'AMBuilder'],
   311 		['plugins', 'AMBuilder'],
   312 		['tools', 'buildbot', 'PackageScript']
   313 	]
   314 
   315 for parts in FileList:
   316 	AMBuild.Include(os.path.join(*parts), globals)
   317