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': '6',
17 'name': 'ORANGEBOXVALVE', 'platform': ['windows', 'linux', 'darwin']}
18 self.sdkInfo['l4d'] = {'sdk': 'HL2SDKL4D', 'ext': '2.l4d', 'def': '7',
19 'name': 'LEFT4DEAD', 'platform': ['windows', 'linux', 'darwin']}
20 self.sdkInfo['l4d2'] = {'sdk': 'HL2SDKL4D2', 'ext': '2.l4d2', 'def': '8',
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': '9',
25 'name': 'ALIENSWARM', 'platform': ['windows']}
26 self.sdkInfo['bgt'] = {'sdk': 'HL2SDK-BGT', 'ext': '2.bgt', 'def': '4',
27 'name': 'BLOODYGOODTIME', 'platform': ['windows']}
28 self.sdkInfo['eye'] = {'sdk': 'HL2SDK-EYE', 'ext': '2.eye', 'def': '5',
29 'name': 'EYE', 'platform': ['windows']}
31 if AMBuild.mode == 'config':
33 self.compiler.DetectAll(AMBuild)
36 envvars = { 'MMSOURCE18': 'mmsource-1.8',
37 'HL2SDKOBVALVE': 'hl2sdk-ob-valve',
38 'HL2SDKL4D': 'hl2sdk-l4d',
39 'HL2SDKL4D2': 'hl2sdk-l4d2',
43 if AMBuild.target['platform'] != 'darwin':
44 envvars['HL2SDK'] = 'hl2sdk'
45 envvars['HL2SDKOB'] = 'hl2sdk-ob'
47 #Dark Messiah is Windows-only
48 if AMBuild.target['platform'] == 'windows':
49 envvars['HL2SDK-DARKM'] = 'hl2sdk-darkm'
50 envvars['HL2SDK-SWARM'] = 'hl2sdk-swarm'
51 envvars['HL2SDK-BGT'] = 'hl2sdk-bgt'
52 envvars['HL2SDK-BGT'] = 'hl2sdk-eye'
54 #Must have a path for each envvar (file a bug if you don't like this)
58 if not os.path.isdir(path):
59 raise Exception('Path for {0} was not found: {1}'.format(i, path))
63 while head != None and head != oldhead:
64 path = os.path.join(head, envvars[i])
65 if os.path.isdir(path):
68 head, tail = os.path.split(head)
69 if head == None or head == oldhead:
70 raise Exception('Could not find a valid path for {0}'.format(i))
71 AMBuild.cache.CacheVariable(i, path)
74 cxx = self.compiler.cxx
75 if isinstance(cxx, Cpp.CompatGCC):
76 if isinstance(cxx, Cpp.GCC):
78 elif isinstance(cxx, Cpp.Clang):
80 self.compiler.AddToListVar('CDEFINES', 'stricmp=strcasecmp')
81 self.compiler.AddToListVar('CDEFINES', '_stricmp=strcasecmp')
82 self.compiler.AddToListVar('CDEFINES', '_snprintf=snprintf')
83 self.compiler.AddToListVar('CDEFINES', '_vsnprintf=vsnprintf')
84 self.compiler.AddToListVar('CFLAGS', '-pipe')
85 self.compiler.AddToListVar('CFLAGS', '-fno-strict-aliasing')
86 if (self.vendor == 'gcc' and cxx.majorVersion >= 4) or self.vendor == 'clang':
87 self.compiler.AddToListVar('CFLAGS', '-fvisibility=hidden')
88 self.compiler.AddToListVar('CXXFLAGS', '-fvisibility-inlines-hidden')
89 self.compiler.AddToListVar('CFLAGS', '-Wall')
90 self.compiler.AddToListVar('CFLAGS', '-Werror')
91 self.compiler.AddToListVar('CFLAGS', '-Wno-uninitialized')
92 self.compiler.AddToListVar('CFLAGS', '-Wno-unused')
93 self.compiler.AddToListVar('CFLAGS', '-Wno-switch')
94 self.compiler.AddToListVar('CFLAGS', '-msse')
95 self.compiler.AddToListVar('CFLAGS', '-m32')
96 self.compiler.AddToListVar('POSTLINKFLAGS', '-m32')
97 self.compiler.AddToListVar('CXXFLAGS', '-fno-exceptions')
98 self.compiler.AddToListVar('CXXFLAGS', '-fno-rtti')
99 self.compiler.AddToListVar('CXXFLAGS', '-fno-threadsafe-statics')
100 self.compiler.AddToListVar('CXXFLAGS', '-Wno-non-virtual-dtor')
101 self.compiler.AddToListVar('CXXFLAGS', '-Wno-overloaded-virtual')
102 self.compiler.AddToListVar('CDEFINES', 'HAVE_STDINT_H')
103 self.compiler.AddToListVar('CDEFINES', 'GNUC')
104 if self.vendor == 'gcc':
105 self.compiler.AddToListVar('CFLAGS', '-mfpmath=sse')
106 elif isinstance(cxx, Cpp.MSVC):
108 if AMBuild.options.debug == '1':
109 self.compiler.AddToListVar('CFLAGS', '/MTd')
110 self.compiler.AddToListVar('POSTLINKFLAGS', '/NODEFAULTLIB:libcmt')
112 self.compiler.AddToListVar('CFLAGS', '/MT')
113 self.compiler.AddToListVar('CDEFINES', '_CRT_SECURE_NO_DEPRECATE')
114 self.compiler.AddToListVar('CDEFINES', '_CRT_SECURE_NO_WARNINGS')
115 self.compiler.AddToListVar('CDEFINES', '_CRT_NONSTDC_NO_DEPRECATE')
116 self.compiler.AddToListVar('CXXFLAGS', '/EHsc')
117 self.compiler.AddToListVar('CXXFLAGS', '/GR-')
118 self.compiler.AddToListVar('CFLAGS', '/W3')
119 self.compiler.AddToListVar('CFLAGS', '/nologo')
120 self.compiler.AddToListVar('CFLAGS', '/Zi')
121 self.compiler.AddToListVar('CXXFLAGS', '/TP')
122 self.compiler.AddToListVar('POSTLINKFLAGS', '/DEBUG')
123 self.compiler.AddToListVar('POSTLINKFLAGS', '/MACHINE:X86')
124 self.compiler.AddToListVar('POSTLINKFLAGS', '/SUBSYSTEM:WINDOWS')
125 self.compiler.AddToListVar('POSTLINKFLAGS', 'kernel32.lib')
126 self.compiler.AddToListVar('POSTLINKFLAGS', 'user32.lib')
127 self.compiler.AddToListVar('POSTLINKFLAGS', 'gdi32.lib')
128 self.compiler.AddToListVar('POSTLINKFLAGS', 'winspool.lib')
129 self.compiler.AddToListVar('POSTLINKFLAGS', 'comdlg32.lib')
130 self.compiler.AddToListVar('POSTLINKFLAGS', 'advapi32.lib')
131 self.compiler.AddToListVar('POSTLINKFLAGS', 'shell32.lib')
132 self.compiler.AddToListVar('POSTLINKFLAGS', 'ole32.lib')
133 self.compiler.AddToListVar('POSTLINKFLAGS', 'oleaut32.lib')
134 self.compiler.AddToListVar('POSTLINKFLAGS', 'uuid.lib')
135 self.compiler.AddToListVar('POSTLINKFLAGS', 'odbc32.lib')
136 self.compiler.AddToListVar('POSTLINKFLAGS', 'odbccp32.lib')
139 if AMBuild.options.opt == '1':
140 self.compiler.AddToListVar('CDEFINES', 'NDEBUG')
141 if self.vendor == 'gcc' or self.vendor == 'clang':
142 self.compiler.AddToListVar('CFLAGS', '-O3')
143 elif self.vendor == 'msvc':
144 self.compiler.AddToListVar('CFLAGS', '/Ox')
145 self.compiler.AddToListVar('POSTLINKFLAGS', '/OPT:ICF')
146 self.compiler.AddToListVar('POSTLINKFLAGS', '/OPT:REF')
149 if AMBuild.options.debug == '1':
150 self.compiler.AddToListVar('CDEFINES', 'DEBUG')
151 self.compiler.AddToListVar('CDEFINES', '_DEBUG')
152 if self.vendor == 'gcc' or self.vendor == 'clang':
153 self.compiler.AddToListVar('CFLAGS', '-g3')
154 elif self.vendor == 'msvc':
155 self.compiler.AddToListVar('CFLAGS', '/Od')
156 self.compiler.AddToListVar('CFLAGS', '/RTC1')
159 if AMBuild.target['platform'] == 'linux':
160 self.compiler.AddToListVar('CDEFINES', '_LINUX')
161 if self.vendor == 'gcc':
162 self.compiler.AddToListVar('POSTLINKFLAGS', '-static-libgcc')
163 if self.vendor == 'clang':
164 self.compiler.AddToListVar('POSTLINKFLAGS', '-lgcc_eh')
165 elif AMBuild.target['platform'] == 'darwin':
166 self.compiler.AddToListVar('CFLAGS', ['-isysroot',
167 '/Developer/SDKs/MacOSX10.5.sdk'])
168 self.compiler.AddToListVar('POSTLINKFLAGS', '-mmacosx-version-min=10.5')
169 self.compiler.AddToListVar('POSTLINKFLAGS', ['-arch', 'i386'])
170 self.compiler.AddToListVar('POSTLINKFLAGS', '-lstdc++')
172 # For OS X dylib versioning
174 productFile = open(os.path.join(AMBuild.sourceFolder, 'product.version'), 'r')
175 productContents = productFile.read()
177 m = re.match('(\d+)\.(\d+)\.(\d+).*', productContents)
179 self.version = '1.0.0'
181 major, minor, release = m.groups()
182 self.version = '{0}.{1}.{2}'.format(major, minor, release)
183 AMBuild.cache.CacheVariable('version', self.version)
184 elif AMBuild.target['platform'] == 'windows':
185 self.compiler.AddToListVar('CDEFINES', 'WIN32')
186 self.compiler.AddToListVar('CDEFINES', '_WINDOWS')
189 self.compiler.AddToListVar('CDEFINES', 'SOURCEMOD_BUILD')
190 self.compiler.AddToListVar('CDEFINES', 'SM_GENERATED_BUILD')
191 self.compiler.AddToListVar('CINCLUDES',
192 os.path.join(AMBuild.outputFolder, 'includes'))
193 self.compiler.ToConfig(AMBuild, 'compiler')
194 AMBuild.cache.CacheVariable('vendor', self.vendor)
196 AMBuild.cache.CacheVariable('targetMap', self.targetMap)
198 self.compiler.FromConfig(AMBuild, 'compiler')
199 self.targetMap = AMBuild.cache['targetMap']
201 if AMBuild.target['platform'] == 'windows':
202 self.compiler.AddToListVar('RCINCLUDES', os.path.join(AMBuild.sourceFolder, 'public'))
203 self.compiler.AddToListVar('RCINCLUDES',
204 os.path.join(AMBuild.outputFolder, 'includes'))
205 self.mmsPath = AMBuild.cache['MMSOURCE18']
207 def DefaultCompiler(self):
208 return self.compiler.Clone()
210 def JobMatters(self, jobname):
211 file = sys._getframe().f_code.co_filename
212 if AMBuild.mode == 'config':
213 self.targetMap[jobname] = file
215 if len(AMBuild.args) == 0:
217 if not jobname in AMBuild.args:
220 def DefaultExtCompiler(self, path):
221 compiler = self.DefaultCompiler()
222 compiler['CXXINCLUDES'].append(os.path.join(AMBuild.sourceFolder, path))
223 compiler['CXXINCLUDES'].append(os.path.join(AMBuild.sourceFolder, path, 'sdk'))
224 compiler['CXXINCLUDES'].append(os.path.join(AMBuild.sourceFolder, 'public'))
225 compiler['CXXINCLUDES'].append(os.path.join(AMBuild.sourceFolder, 'public', 'extensions'))
226 compiler['CXXINCLUDES'].append(os.path.join(AMBuild.sourceFolder, 'public', 'sourcepawn'))
229 def AutoVersion(self, folder, binary):
230 if AMBuild.target['platform'] == 'windows':
231 env = {'RCDEFINES': ['BINARY_NAME="' + binary.binaryFile + '"', 'SM_GENERATED_BUILD']}
232 binary.AddResourceFile(os.path.join(folder, 'version.rc' ), env)
233 elif AMBuild.target['platform'] == 'darwin' and isinstance(binary, Cpp.LibraryBuilder):
234 binary.compiler['POSTLINKFLAGS'].extend(['-compatibility_version', '1.0.0'])
235 binary.compiler['POSTLINKFLAGS'].extend(['-current_version', AMBuild.cache['version']])
239 def PreSetupHL2Job(self, job, builder, sdk):
240 info = self.sdkInfo[sdk]
241 sdkPath = AMBuild.cache[info['sdk']]
242 if AMBuild.target['platform'] == 'linux':
244 staticLibs = os.path.join(sdkPath, 'linux_sdk')
246 staticLibs = os.path.join(sdkPath, 'lib', 'linux')
247 workFolder = os.path.join(AMBuild.outputFolder, job.workFolder)
248 if sdk in ['ep2v', 'l4d', 'l4d2']:
249 for i in ['tier1_i486.a', 'mathlib_i486.a', 'libvstdlib.so', 'libtier0.so']:
250 link = os.path.join(workFolder, i)
251 target = os.path.join(staticLibs, i)
255 job.AddCommand(SymlinkCommand(link, target))
257 for i in ['tier1_i486.a', 'mathlib_i486.a', 'vstdlib_i486.so', 'tier0_i486.so']:
258 link = os.path.join(workFolder, i)
259 target = os.path.join(staticLibs, i)
263 job.AddCommand(SymlinkCommand(link, target))
264 elif AMBuild.target['platform'] == 'darwin':
265 staticLibs = os.path.join(sdkPath, 'lib', 'mac')
266 workFolder = os.path.join(AMBuild.outputFolder, job.workFolder)
267 for i in ['tier1_i486.a', 'mathlib_i486.a', 'libvstdlib.dylib', 'libtier0.dylib']:
268 link = os.path.join(workFolder, i)
269 target = os.path.join(staticLibs, i)
273 job.AddCommand(SymlinkCommand(link, target))
274 elif AMBuild.target['platform'] == 'windows':
275 libs = ['tier0', 'tier1', 'vstdlib', 'mathlib']
277 libs.append('interfaces')
279 libPath = os.path.join(sdkPath, 'lib', 'public', lib) + '.lib'
280 builder.RebuildIfNewer(libPath)
281 builder['POSTLINKFLAGS'].append(libPath)
283 def PostSetupHL2Job(self, job, builder, sdk):
284 if AMBuild.target['platform'] in ['linux', 'darwin']:
285 builder.AddObjectFiles(['tier1_i486.a', 'mathlib_i486.a'])
287 def DefaultHL2Compiler(self, path, sdk, noLink = False, oldMms = '-legacy'):
288 compiler = self.DefaultExtCompiler(path)
294 compiler['CXXINCLUDES'].append(os.path.join(self.mmsPath, mms))
295 compiler['CXXINCLUDES'].append(os.path.join(self.mmsPath, mms, 'sourcehook'))
298 compiler['CDEFINES'].extend(['SE_' + info[i]['name'] + '=' + info[i]['def'] for i in info])
300 paths = [['public'], ['public', 'engine'], ['public', 'mathlib'], ['public', 'vstdlib'],
301 ['public', 'tier0'], ['public', 'tier1']]
302 if sdk == 'ep1' or sdk == 'darkm':
303 paths.append(['public', 'dlls'])
304 paths.append(['game_shared'])
306 paths.append(['public', 'game', 'server'])
307 paths.append(['public', 'toolframework'])
308 paths.append(['game', 'shared'])
309 paths.append(['common'])
311 info = self.sdkInfo[sdk]
312 sdkPath = AMBuild.cache[info['sdk']]
314 compiler['CDEFINES'].append('SOURCE_ENGINE=' + info['def'])
316 if sdk == 'swarm' and AMBuild.target['platform'] == 'windows':
317 compiler['CDEFINES'].extend(['COMPILER_MSVC', 'COMPILER_MSVC32'])
320 if AMBuild.target['platform'] == 'linux':
321 staticLibs = os.path.join(sdkPath, 'linux_sdk')
323 if AMBuild.target['platform'] == 'linux':
324 staticLibs = os.path.join(sdkPath, 'lib', 'linux')
325 elif AMBuild.target['platform'] == 'darwin':
326 staticLibs = os.path.join(sdkPath, 'lib', 'mac')
329 compiler['CXXINCLUDES'].append(os.path.join(sdkPath, *i))
332 if AMBuild.target['platform'] == 'linux':
333 compiler['POSTLINKFLAGS'][0:0] = ['-lm']
334 if sdk in ['ep2v', 'l4d', 'l4d2']:
335 compiler['POSTLINKFLAGS'][0:0] = ['libtier0.so']
336 compiler['POSTLINKFLAGS'][0:0] = ['libvstdlib.so']
338 compiler['POSTLINKFLAGS'][0:0] = ['tier0_i486.so']
339 compiler['POSTLINKFLAGS'][0:0] = ['vstdlib_i486.so']
340 elif AMBuild.target['platform'] == 'darwin':
341 compiler['POSTLINKFLAGS'][0:0] = ['libtier0.dylib']
342 compiler['POSTLINKFLAGS'][0:0] = ['libvstdlib.dylib']
351 AMBuild.Include(os.path.join('tools', 'buildbot', 'Versioning'), globals)
354 ['loader', 'AMBuilder'],
355 ['core', 'AMBuilder'],
356 ['core', 'logic', 'AMBuilder'],
357 ['extensions', 'bintools', 'AMBuilder'],
358 ['extensions', 'clientprefs', 'AMBuilder'],
359 ['extensions', 'cstrike', 'AMBuilder'],
360 ['extensions', 'curl', 'AMBuilder'],
361 ['extensions', 'geoip', 'AMBuilder'],
362 ['extensions', 'mysql', 'AMBuilder'],
363 ['extensions', 'sdktools', 'AMBuilder'],
364 ['extensions', 'topmenus', 'AMBuilder'],
365 ['extensions', 'updater', 'AMBuilder'],
366 ['extensions', 'sqlite', 'AMBuilder'],
367 ['extensions', 'regex', 'AMBuilder'],
368 ['extensions', 'tf2', 'AMBuilder'],
369 ['sourcepawn', 'jit', 'AMBuilder'],
370 ['sourcepawn', 'compiler', 'AMBuilder'],
371 ['plugins', 'AMBuilder'],
372 ['tools', 'buildbot', 'PackageScript']
375 for parts in FileList:
376 AMBuild.Include(os.path.join(*parts), globals)