1 # vim: set ts=2 sw=2 tw=99 noet ft=python:
4 from ambuild.command import SymlinkCommand
8 self.compiler = Cpp.Compiler()
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': '5',
17 'name': 'ORANGEBOXVALVE', 'platform': ['windows', 'linux', 'darwin']}
18 self.sdkInfo['l4d'] = {'sdk': 'HL2SDKL4D', 'ext': '2.l4d', 'def': '6',
19 'name': 'LEFT4DEAD', 'platform': ['windows', 'linux', 'darwin']}
20 self.sdkInfo['l4d2'] = {'sdk': 'HL2SDKL4D2', 'ext': '2.l4d2', 'def': '7',
21 'name': 'LEFT4DEAD2', 'platform': ['windows', 'linux', 'darwin']}
22 self.sdkInfo['darkm'] = {'sdk': 'HL2SDK-DARKM', 'ext': '2.darkm', 'def': '2',
23 'name': 'DARKMESSIAH', 'platform': ['windows']}
24 self.sdkInfo['swarm'] = {'sdk': 'HL2SDK-SWARM', 'ext': '2.swarm', 'def': '8',
25 'name': 'ALIENSWARM', 'platform': ['windows']}
26 self.sdkInfo['bgt'] = {'sdk': 'HL2SDK-BGT', 'ext': '2.bgt', 'def': '4',
27 'name': 'BLOODYGOODTIME', 'platform': ['windows']}
29 if AMBuild.mode == 'config':
31 self.compiler.DetectAll(AMBuild)
34 envvars = { 'MMSOURCE18': 'mmsource-1.8',
35 'HL2SDKOBVALVE': 'hl2sdk-ob-valve',
36 'HL2SDKL4D': 'hl2sdk-l4d',
37 'HL2SDKL4D2': 'hl2sdk-l4d2',
41 if AMBuild.target['platform'] != 'darwin':
42 envvars['HL2SDK'] = 'hl2sdk'
43 envvars['HL2SDKOB'] = 'hl2sdk-ob'
45 #Dark Messiah is Windows-only
46 if AMBuild.target['platform'] == 'windows':
47 envvars['HL2SDK-DARKM'] = 'hl2sdk-darkm'
48 envvars['HL2SDK-SWARM'] = 'hl2sdk-swarm'
49 envvars['HL2SDK-BGT'] = 'hl2sdk-bgt'
51 #Must have a path for each envvar (file a bug if you don't like this)
55 if not os.path.isdir(path):
56 raise Exception('Path for {0} was not found: {1}'.format(i, path))
60 while head != None and head != oldhead:
61 path = os.path.join(head, envvars[i])
62 if os.path.isdir(path):
65 head, tail = os.path.split(head)
66 if head == None or head == oldhead:
67 raise Exception('Could not find a valid path for {0}'.format(i))
68 AMBuild.cache.CacheVariable(i, path)
71 cxx = self.compiler.cxx
72 if isinstance(cxx, Cpp.CompatGCC):
73 if isinstance(cxx, Cpp.GCC):
75 elif isinstance(cxx, Cpp.Clang):
77 self.compiler.AddToListVar('CDEFINES', 'stricmp=strcasecmp')
78 self.compiler.AddToListVar('CDEFINES', '_stricmp=strcasecmp')
79 self.compiler.AddToListVar('CDEFINES', '_snprintf=snprintf')
80 self.compiler.AddToListVar('CDEFINES', '_vsnprintf=vsnprintf')
81 self.compiler.AddToListVar('CFLAGS', '-pipe')
82 self.compiler.AddToListVar('CFLAGS', '-fno-strict-aliasing')
83 if (self.vendor == 'gcc' and cxx.majorVersion >= 4) or self.vendor == 'clang':
84 self.compiler.AddToListVar('CFLAGS', '-fvisibility=hidden')
85 self.compiler.AddToListVar('CXXFLAGS', '-fvisibility-inlines-hidden')
86 self.compiler.AddToListVar('CFLAGS', '-Wall')
87 self.compiler.AddToListVar('CFLAGS', '-Werror')
88 self.compiler.AddToListVar('CFLAGS', '-Wno-uninitialized')
89 self.compiler.AddToListVar('CFLAGS', '-Wno-unused')
90 self.compiler.AddToListVar('CFLAGS', '-Wno-switch')
91 self.compiler.AddToListVar('CFLAGS', '-msse')
92 self.compiler.AddToListVar('CFLAGS', '-m32')
93 self.compiler.AddToListVar('POSTLINKFLAGS', '-m32')
94 self.compiler.AddToListVar('CXXFLAGS', '-fno-exceptions')
95 self.compiler.AddToListVar('CXXFLAGS', '-fno-rtti')
96 self.compiler.AddToListVar('CXXFLAGS', '-fno-threadsafe-statics')
97 self.compiler.AddToListVar('CXXFLAGS', '-Wno-non-virtual-dtor')
98 self.compiler.AddToListVar('CXXFLAGS', '-Wno-overloaded-virtual')
99 self.compiler.AddToListVar('CDEFINES', 'HAVE_STDINT_H')
100 self.compiler.AddToListVar('CDEFINES', 'GNUC')
101 if self.vendor == 'gcc':
102 self.compiler.AddToListVar('CFLAGS', '-mfpmath=sse')
103 elif isinstance(cxx, Cpp.MSVC):
105 if AMBuild.options.debug == '1':
106 self.compiler.AddToListVar('CFLAGS', '/MTd')
107 self.compiler.AddToListVar('POSTLINKFLAGS', '/NODEFAULTLIB:libcmt')
109 self.compiler.AddToListVar('CFLAGS', '/MT')
110 self.compiler.AddToListVar('CDEFINES', '_CRT_SECURE_NO_DEPRECATE')
111 self.compiler.AddToListVar('CDEFINES', '_CRT_SECURE_NO_WARNINGS')
112 self.compiler.AddToListVar('CDEFINES', '_CRT_NONSTDC_NO_DEPRECATE')
113 self.compiler.AddToListVar('CXXFLAGS', '/EHsc')
114 self.compiler.AddToListVar('CXXFLAGS', '/GR-')
115 self.compiler.AddToListVar('CFLAGS', '/W3')
116 self.compiler.AddToListVar('CFLAGS', '/nologo')
117 self.compiler.AddToListVar('CFLAGS', '/Zi')
118 self.compiler.AddToListVar('CXXFLAGS', '/TP')
119 self.compiler.AddToListVar('POSTLINKFLAGS', '/DEBUG')
120 self.compiler.AddToListVar('POSTLINKFLAGS', '/MACHINE:X86')
121 self.compiler.AddToListVar('POSTLINKFLAGS', '/SUBSYSTEM:WINDOWS')
122 self.compiler.AddToListVar('POSTLINKFLAGS', 'kernel32.lib')
123 self.compiler.AddToListVar('POSTLINKFLAGS', 'user32.lib')
124 self.compiler.AddToListVar('POSTLINKFLAGS', 'gdi32.lib')
125 self.compiler.AddToListVar('POSTLINKFLAGS', 'winspool.lib')
126 self.compiler.AddToListVar('POSTLINKFLAGS', 'comdlg32.lib')
127 self.compiler.AddToListVar('POSTLINKFLAGS', 'advapi32.lib')
128 self.compiler.AddToListVar('POSTLINKFLAGS', 'shell32.lib')
129 self.compiler.AddToListVar('POSTLINKFLAGS', 'ole32.lib')
130 self.compiler.AddToListVar('POSTLINKFLAGS', 'oleaut32.lib')
131 self.compiler.AddToListVar('POSTLINKFLAGS', 'uuid.lib')
132 self.compiler.AddToListVar('POSTLINKFLAGS', 'odbc32.lib')
133 self.compiler.AddToListVar('POSTLINKFLAGS', 'odbccp32.lib')
136 if AMBuild.options.opt == '1':
137 self.compiler.AddToListVar('CDEFINES', 'NDEBUG')
138 if self.vendor == 'gcc' or self.vendor == 'clang':
139 self.compiler.AddToListVar('CFLAGS', '-O3')
140 elif self.vendor == 'msvc':
141 self.compiler.AddToListVar('CFLAGS', '/Ox')
142 self.compiler.AddToListVar('POSTLINKFLAGS', '/OPT:ICF')
143 self.compiler.AddToListVar('POSTLINKFLAGS', '/OPT:REF')
146 if AMBuild.options.debug == '1':
147 self.compiler.AddToListVar('CDEFINES', 'DEBUG')
148 self.compiler.AddToListVar('CDEFINES', '_DEBUG')
149 if self.vendor == 'gcc' or self.vendor == 'clang':
150 self.compiler.AddToListVar('CFLAGS', '-g3')
151 elif self.vendor == 'msvc':
152 self.compiler.AddToListVar('CFLAGS', '/Od')
153 self.compiler.AddToListVar('CFLAGS', '/RTC1')
156 if AMBuild.target['platform'] == 'linux':
157 self.compiler.AddToListVar('CDEFINES', '_LINUX')
158 if self.vendor == 'gcc':
159 self.compiler.AddToListVar('POSTLINKFLAGS', '-static-libgcc')
160 if self.vendor == 'clang':
161 self.compiler.AddToListVar('POSTLINKFLAGS', '-lgcc_eh')
162 elif AMBuild.target['platform'] == 'darwin':
163 self.compiler.AddToListVar('CFLAGS', ['-isysroot',
164 '/Developer/SDKs/MacOSX10.5.sdk'])
165 self.compiler.AddToListVar('POSTLINKFLAGS', '-mmacosx-version-min=10.5')
166 self.compiler.AddToListVar('POSTLINKFLAGS', ['-arch', 'i386'])
167 self.compiler.AddToListVar('POSTLINKFLAGS', '-lstdc++')
169 # For OS X dylib versioning
171 productFile = open(os.path.join(AMBuild.sourceFolder, 'product.version'), 'r')
172 productContents = productFile.read()
174 m = re.match('(\d+)\.(\d+)\.(\d+).*', productContents)
176 self.version = '1.0.0'
178 major, minor, release = m.groups()
179 self.version = '{0}.{1}.{2}'.format(major, minor, release)
180 AMBuild.cache.CacheVariable('version', self.version)
181 elif AMBuild.target['platform'] == 'windows':
182 self.compiler.AddToListVar('CDEFINES', 'WIN32')
183 self.compiler.AddToListVar('CDEFINES', '_WINDOWS')
186 self.compiler.AddToListVar('CDEFINES', 'SOURCEMOD_BUILD')
187 self.compiler.AddToListVar('CDEFINES', 'SM_GENERATED_BUILD')
188 self.compiler.AddToListVar('CINCLUDES',
189 os.path.join(AMBuild.outputFolder, 'includes'))
190 self.compiler.ToConfig(AMBuild, 'compiler')
191 AMBuild.cache.CacheVariable('vendor', self.vendor)
193 AMBuild.cache.CacheVariable('targetMap', self.targetMap)
195 self.compiler.FromConfig(AMBuild, 'compiler')
196 self.targetMap = AMBuild.cache['targetMap']
198 if AMBuild.target['platform'] == 'windows':
199 self.compiler.AddToListVar('RCINCLUDES', os.path.join(AMBuild.sourceFolder, 'public'))
200 self.compiler.AddToListVar('RCINCLUDES',
201 os.path.join(AMBuild.outputFolder, 'includes'))
202 self.mmsPath = AMBuild.cache['MMSOURCE18']
204 def DefaultCompiler(self):
205 return self.compiler.Clone()
207 def JobMatters(self, jobname):
208 file = sys._getframe().f_code.co_filename
209 if AMBuild.mode == 'config':
210 self.targetMap[jobname] = file
212 if len(AMBuild.args) == 0:
214 if not jobname in AMBuild.args:
217 def DefaultExtCompiler(self, path):
218 compiler = self.DefaultCompiler()
219 compiler['CXXINCLUDES'].append(os.path.join(AMBuild.sourceFolder, path))
220 compiler['CXXINCLUDES'].append(os.path.join(AMBuild.sourceFolder, path, 'sdk'))
221 compiler['CXXINCLUDES'].append(os.path.join(AMBuild.sourceFolder, 'public'))
222 compiler['CXXINCLUDES'].append(os.path.join(AMBuild.sourceFolder, 'public', 'extensions'))
223 compiler['CXXINCLUDES'].append(os.path.join(AMBuild.sourceFolder, 'public', 'sourcepawn'))
226 def AutoVersion(self, folder, binary):
227 if AMBuild.target['platform'] == 'windows':
228 env = {'RCDEFINES': ['BINARY_NAME="' + binary.binaryFile + '"', 'SM_GENERATED_BUILD']}
229 binary.AddResourceFile(os.path.join(folder, 'version.rc' ), env)
230 elif AMBuild.target['platform'] == 'darwin' and isinstance(binary, Cpp.LibraryBuilder):
231 binary.compiler['POSTLINKFLAGS'].extend(['-compatibility_version', '1.0.0'])
232 binary.compiler['POSTLINKFLAGS'].extend(['-current_version', AMBuild.cache['version']])
236 def PreSetupHL2Job(self, job, builder, sdk):
237 info = self.sdkInfo[sdk]
238 sdkPath = AMBuild.cache[info['sdk']]
239 if AMBuild.target['platform'] == 'linux':
241 staticLibs = os.path.join(sdkPath, 'linux_sdk')
243 staticLibs = os.path.join(sdkPath, 'lib', 'linux')
244 workFolder = os.path.join(AMBuild.outputFolder, job.workFolder)
245 if sdk in ['ep2v', 'l4d', 'l4d2']:
246 for i in ['tier1_i486.a', 'mathlib_i486.a', 'libvstdlib.so', 'libtier0.so']:
247 link = os.path.join(workFolder, i)
248 target = os.path.join(staticLibs, i)
252 job.AddCommand(SymlinkCommand(link, target))
254 for i in ['tier1_i486.a', 'mathlib_i486.a', 'vstdlib_i486.so', 'tier0_i486.so']:
255 link = os.path.join(workFolder, i)
256 target = os.path.join(staticLibs, i)
260 job.AddCommand(SymlinkCommand(link, target))
261 elif AMBuild.target['platform'] == 'darwin':
262 staticLibs = os.path.join(sdkPath, 'lib', 'mac')
263 workFolder = os.path.join(AMBuild.outputFolder, job.workFolder)
264 for i in ['tier1_i486.a', 'mathlib_i486.a', 'libvstdlib.dylib', 'libtier0.dylib']:
265 link = os.path.join(workFolder, i)
266 target = os.path.join(staticLibs, i)
270 job.AddCommand(SymlinkCommand(link, target))
271 elif AMBuild.target['platform'] == 'windows':
272 libs = ['tier0', 'tier1', 'vstdlib', 'mathlib']
274 libs.append('interfaces')
276 libPath = os.path.join(sdkPath, 'lib', 'public', lib) + '.lib'
277 builder.RebuildIfNewer(libPath)
278 builder['POSTLINKFLAGS'].append(libPath)
280 def PostSetupHL2Job(self, job, builder, sdk):
281 if AMBuild.target['platform'] in ['linux', 'darwin']:
282 builder.AddObjectFiles(['tier1_i486.a', 'mathlib_i486.a'])
284 def DefaultHL2Compiler(self, path, sdk, noLink = False, oldMms = '-legacy'):
285 compiler = self.DefaultExtCompiler(path)
291 compiler['CXXINCLUDES'].append(os.path.join(self.mmsPath, mms))
292 compiler['CXXINCLUDES'].append(os.path.join(self.mmsPath, mms, 'sourcehook'))
295 compiler['CDEFINES'].extend(['SE_' + info[i]['name'] + '=' + info[i]['def'] for i in info])
297 paths = [['public'], ['public', 'engine'], ['public', 'mathlib'], ['public', 'vstdlib'],
298 ['public', 'tier0'], ['public', 'tier1']]
299 if sdk == 'ep1' or sdk == 'darkm':
300 paths.append(['public', 'dlls'])
301 paths.append(['game_shared'])
303 paths.append(['public', 'game', 'server'])
304 paths.append(['public', 'toolframework'])
305 paths.append(['game', 'shared'])
306 paths.append(['common'])
308 info = self.sdkInfo[sdk]
309 sdkPath = AMBuild.cache[info['sdk']]
311 compiler['CDEFINES'].append('SOURCE_ENGINE=' + info['def'])
313 if sdk == 'swarm' and AMBuild.target['platform'] == 'windows':
314 compiler['CDEFINES'].extend(['COMPILER_MSVC', 'COMPILER_MSVC32'])
317 if AMBuild.target['platform'] == 'linux':
318 staticLibs = os.path.join(sdkPath, 'linux_sdk')
320 if AMBuild.target['platform'] == 'linux':
321 staticLibs = os.path.join(sdkPath, 'lib', 'linux')
322 elif AMBuild.target['platform'] == 'darwin':
323 staticLibs = os.path.join(sdkPath, 'lib', 'mac')
326 compiler['CXXINCLUDES'].append(os.path.join(sdkPath, *i))
329 if AMBuild.target['platform'] == 'linux':
330 compiler['POSTLINKFLAGS'][0:0] = ['-lm']
331 if sdk in ['ep2v', 'l4d', 'l4d2']:
332 compiler['POSTLINKFLAGS'][0:0] = ['libtier0.so']
333 compiler['POSTLINKFLAGS'][0:0] = ['libvstdlib.so']
335 compiler['POSTLINKFLAGS'][0:0] = ['tier0_i486.so']
336 compiler['POSTLINKFLAGS'][0:0] = ['vstdlib_i486.so']
337 elif AMBuild.target['platform'] == 'darwin':
338 compiler['POSTLINKFLAGS'][0:0] = ['libtier0.dylib']
339 compiler['POSTLINKFLAGS'][0:0] = ['libvstdlib.dylib']
348 AMBuild.Include(os.path.join('tools', 'buildbot', 'Versioning'), globals)
351 ['loader', 'AMBuilder'],
352 ['core', 'AMBuilder'],
353 ['core', 'logic', 'AMBuilder'],
354 ['extensions', 'bintools', 'AMBuilder'],
355 ['extensions', 'clientprefs', 'AMBuilder'],
356 ['extensions', 'cstrike', 'AMBuilder'],
357 ['extensions', 'curl', 'AMBuilder'],
358 ['extensions', 'geoip', 'AMBuilder'],
359 ['extensions', 'mysql', 'AMBuilder'],
360 ['extensions', 'sdktools', 'AMBuilder'],
361 ['extensions', 'topmenus', 'AMBuilder'],
362 ['extensions', 'updater', 'AMBuilder'],
363 ['extensions', 'sqlite', 'AMBuilder'],
364 ['extensions', 'regex', 'AMBuilder'],
365 ['extensions', 'tf2', 'AMBuilder'],
366 ['sourcepawn', 'jit', 'AMBuilder'],
367 ['sourcepawn', 'compiler', 'AMBuilder'],
368 ['plugins', 'AMBuilder'],
369 ['tools', 'buildbot', 'PackageScript']
372 for parts in FileList:
373 AMBuild.Include(os.path.join(*parts), globals)