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 if self.vendor == 'gcc':
101 self.compiler.AddToListVar('CFLAGS', '-mfpmath=sse')
102 self.compiler.AddToListVar('POSTLINKFLAGS', '-static-libgcc')
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 == 'clang':
159 self.compiler.AddToListVar('POSTLINKFLAGS', '-lgcc_eh')
160 elif AMBuild.target['platform'] == 'darwin':
161 self.compiler.AddToListVar('CFLAGS', ['-isysroot',
162 '/Developer/SDKs/MacOSX10.5.sdk'])
163 self.compiler.AddToListVar('POSTLINKFLAGS', '-mmacosx-version-min=10.5')
164 self.compiler.AddToListVar('POSTLINKFLAGS', ['-arch', 'i386'])
165 self.compiler.AddToListVar('POSTLINKFLAGS', '-lstdc++')
167 # For OS X dylib versioning
169 productFile = open(os.path.join(AMBuild.sourceFolder, 'product.version'), 'r')
170 productContents = productFile.read()
172 m = re.match('(\d+)\.(\d+)\.(\d+).*', productContents)
174 self.version = '1.0.0'
176 major, minor, release = m.groups()
177 self.version = '{0}.{1}.{2}'.format(major, minor, release)
178 AMBuild.cache.CacheVariable('version', self.version)
179 elif AMBuild.target['platform'] == 'windows':
180 self.compiler.AddToListVar('CDEFINES', 'WIN32')
181 self.compiler.AddToListVar('CDEFINES', '_WINDOWS')
184 self.compiler.AddToListVar('CDEFINES', 'SOURCEMOD_BUILD')
185 self.compiler.AddToListVar('CDEFINES', 'SM_GENERATED_BUILD')
186 self.compiler.AddToListVar('CINCLUDES',
187 os.path.join(AMBuild.outputFolder, 'includes'))
188 self.compiler.ToConfig(AMBuild, 'compiler')
189 AMBuild.cache.CacheVariable('vendor', self.vendor)
191 AMBuild.cache.CacheVariable('targetMap', self.targetMap)
193 self.compiler.FromConfig(AMBuild, 'compiler')
194 self.targetMap = AMBuild.cache['targetMap']
196 if AMBuild.target['platform'] == 'windows':
197 self.compiler.AddToListVar('RCINCLUDES', os.path.join(AMBuild.sourceFolder, 'public'))
198 self.compiler.AddToListVar('RCINCLUDES',
199 os.path.join(AMBuild.outputFolder, 'includes'))
200 self.mmsPath = AMBuild.cache['MMSOURCE18']
202 def DefaultCompiler(self):
203 return self.compiler.Clone()
205 def JobMatters(self, jobname):
206 file = sys._getframe().f_code.co_filename
207 if AMBuild.mode == 'config':
208 self.targetMap[jobname] = file
210 if len(AMBuild.args) == 0:
212 if not jobname in AMBuild.args:
215 def DefaultExtCompiler(self, path):
216 compiler = self.DefaultCompiler()
217 compiler['CXXINCLUDES'].append(os.path.join(AMBuild.sourceFolder, path))
218 compiler['CXXINCLUDES'].append(os.path.join(AMBuild.sourceFolder, path, 'sdk'))
219 compiler['CXXINCLUDES'].append(os.path.join(AMBuild.sourceFolder, 'public'))
220 compiler['CXXINCLUDES'].append(os.path.join(AMBuild.sourceFolder, 'public', 'extensions'))
221 compiler['CXXINCLUDES'].append(os.path.join(AMBuild.sourceFolder, 'public', 'sourcepawn'))
224 def AutoVersion(self, folder, binary):
225 if AMBuild.target['platform'] == 'windows':
226 env = {'RCDEFINES': ['BINARY_NAME="' + binary.binaryFile + '"', 'SM_GENERATED_BUILD']}
227 binary.AddResourceFile(os.path.join(folder, 'version.rc' ), env)
228 elif AMBuild.target['platform'] == 'darwin' and isinstance(binary, Cpp.LibraryBuilder):
229 binary.compiler['POSTLINKFLAGS'].extend(['-compatibility_version', '1.0.0'])
230 binary.compiler['POSTLINKFLAGS'].extend(['-current_version', AMBuild.cache['version']])
234 def PreSetupHL2Job(self, job, builder, sdk):
235 info = self.sdkInfo[sdk]
236 sdkPath = AMBuild.cache[info['sdk']]
237 if AMBuild.target['platform'] == 'linux':
239 staticLibs = os.path.join(sdkPath, 'linux_sdk')
241 staticLibs = os.path.join(sdkPath, 'lib', 'linux')
242 workFolder = os.path.join(AMBuild.outputFolder, job.workFolder)
243 if sdk in ['ep2v', 'l4d', 'l4d2']:
244 for i in ['tier1_i486.a', 'mathlib_i486.a', 'libvstdlib.so', 'libtier0.so']:
245 link = os.path.join(workFolder, i)
246 target = os.path.join(staticLibs, i)
250 job.AddCommand(SymlinkCommand(link, target))
252 for i in ['tier1_i486.a', 'mathlib_i486.a', 'vstdlib_i486.so', 'tier0_i486.so']:
253 link = os.path.join(workFolder, i)
254 target = os.path.join(staticLibs, i)
258 job.AddCommand(SymlinkCommand(link, target))
259 elif AMBuild.target['platform'] == 'darwin':
260 staticLibs = os.path.join(sdkPath, 'lib', 'mac')
261 workFolder = os.path.join(AMBuild.outputFolder, job.workFolder)
262 for i in ['tier1_i486.a', 'mathlib_i486.a', 'libvstdlib.dylib', 'libtier0.dylib']:
263 link = os.path.join(workFolder, i)
264 target = os.path.join(staticLibs, i)
268 job.AddCommand(SymlinkCommand(link, target))
269 elif AMBuild.target['platform'] == 'windows':
270 libs = ['tier0', 'tier1', 'vstdlib', 'mathlib']
272 libs.append('interfaces')
274 libPath = os.path.join(sdkPath, 'lib', 'public', lib) + '.lib'
275 builder.RebuildIfNewer(libPath)
276 builder['POSTLINKFLAGS'].append(libPath)
278 def PostSetupHL2Job(self, job, builder, sdk):
279 if AMBuild.target['platform'] in ['linux', 'darwin']:
280 builder.AddObjectFiles(['tier1_i486.a', 'mathlib_i486.a'])
282 def DefaultHL2Compiler(self, path, sdk, noLink = False, oldMms = '-legacy'):
283 compiler = self.DefaultExtCompiler(path)
289 compiler['CXXINCLUDES'].append(os.path.join(self.mmsPath, mms))
290 compiler['CXXINCLUDES'].append(os.path.join(self.mmsPath, mms, 'sourcehook'))
293 compiler['CDEFINES'].extend(['SE_' + info[i]['name'] + '=' + info[i]['def'] for i in info])
295 paths = [['public'], ['public', 'engine'], ['public', 'mathlib'], ['public', 'vstdlib'],
296 ['public', 'tier0'], ['public', 'tier1']]
297 if sdk == 'ep1' or sdk == 'darkm':
298 paths.append(['public', 'dlls'])
299 paths.append(['game_shared'])
301 paths.append(['public', 'game', 'server'])
302 paths.append(['game', 'shared'])
303 paths.append(['common'])
305 info = self.sdkInfo[sdk]
306 sdkPath = AMBuild.cache[info['sdk']]
308 compiler['CDEFINES'].append('SOURCE_ENGINE=' + info['def'])
310 if sdk == 'swarm' and AMBuild.target['platform'] == 'windows':
311 compiler['CDEFINES'].extend(['COMPILER_MSVC', 'COMPILER_MSVC32'])
314 if AMBuild.target['platform'] == 'linux':
315 staticLibs = os.path.join(sdkPath, 'linux_sdk')
317 if AMBuild.target['platform'] == 'linux':
318 staticLibs = os.path.join(sdkPath, 'lib', 'linux')
319 elif AMBuild.target['platform'] == 'darwin':
320 staticLibs = os.path.join(sdkPath, 'lib', 'mac')
323 compiler['CXXINCLUDES'].append(os.path.join(sdkPath, *i))
326 if AMBuild.target['platform'] == 'linux':
327 compiler['POSTLINKFLAGS'][0:0] = ['-lm']
328 if sdk in ['ep2v', 'l4d', 'l4d2']:
329 compiler['POSTLINKFLAGS'][0:0] = ['libtier0.so']
330 compiler['POSTLINKFLAGS'][0:0] = ['libvstdlib.so']
332 compiler['POSTLINKFLAGS'][0:0] = ['tier0_i486.so']
333 compiler['POSTLINKFLAGS'][0:0] = ['vstdlib_i486.so']
334 elif AMBuild.target['platform'] == 'darwin':
335 compiler['POSTLINKFLAGS'][0:0] = ['libtier0.dylib']
336 compiler['POSTLINKFLAGS'][0:0] = ['libvstdlib.dylib']
345 AMBuild.Include(os.path.join('tools', 'buildbot', 'Versioning'), globals)
348 ['loader', 'AMBuilder'],
349 ['core', 'AMBuilder'],
350 ['core', 'logic', 'AMBuilder'],
351 ['extensions', 'bintools', 'AMBuilder'],
352 ['extensions', 'clientprefs', 'AMBuilder'],
353 ['extensions', 'cstrike', 'AMBuilder'],
354 ['extensions', 'curl', 'AMBuilder'],
355 ['extensions', 'geoip', 'AMBuilder'],
356 ['extensions', 'mysql', 'AMBuilder'],
357 ['extensions', 'sdktools', 'AMBuilder'],
358 ['extensions', 'topmenus', 'AMBuilder'],
359 ['extensions', 'updater', 'AMBuilder'],
360 ['extensions', 'sqlite', 'AMBuilder'],
361 ['extensions', 'regex', 'AMBuilder'],
362 ['extensions', 'tf2', 'AMBuilder'],
363 ['sourcepawn', 'jit', 'AMBuilder'],
364 ['sourcepawn', 'compiler', 'AMBuilder'],
365 ['plugins', 'AMBuilder'],
366 ['tools', 'buildbot', 'PackageScript']
369 for parts in FileList:
370 AMBuild.Include(os.path.join(*parts), globals)