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 elif isinstance(cxx, Cpp.MSVC):
104 if AMBuild.options.debug == '1':
105 self.compiler.AddToListVar('CFLAGS', '/MTd')
106 self.compiler.AddToListVar('POSTLINKFLAGS', '/NODEFAULTLIB:libcmt')
108 self.compiler.AddToListVar('CFLAGS', '/MT')
109 self.compiler.AddToListVar('CDEFINES', '_CRT_SECURE_NO_DEPRECATE')
110 self.compiler.AddToListVar('CDEFINES', '_CRT_SECURE_NO_WARNINGS')
111 self.compiler.AddToListVar('CDEFINES', '_CRT_NONSTDC_NO_DEPRECATE')
112 self.compiler.AddToListVar('CXXFLAGS', '/EHsc')
113 self.compiler.AddToListVar('CXXFLAGS', '/GR-')
114 self.compiler.AddToListVar('CFLAGS', '/W3')
115 self.compiler.AddToListVar('CFLAGS', '/nologo')
116 self.compiler.AddToListVar('CFLAGS', '/Zi')
117 self.compiler.AddToListVar('CXXFLAGS', '/TP')
118 self.compiler.AddToListVar('POSTLINKFLAGS', '/DEBUG')
119 self.compiler.AddToListVar('POSTLINKFLAGS', '/MACHINE:X86')
120 self.compiler.AddToListVar('POSTLINKFLAGS', '/SUBSYSTEM:WINDOWS')
121 self.compiler.AddToListVar('POSTLINKFLAGS', 'kernel32.lib')
122 self.compiler.AddToListVar('POSTLINKFLAGS', 'user32.lib')
123 self.compiler.AddToListVar('POSTLINKFLAGS', 'gdi32.lib')
124 self.compiler.AddToListVar('POSTLINKFLAGS', 'winspool.lib')
125 self.compiler.AddToListVar('POSTLINKFLAGS', 'comdlg32.lib')
126 self.compiler.AddToListVar('POSTLINKFLAGS', 'advapi32.lib')
127 self.compiler.AddToListVar('POSTLINKFLAGS', 'shell32.lib')
128 self.compiler.AddToListVar('POSTLINKFLAGS', 'ole32.lib')
129 self.compiler.AddToListVar('POSTLINKFLAGS', 'oleaut32.lib')
130 self.compiler.AddToListVar('POSTLINKFLAGS', 'uuid.lib')
131 self.compiler.AddToListVar('POSTLINKFLAGS', 'odbc32.lib')
132 self.compiler.AddToListVar('POSTLINKFLAGS', 'odbccp32.lib')
135 if AMBuild.options.opt == '1':
136 self.compiler.AddToListVar('CDEFINES', 'NDEBUG')
137 if self.vendor == 'gcc' or self.vendor == 'clang':
138 self.compiler.AddToListVar('CFLAGS', '-O3')
139 elif self.vendor == 'msvc':
140 self.compiler.AddToListVar('CFLAGS', '/Ox')
141 self.compiler.AddToListVar('POSTLINKFLAGS', '/OPT:ICF')
142 self.compiler.AddToListVar('POSTLINKFLAGS', '/OPT:REF')
145 if AMBuild.options.debug == '1':
146 self.compiler.AddToListVar('CDEFINES', 'DEBUG')
147 self.compiler.AddToListVar('CDEFINES', '_DEBUG')
148 if self.vendor == 'gcc' or self.vendor == 'clang':
149 self.compiler.AddToListVar('CFLAGS', '-g3')
150 elif self.vendor == 'msvc':
151 self.compiler.AddToListVar('CFLAGS', '/Od')
152 self.compiler.AddToListVar('CFLAGS', '/RTC1')
155 if AMBuild.target['platform'] == 'linux':
156 self.compiler.AddToListVar('CDEFINES', '_LINUX')
157 if self.vendor == 'gcc':
158 self.compiler.AddToListVar('POSTLINKFLAGS', '-static-libgcc')
159 if self.vendor == 'clang':
160 self.compiler.AddToListVar('POSTLINKFLAGS', '-lgcc_eh')
161 elif AMBuild.target['platform'] == 'darwin':
162 self.compiler.AddToListVar('CFLAGS', ['-isysroot',
163 '/Developer/SDKs/MacOSX10.5.sdk'])
164 self.compiler.AddToListVar('POSTLINKFLAGS', '-mmacosx-version-min=10.5')
165 self.compiler.AddToListVar('POSTLINKFLAGS', ['-arch', 'i386'])
166 self.compiler.AddToListVar('POSTLINKFLAGS', '-lstdc++')
168 # For OS X dylib versioning
170 productFile = open(os.path.join(AMBuild.sourceFolder, 'product.version'), 'r')
171 productContents = productFile.read()
173 m = re.match('(\d+)\.(\d+)\.(\d+).*', productContents)
175 self.version = '1.0.0'
177 major, minor, release = m.groups()
178 self.version = '{0}.{1}.{2}'.format(major, minor, release)
179 AMBuild.cache.CacheVariable('version', self.version)
180 elif AMBuild.target['platform'] == 'windows':
181 self.compiler.AddToListVar('CDEFINES', 'WIN32')
182 self.compiler.AddToListVar('CDEFINES', '_WINDOWS')
185 self.compiler.AddToListVar('CDEFINES', 'SOURCEMOD_BUILD')
186 self.compiler.AddToListVar('CDEFINES', 'SM_GENERATED_BUILD')
187 self.compiler.AddToListVar('CINCLUDES',
188 os.path.join(AMBuild.outputFolder, 'includes'))
189 self.compiler.ToConfig(AMBuild, 'compiler')
190 AMBuild.cache.CacheVariable('vendor', self.vendor)
192 AMBuild.cache.CacheVariable('targetMap', self.targetMap)
194 self.compiler.FromConfig(AMBuild, 'compiler')
195 self.targetMap = AMBuild.cache['targetMap']
197 if AMBuild.target['platform'] == 'windows':
198 self.compiler.AddToListVar('RCINCLUDES', os.path.join(AMBuild.sourceFolder, 'public'))
199 self.compiler.AddToListVar('RCINCLUDES',
200 os.path.join(AMBuild.outputFolder, 'includes'))
201 self.mmsPath = AMBuild.cache['MMSOURCE18']
203 def DefaultCompiler(self):
204 return self.compiler.Clone()
206 def JobMatters(self, jobname):
207 file = sys._getframe().f_code.co_filename
208 if AMBuild.mode == 'config':
209 self.targetMap[jobname] = file
211 if len(AMBuild.args) == 0:
213 if not jobname in AMBuild.args:
216 def DefaultExtCompiler(self, path):
217 compiler = self.DefaultCompiler()
218 compiler['CXXINCLUDES'].append(os.path.join(AMBuild.sourceFolder, path))
219 compiler['CXXINCLUDES'].append(os.path.join(AMBuild.sourceFolder, path, 'sdk'))
220 compiler['CXXINCLUDES'].append(os.path.join(AMBuild.sourceFolder, 'public'))
221 compiler['CXXINCLUDES'].append(os.path.join(AMBuild.sourceFolder, 'public', 'extensions'))
222 compiler['CXXINCLUDES'].append(os.path.join(AMBuild.sourceFolder, 'public', 'sourcepawn'))
225 def AutoVersion(self, folder, binary):
226 if AMBuild.target['platform'] == 'windows':
227 env = {'RCDEFINES': ['BINARY_NAME="' + binary.binaryFile + '"', 'SM_GENERATED_BUILD']}
228 binary.AddResourceFile(os.path.join(folder, 'version.rc' ), env)
229 elif AMBuild.target['platform'] == 'darwin' and isinstance(binary, Cpp.LibraryBuilder):
230 binary.compiler['POSTLINKFLAGS'].extend(['-compatibility_version', '1.0.0'])
231 binary.compiler['POSTLINKFLAGS'].extend(['-current_version', AMBuild.cache['version']])
235 def PreSetupHL2Job(self, job, builder, sdk):
236 info = self.sdkInfo[sdk]
237 sdkPath = AMBuild.cache[info['sdk']]
238 if AMBuild.target['platform'] == 'linux':
240 staticLibs = os.path.join(sdkPath, 'linux_sdk')
242 staticLibs = os.path.join(sdkPath, 'lib', 'linux')
243 workFolder = os.path.join(AMBuild.outputFolder, job.workFolder)
244 if sdk in ['ep2v', 'l4d', 'l4d2']:
245 for i in ['tier1_i486.a', 'mathlib_i486.a', 'libvstdlib.so', 'libtier0.so']:
246 link = os.path.join(workFolder, i)
247 target = os.path.join(staticLibs, i)
251 job.AddCommand(SymlinkCommand(link, target))
253 for i in ['tier1_i486.a', 'mathlib_i486.a', 'vstdlib_i486.so', 'tier0_i486.so']:
254 link = os.path.join(workFolder, i)
255 target = os.path.join(staticLibs, i)
259 job.AddCommand(SymlinkCommand(link, target))
260 elif AMBuild.target['platform'] == 'darwin':
261 staticLibs = os.path.join(sdkPath, 'lib', 'mac')
262 workFolder = os.path.join(AMBuild.outputFolder, job.workFolder)
263 for i in ['tier1_i486.a', 'mathlib_i486.a', 'libvstdlib.dylib', 'libtier0.dylib']:
264 link = os.path.join(workFolder, i)
265 target = os.path.join(staticLibs, i)
269 job.AddCommand(SymlinkCommand(link, target))
270 elif AMBuild.target['platform'] == 'windows':
271 libs = ['tier0', 'tier1', 'vstdlib', 'mathlib']
273 libs.append('interfaces')
275 libPath = os.path.join(sdkPath, 'lib', 'public', lib) + '.lib'
276 builder.RebuildIfNewer(libPath)
277 builder['POSTLINKFLAGS'].append(libPath)
279 def PostSetupHL2Job(self, job, builder, sdk):
280 if AMBuild.target['platform'] in ['linux', 'darwin']:
281 builder.AddObjectFiles(['tier1_i486.a', 'mathlib_i486.a'])
283 def DefaultHL2Compiler(self, path, sdk, noLink = False, oldMms = '-legacy'):
284 compiler = self.DefaultExtCompiler(path)
290 compiler['CXXINCLUDES'].append(os.path.join(self.mmsPath, mms))
291 compiler['CXXINCLUDES'].append(os.path.join(self.mmsPath, mms, 'sourcehook'))
294 compiler['CDEFINES'].extend(['SE_' + info[i]['name'] + '=' + info[i]['def'] for i in info])
296 paths = [['public'], ['public', 'engine'], ['public', 'mathlib'], ['public', 'vstdlib'],
297 ['public', 'tier0'], ['public', 'tier1']]
298 if sdk == 'ep1' or sdk == 'darkm':
299 paths.append(['public', 'dlls'])
300 paths.append(['game_shared'])
302 paths.append(['public', 'game', 'server'])
303 paths.append(['public', 'toolframework'])
304 paths.append(['game', 'shared'])
305 paths.append(['common'])
307 info = self.sdkInfo[sdk]
308 sdkPath = AMBuild.cache[info['sdk']]
310 compiler['CDEFINES'].append('SOURCE_ENGINE=' + info['def'])
312 if sdk == 'swarm' and AMBuild.target['platform'] == 'windows':
313 compiler['CDEFINES'].extend(['COMPILER_MSVC', 'COMPILER_MSVC32'])
316 if AMBuild.target['platform'] == 'linux':
317 staticLibs = os.path.join(sdkPath, 'linux_sdk')
319 if AMBuild.target['platform'] == 'linux':
320 staticLibs = os.path.join(sdkPath, 'lib', 'linux')
321 elif AMBuild.target['platform'] == 'darwin':
322 staticLibs = os.path.join(sdkPath, 'lib', 'mac')
325 compiler['CXXINCLUDES'].append(os.path.join(sdkPath, *i))
328 if AMBuild.target['platform'] == 'linux':
329 compiler['POSTLINKFLAGS'][0:0] = ['-lm']
330 if sdk in ['ep2v', 'l4d', 'l4d2']:
331 compiler['POSTLINKFLAGS'][0:0] = ['libtier0.so']
332 compiler['POSTLINKFLAGS'][0:0] = ['libvstdlib.so']
334 compiler['POSTLINKFLAGS'][0:0] = ['tier0_i486.so']
335 compiler['POSTLINKFLAGS'][0:0] = ['vstdlib_i486.so']
336 elif AMBuild.target['platform'] == 'darwin':
337 compiler['POSTLINKFLAGS'][0:0] = ['libtier0.dylib']
338 compiler['POSTLINKFLAGS'][0:0] = ['libvstdlib.dylib']
347 AMBuild.Include(os.path.join('tools', 'buildbot', 'Versioning'), globals)
350 ['loader', 'AMBuilder'],
351 ['core', 'AMBuilder'],
352 ['core', 'logic', 'AMBuilder'],
353 ['extensions', 'bintools', 'AMBuilder'],
354 ['extensions', 'clientprefs', 'AMBuilder'],
355 ['extensions', 'cstrike', 'AMBuilder'],
356 ['extensions', 'curl', 'AMBuilder'],
357 ['extensions', 'geoip', 'AMBuilder'],
358 ['extensions', 'mysql', 'AMBuilder'],
359 ['extensions', 'sdktools', 'AMBuilder'],
360 ['extensions', 'topmenus', 'AMBuilder'],
361 ['extensions', 'updater', 'AMBuilder'],
362 ['extensions', 'sqlite', 'AMBuilder'],
363 ['extensions', 'regex', 'AMBuilder'],
364 ['extensions', 'tf2', 'AMBuilder'],
365 ['sourcepawn', 'jit', 'AMBuilder'],
366 ['sourcepawn', 'compiler', 'AMBuilder'],
367 ['plugins', 'AMBuilder'],
368 ['tools', 'buildbot', 'PackageScript']
371 for parts in FileList:
372 AMBuild.Include(os.path.join(*parts), globals)