AMBuildScript
author David Anderson <dvander@alliedmods.net>
Thu May 13 01:47:12 2010 -0700 (2010-05-13)
changeset 2989 e8b0605226ce
parent 2988 53b37c44548c
child 2991 4663c6df82ab
permissions -rw-r--r--
Move timer natives into logic binary (bug 4402, r=ds).
     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('POSTLINKFLAGS', '-m32')
    85 				self.compiler.AddToListVar('CFLAGS', '-static-libgcc')
    86 				self.compiler.AddToListVar('CXXFLAGS', '-fno-exceptions')
    87 				self.compiler.AddToListVar('CXXFLAGS', '-fno-rtti')
    88 				self.compiler.AddToListVar('CXXFLAGS', '-fno-threadsafe-statics')
    89 				self.compiler.AddToListVar('CXXFLAGS', '-Wno-non-virtual-dtor')
    90 				self.compiler.AddToListVar('CDEFINES', 'HAVE_STDINT_H')
    91 			elif isinstance(cxx, Cpp.MSVC):
    92 				self.vendor = 'msvc'
    93 				if AMBuild.options.debug == '1':
    94 					self.compiler.AddToListVar('CFLAGS', '/MTd')
    95 				else:
    96 					self.compiler.AddToListVar('CFLAGS', '/MT')
    97 				self.compiler.AddToListVar('CDEFINES', '_CRT_SECURE_NO_DEPRECATE')
    98 				self.compiler.AddToListVar('CDEFINES', '_CRT_SECURE_NO_WARNINGS')
    99 				self.compiler.AddToListVar('CDEFINES', '_CRT_NONSTDC_NO_DEPRECATE')
   100 				self.compiler.AddToListVar('CXXFLAGS', '/EHsc')
   101 				self.compiler.AddToListVar('CXXFLAGS', '/GR-')
   102 				self.compiler.AddToListVar('CFLAGS', '/W3')
   103 				self.compiler.AddToListVar('CFLAGS', '/nologo')
   104 				self.compiler.AddToListVar('CFLAGS', '/Zi')
   105 				self.compiler.AddToListVar('CXXFLAGS', '/TP')
   106 				self.compiler.AddToListVar('POSTLINKFLAGS', '/DEBUG')
   107 				self.compiler.AddToListVar('POSTLINKFLAGS', '/MACHINE:X86')
   108 				self.compiler.AddToListVar('POSTLINKFLAGS', '/SUBSYSTEM:WINDOWS')
   109 				self.compiler.AddToListVar('POSTLINKFLAGS', 'kernel32.lib')
   110 				self.compiler.AddToListVar('POSTLINKFLAGS', 'user32.lib')
   111 				self.compiler.AddToListVar('POSTLINKFLAGS', 'gdi32.lib')
   112 				self.compiler.AddToListVar('POSTLINKFLAGS', 'winspool.lib')
   113 				self.compiler.AddToListVar('POSTLINKFLAGS', 'comdlg32.lib')
   114 				self.compiler.AddToListVar('POSTLINKFLAGS', 'advapi32.lib')
   115 				self.compiler.AddToListVar('POSTLINKFLAGS', 'shell32.lib')
   116 				self.compiler.AddToListVar('POSTLINKFLAGS', 'ole32.lib')
   117 				self.compiler.AddToListVar('POSTLINKFLAGS', 'oleaut32.lib')
   118 				self.compiler.AddToListVar('POSTLINKFLAGS', 'uuid.lib')
   119 				self.compiler.AddToListVar('POSTLINKFLAGS', 'odbc32.lib')
   120 				self.compiler.AddToListVar('POSTLINKFLAGS', 'odbccp32.lib')
   121 
   122 			#Optimization
   123 			if AMBuild.options.opt == '1':
   124 				self.compiler.AddToListVar('CDEFINES', 'NDEBUG')
   125 				if self.vendor == 'gcc':
   126 					self.compiler.AddToListVar('CFLAGS', '-O3')
   127 				elif self.vendor == 'msvc':
   128 					self.compiler.AddToListVar('CFLAGS', '/Ot')
   129 					self.compiler.AddToListVar('POSTLINKFLAGS', '/OPT:ICF')
   130 
   131 			#Debugging
   132 			if AMBuild.options.debug == '1':
   133 				self.compiler.AddToListVar('CDEFINES', 'DEBUG')
   134 				self.compiler.AddToListVar('CDEFINES', '_DEBUG')
   135 				if self.vendor == 'gcc':
   136 					self.compiler.AddToListVar('CFLAGS', '-g3')
   137 				elif self.vendor == 'msvc':
   138 					self.compiler.AddToListVar('CFLAGS', '/Od')
   139 					self.compiler.AddToListVar('CFLAGS', '/RTC1')
   140 
   141 			#Platform-specifics
   142 			if AMBuild.target['platform'] == 'linux':
   143 				self.compiler.AddToListVar('CDEFINES', '_LINUX')
   144 			elif AMBuild.target['platform'] == 'darwin':
   145 				self.compiler.AddToListVar('CFLAGS', ['-isysroot',
   146 				                                      '/Developer/SDKs/MacOSX10.5.sdk'])
   147 				self.compiler.AddToListVar('POSTLINKFLAGS', '-mmacosx-version-min=10.5')
   148 				self.compiler.AddToListVar('POSTLINKFLAGS', ['-arch', 'i386'])
   149 			elif AMBuild.target['platform'] == 'windows':
   150 				self.compiler.AddToListVar('CDEFINES', 'WIN32')
   151 				self.compiler.AddToListVar('CDEFINES', '_WINDOWS')
   152 
   153 			#Finish up
   154 			self.compiler.AddToListVar('CDEFINES', 'SOURCEMOD_BUILD')
   155 			self.compiler.AddToListVar('CDEFINES', 'SM_GENERATED_BUILD')
   156 			self.compiler.AddToListVar('CINCLUDES',
   157 			                           os.path.join(AMBuild.outputFolder, 'includes'))
   158 			self.compiler.ToConfig(AMBuild, 'compiler')
   159 			AMBuild.cache.CacheVariable('vendor', self.vendor)
   160 			self.targetMap = { }
   161 			AMBuild.cache.CacheVariable('targetMap', self.targetMap)
   162 		else:
   163 			self.compiler.FromConfig(AMBuild, 'compiler')
   164 			self.targetMap = AMBuild.cache['targetMap']
   165 
   166 		if AMBuild.target['platform'] == 'windows':
   167 			self.compiler.AddToListVar('RCINCLUDES', os.path.join(AMBuild.sourceFolder, 'public'))
   168 			self.compiler.AddToListVar('RCINCLUDES',
   169 			                           os.path.join(AMBuild.outputFolder, 'includes'))
   170 		self.mmsPath = AMBuild.cache['MMSOURCE18']
   171 
   172 	def DefaultCompiler(self):
   173 		return self.compiler.Clone()
   174 
   175 	def JobMatters(self, jobname):
   176 		file = sys._getframe().f_code.co_filename
   177 		if AMBuild.mode == 'config':
   178 			self.targetMap[jobname] = file
   179 			return True
   180 		if len(AMBuild.args) == 0:
   181 			return True
   182 		if not jobname in AMBuild.args:
   183 			return False
   184 
   185 	def DefaultExtCompiler(self, path):
   186 		compiler = self.DefaultCompiler()
   187 		compiler['CXXINCLUDES'].append(os.path.join(AMBuild.sourceFolder, path))
   188 		compiler['CXXINCLUDES'].append(os.path.join(AMBuild.sourceFolder, path, 'sdk'))
   189 		compiler['CXXINCLUDES'].append(os.path.join(AMBuild.sourceFolder, 'public'))
   190 		compiler['CXXINCLUDES'].append(os.path.join(AMBuild.sourceFolder, 'public', 'extensions'))
   191 		compiler['CXXINCLUDES'].append(os.path.join(AMBuild.sourceFolder, 'public', 'sourcepawn'))
   192 		return compiler
   193 
   194 	def AutoVersion(self, folder, binary):
   195 		if AMBuild.target['platform'] != 'windows':
   196 			return
   197 		env = {'RCDEFINES': ['BINARY_NAME="' + binary.binaryFile + '"', 'SM_GENERATED_BUILD']}
   198 		binary.AddResourceFile(os.path.join(folder, 'version.rc' ), env)
   199 
   200 	def PreSetupHL2Job(self, job, builder, sdk):
   201 		info = self.sdkInfo[sdk]
   202 		sdkPath = AMBuild.cache[info['sdk']]
   203 		if AMBuild.target['platform'] == 'linux':
   204 			if sdk == 'ep1':
   205 				staticLibs = os.path.join(sdkPath, 'linux_sdk')
   206 			else:
   207 				staticLibs = os.path.join(sdkPath, 'lib', 'linux')
   208 			workFolder = os.path.join(AMBuild.outputFolder, job.workFolder)
   209 			if sdk == 'ep2v' or sdk == 'l4d2':
   210 				for i in ['tier1_i486.a', 'mathlib_i486.a', 'libvstdlib.so', 'libtier0.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 			else:
   218 				for i in ['tier1_i486.a', 'mathlib_i486.a', 'vstdlib_i486.so', 'tier0_i486.so']:
   219 					link = os.path.join(workFolder, i)
   220 					target = os.path.join(staticLibs, i)
   221 					try:
   222 						os.lstat(link)
   223 					except:
   224 						job.AddCommand(SymlinkCommand(link, target))
   225 		elif AMBuild.target['platform'] == 'windows':
   226 			for lib in ['tier0', 'tier1', 'vstdlib', 'mathlib']:
   227 				libPath = os.path.join(sdkPath, 'lib', 'public', lib) + '.lib'
   228 				builder.RebuildIfNewer(libPath)
   229 				builder['POSTLINKFLAGS'].append(libPath)
   230 
   231 	def PostSetupHL2Job(self, job, builder, sdk):
   232 		if AMBuild.target['platform'] == 'linux':
   233 			builder.AddObjectFiles(['tier1_i486.a', 'mathlib_i486.a'])
   234 
   235 	def DefaultHL2Compiler(self, path, sdk, noLink = False, oldMms = '-legacy'):
   236 		compiler = self.DefaultExtCompiler(path)
   237 
   238 		mms = 'core'
   239 		if sdk == 'ep1':
   240 			mms += oldMms
   241 
   242 		compiler['CXXINCLUDES'].append(os.path.join(self.mmsPath, mms))
   243 		compiler['CXXINCLUDES'].append(os.path.join(self.mmsPath, mms, 'sourcehook'))
   244 
   245 		info = self.sdkInfo
   246 		compiler['CDEFINES'].extend(['SE_' + info[i]['name'] + '=' + info[i]['def'] for i in info])
   247 		compiler['CDEFINES'].append('SE_DARKMESSIAH=2')
   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