-
Notifications
You must be signed in to change notification settings - Fork 1
/
SConstruct
390 lines (306 loc) · 11.9 KB
/
SConstruct
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
# -*- mode: python -*-
# DOOM build script
# TTimo <[email protected]>
# http://scons.sourceforge.net
import sys, os, time, commands, re, pickle, StringIO, popen2, commands, pdb, zipfile, string
import SCons
sys.path.append( 'sys/scons' )
import scons_utils
conf_filename='site.conf'
# choose configuration variables which should be saved between runs
# ( we handle all those as strings )
serialized=['CC', 'CXX', 'JOBS', 'BUILD', 'GL_HARDLINK',
'DEBUG_MEMORY', 'LIBC_MALLOC', 'ID_MCHECK', 'NOCURL',
'BUILD_ROOT', 'BASEFLAGS', 'SILENT', 'NO_GCH', 'OPENMP',
'TARGET_ARCH' ]
# ------------------------------------------------
# help -------------------------------------------
help_string = """
Usage: scons [OPTIONS] [TARGET] [CONFIG]
[OPTIONS] and [TARGET] are covered in command line options, use scons -H
[CONFIG]: KEY="VALUE" [...]
a number of configuration options saved between runs in the """ + conf_filename + """ file
erase """ + conf_filename + """ to start with default settings again
CC (default gcc)
CXX (default g++)
Specify C and C++ compilers (defaults gcc and g++)
ex: CC="gcc-3.3"
You can use ccache and distcc, for instance:
CC="ccache distcc gcc" CXX="ccache distcc g++"
JOBS (default 1)
Parallel build
BUILD (default debug)
Use debug-all/debug/release/profile to select build settings
ex: BUILD="release"
debug-all: no optimisations, debugging symbols
debug: -O -g
profile: -pg -fprofile-arcs (to produce gmon.out, which can be analyzed with gprof)
release: all optimisations, including CPU target etc.
BUILD_ROOT (default 'build')
change the build root directory
BASEFLAGS (default '')
Add compile flags
NOCONF (default 0, not saved)
ignore site configuration and use defaults + command line only
SILENT ( default 0, saved )
hide the compiler output, unless error
NO_GCH (default 0)
Don't use precompiled headers when building.
OPENMP (default 0)
Enable OpenMP builds.
TARGET_ARCH (default: "x86")
Build for either x86 or x64 architecture.
GL_HARDLINK (default 0)
Instead of dynamically loading the OpenGL libraries, use implicit dependencies
NOTE: no GL logging capability and no r_glDriver with GL_HARDLINK 1
DEBUG_MEMORY (default 0)
Enables memory logging to file
LIBC_MALLOC (default 1)
Toggle idHeap memory / libc malloc usage
When libc malloc is on, memory size statistics are wrong ( no _msize )
ID_MCHECK (default 2)
Perform heap consistency checking
0: on in Debug / off in Release
1 forces on, 2 forces off
note that Doom has it's own block allocator/checking
this should not be considered a replacement, but an additional tool
NOCURL (default 0)
set to 1 to disable usage of libcurl and http/ftp downloads feature
"""
Help( help_string )
# end help ---------------------------------------
# sanity -----------------------------------------
EnsureSConsVersion( 0, 96 )
# end sanity -------------------------------------
# system detection -------------------------------
# CPU type
cpu = commands.getoutput('uname -m')
exp = re.compile('.*i?86.*')
if exp.match(cpu):
cpu = 'x86'
else:
cpu = commands.getoutput('uname -p')
if ( cpu == 'powerpc' ):
cpu = 'ppc'
else:
cpu = 'cpu'
g_os = 'Linux'
# end system detection ---------------------------
# default settings -------------------------------
CC = 'gcc'
CXX = 'g++'
JOBS = '1'
BUILD = 'debug'
GL_HARDLINK = '0'
DEBUG_MEMORY = '0'
LIBC_MALLOC = '1'
ID_MCHECK = '2'
BUILD_ROOT = 'build'
NOCONF = '0'
NOCURL = '0'
BASEFLAGS = ''
SILENT = '0'
NO_GCH = '0'
OPENMP = '0'
TARGET_ARCH = 'x86'
# end default settings ---------------------------
# site settings ----------------------------------
if ( not ARGUMENTS.has_key( 'NOCONF' ) or ARGUMENTS['NOCONF'] != '1' ):
site_dict = {}
if (os.path.exists(conf_filename)):
site_file = open(conf_filename, 'r')
p = pickle.Unpickler(site_file)
site_dict = p.load()
print 'Loading build configuration from ' + conf_filename + ':'
for k, v in site_dict.items():
exec_cmd = k + '=\'' + v + '\''
print ' ' + exec_cmd
exec(exec_cmd)
else:
print 'Site settings ignored'
# end site settings ------------------------------
# command line settings --------------------------
for k in ARGUMENTS.keys():
exec_cmd = k + '=\'' + ARGUMENTS[k] + '\''
print 'Command line: ' + exec_cmd
exec( exec_cmd )
# stgatilov: avoid annoying human errors when you set target='x32'
# and get surprised that it does not build properly =)
if TARGET_ARCH == 'x32':
TARGET_ARCH = 'x86'
# end command line settings ----------------------
# save site configuration ----------------------
if ( not ARGUMENTS.has_key( 'NOCONF' ) or ARGUMENTS['NOCONF'] != '1' ):
for k in serialized:
exec_cmd = 'site_dict[\'' + k + '\'] = ' + k
exec(exec_cmd)
site_file = open(conf_filename, 'w')
p = pickle.Pickler(site_file)
p.dump(site_dict)
site_file.close()
# end save site configuration ------------------
# general configuration, target selection --------
g_build = BUILD_ROOT + '/scons_' + TARGET_ARCH + '/' + BUILD
#
# Use an absolute path to a single signature file to avoid a problem
# whereby everything gets rebuilt every time due to the signature file
# not being detected.
#
SConsignFile(os.path.join(Dir('#').abspath, 'scons.signatures'))
if ( GL_HARDLINK != '0' ):
g_build += '-hardlink'
if ( DEBUG_MEMORY != '0' ):
g_build += '-debugmem'
if ( LIBC_MALLOC != '1' ):
g_build += '-nolibcmalloc'
SetOption('num_jobs', JOBS)
LINK = CXX
# common flags
# BASE + CORE + OPT for engine
# BASE + GAME + OPT for game
# _noopt versions of the environements are built without the OPT
BASECPPFLAGS = [ ]
CORECPPPATH = [ ]
CORELIBPATH = [ ]
CORECPPFLAGS = [ ]
BASELINKFLAGS = [ ]
CORELINKFLAGS = [ ]
# for release build, further optimisations that may not work on all files
OPTCPPFLAGS = [ ]
BASECPPFLAGS.append( BASEFLAGS )
BASECPPFLAGS.append( '-pipe' )
# warn all
BASECPPFLAGS.append( '-Wall' )
BASECPPFLAGS.append( '-Wno-unknown-pragmas' ) # MSVC-specific pragmas
BASECPPFLAGS.append( '-Wno-unused-variable' ) # too many, often happens from commenting out code
BASECPPFLAGS.append( '-Wno-unused-but-set-variable' ) # useful for debugging, also may remain after commenting stuff
BASECPPFLAGS.append( '-Wno-sign-compare' ) # very nasty warning in the world of STL and size_t
# this define is necessary to make sure threading support is enabled in X
CORECPPFLAGS.append( '-DXTHREADS' )
# don't wrap gcc messages
BASECPPFLAGS.append( '-fmessage-length=0' )
# C++11 features
BASECPPFLAGS.append( '-std=c++14' )
# maintain this dangerous optimization off at all times
BASECPPFLAGS.append( '-fno-strict-aliasing' )
if ( g_os == 'Linux' ):
# use old ABI for std::string and std::list (which is not fully compliant with C++11 standard)
# this allows to run TDM binary on OSes which have old glibcxx (e.g. Ubuntu 14.04 from years 2014-2016)
BASECPPFLAGS.append( '-D_GLIBCXX_USE_CXX11_ABI=0' )
# gcc 4.x option only - only export what we mean to from the game SO
BASECPPFLAGS.append( '-fvisibility=hidden' )
# get the 64 bits machine on the distcc array to produce 32 bit binaries :)
if ( TARGET_ARCH == 'x86' ):
BASECPPFLAGS.append( '-m32' )
BASELINKFLAGS.append( '-m32' )
BASECPPFLAGS.append( '-msse2' );
if ( TARGET_ARCH == 'x64' ):
BASECPPFLAGS.append( '-m64' )
BASELINKFLAGS.append( '-m64' )
# current ffmpeg dep was built without -fPIC, so can't use position-independent code generation
BASELINKFLAGS.append( '-no-pie' )
if ( OPENMP != '0' ):
# openmp support for changes made to the renderer
BASECPPFLAGS.append( '-fopenmp' )
BASELINKFLAGS.append( '-fopenmp' )
if ( BUILD == 'debug-all' ):
OPTCPPFLAGS = [ '-g', '-D_DEBUG' ]
if ( ID_MCHECK == '0' ):
ID_MCHECK = '1'
elif ( BUILD == 'debug' ):
OPTCPPFLAGS = [ '-g', '-O1', '-D_DEBUG' ]
if ( ID_MCHECK == '0' ):
ID_MCHECK = '1'
elif ( BUILD == 'profile' ):
# -fprofile-arcs is needed for gcc 3.x and 4.x
OPTCPPFLAGS = [ '-pg', '-fprofile-arcs', '-ftest-coverage', '-O1', '-D_DEBUG' ]
BASELINKFLAGS.append( '-pg' );
BASELINKFLAGS.append( '-fprofile-arcs' );
if ( ID_MCHECK == '0' ):
ID_MCHECK = '1'
elif ( BUILD == 'release' ):
# -fomit-frame-pointer: not set because if prohibits debugging (which is necessary even on release build)
# -finline-functions: implicit at -O3
# -fschedule-insns2: implicit at -O2
# -fno-unsafe-math-optimizations: that should be on by default really. hit some wonko bugs in physics code because of that
OPTCPPFLAGS = [ '-g', '-O3', '-ffast-math', '-fno-unsafe-math-optimizations' ]
if ( ID_MCHECK == '0' ):
ID_MCHECK = '2'
else:
print 'Unknown build configuration ' + BUILD
sys.exit(0)
if ( GL_HARDLINK != '0' ):
CORECPPFLAGS.append( '-DID_GL_HARDLINK' )
if ( DEBUG_MEMORY != '0' ):
BASECPPFLAGS += [ '-DID_DEBUG_MEMORY', '-DID_REDIRECT_NEWDELETE' ]
if ( LIBC_MALLOC != '1' ):
BASECPPFLAGS.append( '-DUSE_LIBC_MALLOC=0' )
if ( ID_MCHECK == '1' ):
BASECPPFLAGS.append( '-DID_MCHECK' )
# create the build environements
g_env_base = Environment( ENV = os.environ, CC = CC, CXX = CXX, LINK = LINK, CPPFLAGS = BASECPPFLAGS, LINKFLAGS = BASELINKFLAGS, CPPPATH = CORECPPPATH, LIBPATH = CORELIBPATH )
scons_utils.SetupUtils( g_env_base )
g_env_base.Prepend(CPPPATH=['.'])
path_template = '#/ThirdParty/artefacts/{0}/include'
g_env_base.Append(CPPPATH = path_template.format('zlib'))
g_env_base.Append(CPPPATH = path_template.format('libcurl'))
g_env_base.Append(CPPPATH = path_template.format('openal'))
g_env_base.Append(CPPPATH = path_template.format('ogg'))
g_env_base.Append(CPPPATH = path_template.format('vorbis'))
g_env_base.Append(CPPPATH = path_template.format('devil'))
g_env_base.Append(CPPPATH = path_template.format('libjpeg'))
g_env_base.Append(CPPPATH = path_template.format('ffmpeg'))
g_env_base.Append(CPPPATH = path_template.format('doctest'))
g_env_base.Append(CPPPATH = path_template.format('pugixml'))
g_env_base.Append(CPPPATH = '#/renderer')
g_env_base.Append(CPPPATH = '#/')
g_env_base['CPPFLAGS'] += OPTCPPFLAGS
g_env_base['CPPFLAGS'] += CORECPPFLAGS
g_env_base['LINKFLAGS'] += CORELINKFLAGS
#if ( int(JOBS) > 1 ):
# print 'Using buffered process output'
# silent = False
# if ( SILENT == '1' ):
# silent = True
# scons_utils.SetupBufferedOutput( g_env, silent )
# scons_utils.SetupBufferedOutput( g_game_env, silent )
# mark the globals
# curl usage. there is a global toggle flag
local_curl = 0
curl_lib = []
GLOBALS = 'g_env_base g_os ID_MCHECK curl_lib local_curl NO_GCH TARGET_ARCH'
# end general configuration ----------------------
# targets ----------------------------------------
Export( 'GLOBALS ' + GLOBALS )
thedarkmod = None
# insert SVN revision number into header (requires svnversion)
# svnversion must be run from SVN root, otherwise revision information may be incomplete
os.chdir(Dir('#').abspath)
svnversion_command = r'sed "s/\!SVNVERSION\!/$(svnversion -c)/g" idlib/svnversion_template.h >idlib/svnversion.h'
if os.system(svnversion_command) != 0:
exit()
print("Inserted SVN revision number into svnversion.h")
# build curl if needed
if ( NOCURL == '0' ):
# 1: debug, 2: release
if ( BUILD == 'release' ):
local_curl = 2
else:
local_curl = 1
Export( 'GLOBALS ' + GLOBALS )
if ( TARGET_ARCH == 'x86' ):
curl_lib = [ '#linux/libcurl/libcurl.a' ] # Use the static one built for TDM
if ( TARGET_ARCH == 'x64' ):
curl_lib = [ '#linux/libcurl/lib64/libcurl.a' ]
VariantDir( g_build + '/core', '.', duplicate = 0 )
thedarkmod = SConscript( g_build + '/core/sys/scons/SConscript.darkmod' )
exe_name = 'thedarkmod.' + ('x64' if TARGET_ARCH == 'x64' else cpu)
# Note: this target only runs if you append ".." (without quotes) as the last argument to scons command line
# It copies executable into ../darkmod, which is default location of darkmod installation in development environment
InstallAs( '../darkmod/' + exe_name, thedarkmod )
# this runs always and produces TDM binary in local directory
if ( BUILD == 'release' ): # strip debug info in release
Command(exe_name, thedarkmod, "strip $SOURCE -o $TARGET")
else:
InstallAs( '#' + exe_name, thedarkmod )
# end targets ------------------------------------