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': '4',
17 'name': 'ORANGEBOXVALVE', 'platform': ['windows', 'linux', 'darwin']}
18 self.sdkInfo['l4d'] = {'sdk': 'HL2SDKL4D', 'ext': '2.l4d', 'def': '5',
19 'name': 'LEFT4DEAD', 'platform': ['windows', 'linux']}
20 self.sdkInfo['l4d2'] = {'sdk': 'HL2SDKL4D2', 'ext': '2.l4d2', 'def': '6',
21 'name': 'LEFT4DEAD2', 'platform': ['windows', 'linux']}
22 self.sdkInfo['darkm'] = {'sdk': 'HL2SDK-DARKM', 'ext': '2.darkm', 'def': '2',
23 'name': 'DARKMESSIAH', 'platform': ['windows']}
25 if AMBuild.mode == 'config':
27 self.compiler.DetectAll(AMBuild)
30 envvars = { 'MMSOURCE18': 'mmsource-1.8',
31 'HL2SDKOBVALVE': 'hl2sdk-ob-valve',
35 if AMBuild.target['platform'] != 'darwin':
36 envvars['HL2SDK'] = 'hl2sdk'
37 envvars['HL2SDKOB'] = 'hl2sdk-ob'
38 envvars['HL2SDKL4D'] = 'hl2sdk-l4d'
39 envvars['HL2SDKL4D2'] = 'hl2sdk-l4d2'
41 #Dark Messiah is Windows-only
42 if AMBuild.target['platform'] == 'windows':
43 envvars['HL2SDK-DARKM'] = 'hl2sdk-darkm'
45 #Must have a path for each envvar (file a bug if you don't like this)
49 if not os.path.isdir(path):
50 raise Exception('Path for {0} was not found: {1}'.format(i, path))
54 while head != None and head != oldhead:
55 path = os.path.join(head, envvars[i])
56 if os.path.isdir(path):
59 head, tail = os.path.split(head)
60 if head == None or head == oldhead:
61 raise Exception('Could not find a valid path for {0}'.format(i))
62 AMBuild.cache.CacheVariable(i, path)
65 cxx = self.compiler.cxx
66 if isinstance(cxx, Cpp.GCC):
68 self.compiler.AddToListVar('CDEFINES', 'stricmp=strcasecmp')
69 self.compiler.AddToListVar('CDEFINES', '_stricmp=strcasecmp')
70 self.compiler.AddToListVar('CDEFINES', '_snprintf=snprintf')
71 self.compiler.AddToListVar('CDEFINES', '_vsnprintf=vsnprintf')
72 self.compiler.AddToListVar('CFLAGS', '-pipe')
73 self.compiler.AddToListVar('CFLAGS', '-fno-strict-aliasing')
74 if cxx.majorVersion >= 4:
75 self.compiler.AddToListVar('CFLAGS', '-fvisibility=hidden')
76 self.compiler.AddToListVar('CXXFLAGS', '-fvisibility-inlines-hidden')
77 self.compiler.AddToListVar('CFLAGS', '-Wall')
78 self.compiler.AddToListVar('CFLAGS', '-Werror')
79 self.compiler.AddToListVar('CFLAGS', '-Wno-uninitialized')
80 self.compiler.AddToListVar('CFLAGS', '-Wno-unused')
81 self.compiler.AddToListVar('CFLAGS', '-Wno-switch')
82 self.compiler.AddToListVar('CFLAGS', '-mfpmath=sse')
83 self.compiler.AddToListVar('CFLAGS', '-msse')
84 self.compiler.AddToListVar('CFLAGS', '-m32')
85 self.compiler.AddToListVar('POSTLINKFLAGS', '-m32')
86 self.compiler.AddToListVar('CFLAGS', '-static-libgcc')
87 self.compiler.AddToListVar('CXXFLAGS', '-fno-exceptions')
88 self.compiler.AddToListVar('CXXFLAGS', '-fno-rtti')
89 self.compiler.AddToListVar('CXXFLAGS', '-fno-threadsafe-statics')
90 self.compiler.AddToListVar('CXXFLAGS', '-Wno-non-virtual-dtor')
91 self.compiler.AddToListVar('CDEFINES', 'HAVE_STDINT_H')
92 elif isinstance(cxx, Cpp.MSVC):
94 if AMBuild.options.debug == '1':
95 self.compiler.AddToListVar('CFLAGS', '/MTd')
97 self.compiler.AddToListVar('CFLAGS', '/MT')
98 self.compiler.AddToListVar('CDEFINES', '_CRT_SECURE_NO_DEPRECATE')
99 self.compiler.AddToListVar('CDEFINES', '_CRT_SECURE_NO_WARNINGS')
100 self.compiler.AddToListVar('CDEFINES', '_CRT_NONSTDC_NO_DEPRECATE')
101 self.compiler.AddToListVar('CXXFLAGS', '/EHsc')
102 self.compiler.AddToListVar('CXXFLAGS', '/GR-')
103 self.compiler.AddToListVar('CFLAGS', '/W3')
104 self.compiler.AddToListVar('CFLAGS', '/nologo')
105 self.compiler.AddToListVar('CFLAGS', '/Zi')
106 self.compiler.AddToListVar('CXXFLAGS', '/TP')
107 self.compiler.AddToListVar('POSTLINKFLAGS', '/DEBUG')
108 self.compiler.AddToListVar('POSTLINKFLAGS', '/MACHINE:X86')
109 self.compiler.AddToListVar('POSTLINKFLAGS', '/SUBSYSTEM:WINDOWS')
110 self.compiler.AddToListVar('POSTLINKFLAGS', 'kernel32.lib')
111 self.compiler.AddToListVar('POSTLINKFLAGS', 'user32.lib')
112 self.compiler.AddToListVar('POSTLINKFLAGS', 'gdi32.lib')
113 self.compiler.AddToListVar('POSTLINKFLAGS', 'winspool.lib')
114 self.compiler.AddToListVar('POSTLINKFLAGS', 'comdlg32.lib')
115 self.compiler.AddToListVar('POSTLINKFLAGS', 'advapi32.lib')
116 self.compiler.AddToListVar('POSTLINKFLAGS', 'shell32.lib')
117 self.compiler.AddToListVar('POSTLINKFLAGS', 'ole32.lib')
118 self.compiler.AddToListVar('POSTLINKFLAGS', 'oleaut32.lib')
119 self.compiler.AddToListVar('POSTLINKFLAGS', 'uuid.lib')
120 self.compiler.AddToListVar('POSTLINKFLAGS', 'odbc32.lib')
121 self.compiler.AddToListVar('POSTLINKFLAGS', 'odbccp32.lib')
124 if AMBuild.options.opt == '1':
125 self.compiler.AddToListVar('CDEFINES', 'NDEBUG')
126 if self.vendor == 'gcc':
127 self.compiler.AddToListVar('CFLAGS', '-O3')
128 elif self.vendor == 'msvc':
129 self.compiler.AddToListVar('CFLAGS', '/Ox')
130 self.compiler.AddToListVar('POSTLINKFLAGS', '/OPT:ICF')
131 self.compiler.AddToListVar('POSTLINKFLAGS', '/OPT:REF')
134 if AMBuild.options.debug == '1':
135 self.compiler.AddToListVar('CDEFINES', 'DEBUG')
136 self.compiler.AddToListVar('CDEFINES', '_DEBUG')
137 if self.vendor == 'gcc':
138 self.compiler.AddToListVar('CFLAGS', '-g3')
139 elif self.vendor == 'msvc':
140 self.compiler.AddToListVar('CFLAGS', '/Od')
141 self.compiler.AddToListVar('CFLAGS', '/RTC1')
144 if AMBuild.target['platform'] == 'linux':
145 self.compiler.AddToListVar('CDEFINES', '_LINUX')
146 elif AMBuild.target['platform'] == 'darwin':
147 self.compiler.AddToListVar('CFLAGS', ['-isysroot',
148 '/Developer/SDKs/MacOSX10.5.sdk'])
149 self.compiler.AddToListVar('POSTLINKFLAGS', '-mmacosx-version-min=10.5')
150 self.compiler.AddToListVar('POSTLINKFLAGS', ['-arch', 'i386'])
151 self.compiler.AddToListVar('POSTLINKFLAGS', '-lstdc++')
153 # For OS X dylib versioning
155 productFile = open(os.path.join(AMBuild.sourceFolder, 'product.version'), 'r')
156 productContents = productFile.read()
158 m = re.match('(\d+)\.(\d+)\.(\d+).*', productContents)
160 self.version = '1.0.0'
162 major, minor, release = m.groups()
163 self.version = '{0}.{1}.{2}'.format(major, minor, release)
164 AMBuild.cache.CacheVariable('version', self.version)
165 elif AMBuild.target['platform'] == 'windows':
166 self.compiler.AddToListVar('CDEFINES', 'WIN32')
167 self.compiler.AddToListVar('CDEFINES', '_WINDOWS')
170 self.compiler.AddToListVar('CDEFINES', 'SOURCEMOD_BUILD')
171 self.compiler.AddToListVar('CDEFINES', 'SM_GENERATED_BUILD')
172 self.compiler.AddToListVar('CINCLUDES',
173 os.path.join(AMBuild.outputFolder, 'includes'))
174 self.compiler.ToConfig(AMBuild, 'compiler')
175 AMBuild.cache.CacheVariable('vendor', self.vendor)
177 AMBuild.cache.CacheVariable('targetMap', self.targetMap)
179 self.compiler.FromConfig(AMBuild, 'compiler')
180 self.targetMap = AMBuild.cache['targetMap']
182 if AMBuild.target['platform'] == 'windows':
183 self.compiler.AddToListVar('RCINCLUDES', os.path.join(AMBuild.sourceFolder, 'public'))
184 self.compiler.AddToListVar('RCINCLUDES',
185 os.path.join(AMBuild.outputFolder, 'includes'))
186 self.mmsPath = AMBuild.cache['MMSOURCE18']
188 def DefaultCompiler(self):
189 return self.compiler.Clone()
191 def JobMatters(self, jobname):
192 file = sys._getframe().f_code.co_filename
193 if AMBuild.mode == 'config':
194 self.targetMap[jobname] = file
196 if len(AMBuild.args) == 0:
198 if not jobname in AMBuild.args:
201 def DefaultExtCompiler(self, path):
202 compiler = self.DefaultCompiler()
203 compiler['CXXINCLUDES'].append(os.path.join(AMBuild.sourceFolder, path))
204 compiler['CXXINCLUDES'].append(os.path.join(AMBuild.sourceFolder, path, 'sdk'))
205 compiler['CXXINCLUDES'].append(os.path.join(AMBuild.sourceFolder, 'public'))
206 compiler['CXXINCLUDES'].append(os.path.join(AMBuild.sourceFolder, 'public', 'extensions'))
207 compiler['CXXINCLUDES'].append(os.path.join(AMBuild.sourceFolder, 'public', 'sourcepawn'))
210 def AutoVersion(self, folder, binary):
211 if AMBuild.target['platform'] == 'windows':
212 env = {'RCDEFINES': ['BINARY_NAME="' + binary.binaryFile + '"', 'SM_GENERATED_BUILD']}
213 binary.AddResourceFile(os.path.join(folder, 'version.rc' ), env)
214 elif AMBuild.target['platform'] == 'darwin' and isinstance(binary, Cpp.LibraryBuilder):
215 binary.compiler['POSTLINKFLAGS'].extend(['-compatibility_version', '1.0.0'])
216 binary.compiler['POSTLINKFLAGS'].extend(['-current_version', AMBuild.cache['version']])
220 def PreSetupHL2Job(self, job, builder, sdk):
221 info = self.sdkInfo[sdk]
222 sdkPath = AMBuild.cache[info['sdk']]
223 if AMBuild.target['platform'] == 'linux':
225 staticLibs = os.path.join(sdkPath, 'linux_sdk')
227 staticLibs = os.path.join(sdkPath, 'lib', 'linux')
228 workFolder = os.path.join(AMBuild.outputFolder, job.workFolder)
229 if sdk == 'ep2v' or sdk == 'l4d2':
230 for i in ['tier1_i486.a', 'mathlib_i486.a', 'libvstdlib.so', 'libtier0.so']:
231 link = os.path.join(workFolder, i)
232 target = os.path.join(staticLibs, i)
236 job.AddCommand(SymlinkCommand(link, target))
238 for i in ['tier1_i486.a', 'mathlib_i486.a', 'vstdlib_i486.so', 'tier0_i486.so']:
239 link = os.path.join(workFolder, i)
240 target = os.path.join(staticLibs, i)
244 job.AddCommand(SymlinkCommand(link, target))
245 elif AMBuild.target['platform'] == 'darwin':
246 staticLibs = os.path.join(sdkPath, 'lib', 'mac')
247 workFolder = os.path.join(AMBuild.outputFolder, job.workFolder)
248 for i in ['tier1_i486.a', 'mathlib_i486.a', 'libvstdlib.dylib', 'libtier0.dylib']:
249 link = os.path.join(workFolder, i)
250 target = os.path.join(staticLibs, i)
254 job.AddCommand(SymlinkCommand(link, target))
255 elif AMBuild.target['platform'] == 'windows':
256 for lib in ['tier0', 'tier1', 'vstdlib', 'mathlib']:
257 libPath = os.path.join(sdkPath, 'lib', 'public', lib) + '.lib'
258 builder.RebuildIfNewer(libPath)
259 builder['POSTLINKFLAGS'].append(libPath)
261 def PostSetupHL2Job(self, job, builder, sdk):
262 if AMBuild.target['platform'] in ['linux', 'darwin']:
263 builder.AddObjectFiles(['tier1_i486.a', 'mathlib_i486.a'])
265 def DefaultHL2Compiler(self, path, sdk, noLink = False, oldMms = '-legacy'):
266 compiler = self.DefaultExtCompiler(path)
272 compiler['CXXINCLUDES'].append(os.path.join(self.mmsPath, mms))
273 compiler['CXXINCLUDES'].append(os.path.join(self.mmsPath, mms, 'sourcehook'))
276 compiler['CDEFINES'].extend(['SE_' + info[i]['name'] + '=' + info[i]['def'] for i in info])
278 paths = [['public'], ['public', 'engine'], ['public', 'mathlib'], ['public', 'vstdlib'],
279 ['public', 'tier0'], ['public', 'tier1']]
280 if sdk == 'ep1' or sdk == 'darkm':
281 paths.append(['public', 'dlls'])
282 paths.append(['game_shared'])
284 paths.append(['public', 'game', 'server'])
285 paths.append(['game', 'shared'])
286 paths.append(['common'])
288 info = self.sdkInfo[sdk]
289 sdkPath = AMBuild.cache[info['sdk']]
291 compiler['CDEFINES'].append('SOURCE_ENGINE=' + info['def'])
294 if AMBuild.target['platform'] == 'linux':
295 staticLibs = os.path.join(sdkPath, 'linux_sdk')
297 if AMBuild.target['platform'] == 'linux':
298 staticLibs = os.path.join(sdkPath, 'lib', 'linux')
299 elif AMBuild.target['platform'] == 'darwin':
300 staticLibs = os.path.join(sdkPath, 'lib', 'mac')
303 compiler['CXXINCLUDES'].append(os.path.join(sdkPath, *i))
306 if AMBuild.target['platform'] == 'linux':
307 compiler['POSTLINKFLAGS'][0:0] = ['-lm']
308 if sdk == 'ep2v' or sdk == 'l4d2':
309 compiler['POSTLINKFLAGS'][0:0] = ['libtier0.so']
310 compiler['POSTLINKFLAGS'][0:0] = ['libvstdlib.so']
312 compiler['POSTLINKFLAGS'][0:0] = ['tier0_i486.so']
313 compiler['POSTLINKFLAGS'][0:0] = ['vstdlib_i486.so']
314 elif AMBuild.target['platform'] == 'darwin':
315 compiler['POSTLINKFLAGS'][0:0] = ['libtier0.dylib']
316 compiler['POSTLINKFLAGS'][0:0] = ['libvstdlib.dylib']
325 AMBuild.Include(os.path.join('tools', 'buildbot', 'Versioning'), globals)
328 ['loader', 'AMBuilder'],
329 ['core', 'AMBuilder'],
330 ['core', 'logic', 'AMBuilder'],
331 ['extensions', 'bintools', 'AMBuilder'],
332 ['extensions', 'clientprefs', 'AMBuilder'],
333 ['extensions', 'cstrike', 'AMBuilder'],
334 ['extensions', 'curl', 'AMBuilder'],
335 ['extensions', 'geoip', 'AMBuilder'],
336 ['extensions', 'mysql', 'AMBuilder'],
337 ['extensions', 'sdktools', 'AMBuilder'],
338 ['extensions', 'topmenus', 'AMBuilder'],
339 ['extensions', 'updater', 'AMBuilder'],
340 ['extensions', 'sqlite', 'AMBuilder'],
341 ['extensions', 'regex', 'AMBuilder'],
342 ['extensions', 'tf2', 'AMBuilder'],
343 ['sourcepawn', 'jit', 'AMBuilder'],
344 ['sourcepawn', 'compiler', 'AMBuilder'],
345 ['plugins', 'AMBuilder'],
346 ['tools', 'buildbot', 'PackageScript']
349 for parts in FileList:
350 AMBuild.Include(os.path.join(*parts), globals)