AMBuildScript
author Scott Ehlert <ds@alliedmods.net>
Tue May 11 02:36:03 2010 -0500 (2010-05-11)
changeset 2981 392a0b46351f
parent 2978 537abe70c41c
child 2987 29e6cc6f2124
permissions -rw-r--r--
Fixed compiler and linker flags for darwin (r=dvander).

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