root/cafu/trunk/SConstruct

Revision 467, 19.8 KB (checked in by Carsten, 3 weeks ago)

Update the SConstruct build script to automatically take all games in the Games/ directory into account, rather than only the previously hard-wired ones.

References #93.
Closes #94.

Thanks to Haimi for the report!

Line 
1import os, platform, shutil, sys
2
3
4# See the SCons manual, http://www.scons.org/wiki/GoFastButton and the man page for more information about the next two lines.
5Decider("MD5-timestamp")
6SetOption("implicit_cache", 1)
7
8# Print an empty line, so that there is a better visual separation at the command line between successive calls.
9print ""
10
11
12try:
13    import CompilerSetup
14except ImportError:
15    # In order to make getting started with the Cafu source code more convenient, install the
16    # CompilerSetup.py file from the related template file (which is under version control) automatically.
17    shutil.copy("CompilerSetup.py.tmpl", "CompilerSetup.py")
18    import CompilerSetup
19
20# Import the (user-configured) base environment from the setup file.
21# The base environment is evaluated and further refined (e.g. with compiler-specific settings) below.
22envCommon=CompilerSetup.envCommon;
23
24
25# This big if-else tree has a branch for each supported platform and each supported compiler.
26# For the chosen combination of platform and compiler, it prepares the environments envDebug, envRelease and envProfile.
27if sys.platform=="win32":
28    # Under Windows, there are no system copies of these libraries, so instead we use our own local copies.
29    # Setting these paths in envCommon means that they are "globally" available everywhere, but this is ok:
30    # Under Linux, all library headers are globally available (e.g. at /usr/include/) as well.
31    envCommon.Append(CPPPATH=["#/ExtLibs/freetype/include"])
32    envCommon.Append(CPPPATH=["#/ExtLibs/libpng"])
33    envCommon.Append(CPPPATH=["#/ExtLibs/zlib"])
34
35    if envCommon["MSVC_VERSION"] in ["8.0", "8.0Exp"]:
36        ##############################
37        ### Win32, Visual C++ 2005 ###
38        ##############################
39
40        compiler="vc8"
41
42        # Reference of commonly used compiler switches:
43        # /EHsc  Enable exception handling.
44        # /GR    Enable RTTI.
45        # /J     Treat char as unsigned char.
46        # /MT    Use multi-threaded run-time libraries (statically linked into the exe). Defines _MT.
47        # /MTd   Use multi-threaded debug run-time libraries (statically linked into the exe). Defines _DEBUG and _MT.
48        # /Od    Disable optimizations.
49        # /O2    Fastest possible code.
50        # /Ob2   Inline expansion at compilers discretion.
51        # /RTC1  Run-Time Error Checks: Catch release-build errors in debug build.
52        # /W3    Warning level.
53        # /WX    Treat warnings as errors.
54        # /Z7    Include full debug info.
55
56        # Begin with an environment with settings that are common for debug, release and profile builds.
57        envCommon.Append(CCFLAGS = Split("/GR /EHsc"))   # CCFLAGS is also taken as the default value for CXXFLAGS.
58        envCommon.Append(CPPDEFINES = ["_CRT_SECURE_NO_DEPRECATE", "_CRT_NONSTDC_NO_DEPRECATE"])
59        envCommon.Append(LINKFLAGS = Split("/incremental:no"))
60
61        # Explicitly instruct SCons to detect and use the Microsoft Platform SDK, as it is not among the default tools.
62        # See thread "Scons 2010/01/17 doesn't look for MS SDK?" at <http://scons.tigris.org/ds/viewMessage.do?dsForumId=1272&dsMessageId=2455554>
63        # for further information.
64        envCommon.Tool('mssdk')
65
66        # Environment for debug builds:
67        envDebug=envCommon.Clone();
68        envDebug.Append(CCFLAGS=Split("/MDd /Od /Z7 /RTC1"));
69        envDebug.Append(LINKFLAGS=["/debug"]);
70
71        # Environment for release builds:
72        envRelease=envCommon.Clone();
73        envRelease.Append(CCFLAGS=Split("/MD /O2 /Ob2"));
74
75        # Environment for profile builds:
76        envProfile=envCommon.Clone();
77        envProfile.Append(CCFLAGS=Split("/MD /O2 /Ob2 /Z7"));
78        envProfile.Append(LINKFLAGS=["/fixed:no", "/debug"]);
79
80    elif envCommon["MSVC_VERSION"] in ["9.0", "9.0Exp"]:
81        ##############################
82        ### Win32, Visual C++ 2008 ###
83        ##############################
84
85        compiler="vc9"
86
87        # Reference of commonly used compiler switches:
88        # Identical to the compiler switches for Visual C++ 2005, see there for more details.
89
90        # Begin with an environment with settings that are common for debug, release and profile builds.
91        envCommon.Append(CCFLAGS = Split("/GR /EHsc"))   # CCFLAGS is also taken as the default value for CXXFLAGS.
92        envCommon.Append(CPPDEFINES = ["_CRT_SECURE_NO_DEPRECATE", "_CRT_NONSTDC_NO_DEPRECATE"])
93        envCommon.Append(LINKFLAGS = Split("/incremental:no"))
94
95        # Explicitly instruct SCons to detect and use the Microsoft Platform SDK, as it is not among the default tools.
96        # See thread "Scons 2010/01/17 doesn't look for MS SDK?" at <http://scons.tigris.org/ds/viewMessage.do?dsForumId=1272&dsMessageId=2455554>
97        # for further information.
98        envCommon.Tool('mssdk')
99
100        # This is a temporary workaround for SCons bug <http://scons.tigris.org/issues/show_bug.cgi?id=2663>.
101        # It should be removed again as soon as the bug is fixed in SCons.
102        if envCommon["TARGET_ARCH"] in ["x86_64", "amd64", "emt64"]:
103            envCommon["ENV"]["LIB"] = envCommon["ENV"]["LIB"].replace("C:\\Program Files\\Microsoft SDKs\\Windows\\v7.0\\lib;", "C:\\Program Files\\Microsoft SDKs\\Windows\\v7.0\\lib\\x64;");
104            envCommon["ENV"]["LIBPATH"] = envCommon["ENV"]["LIBPATH"].replace("C:\\Program Files\\Microsoft SDKs\\Windows\\v7.0\\lib;", "C:\\Program Files\\Microsoft SDKs\\Windows\\v7.0\\lib\\x64;");
105
106        # Environment for debug builds:
107        envDebug=envCommon.Clone();
108        envDebug.Append(CCFLAGS=Split("/MDd /Od /Z7 /RTC1"));
109        envDebug.Append(LINKFLAGS=["/debug"]);
110
111        # Environment for release builds:
112        envRelease=envCommon.Clone();
113        envRelease.Append(CCFLAGS=Split("/MD /O2 /Ob2"));
114
115        # Environment for profile builds:
116        envProfile=envCommon.Clone();
117        envProfile.Append(CCFLAGS=Split("/MD /O2 /Ob2 /Z7"));
118        envProfile.Append(LINKFLAGS=["/fixed:no", "/debug"]);
119
120    elif envCommon["MSVC_VERSION"] in ["10.0", "10.0Exp"]:
121        ##############################
122        ### Win32, Visual C++ 2010 ###
123        ##############################
124
125        compiler="vc10"
126
127        # Reference of commonly used compiler switches:
128        # Identical to the compiler switches for Visual C++ 2005, see there for more details.
129
130        # Begin with an environment with settings that are common for debug, release and profile builds.
131        envCommon.Append(CCFLAGS = Split("/GR /EHsc"))   # CCFLAGS is also taken as the default value for CXXFLAGS.
132        envCommon.Append(CPPDEFINES = ["_CRT_SECURE_NO_DEPRECATE", "_CRT_NONSTDC_NO_DEPRECATE"])
133        envCommon.Append(LINKFLAGS = Split("/incremental:no"))
134
135        # Explicitly instruct SCons to detect and use the Microsoft Platform SDK, as it is not among the default tools.
136        # See thread "Scons 2010/01/17 doesn't look for MS SDK?" at <http://scons.tigris.org/ds/viewMessage.do?dsForumId=1272&dsMessageId=2455554>
137        # for further information.
138        envCommon.Tool('mssdk')
139
140        # Environment for debug builds:
141        envDebug=envCommon.Clone();
142        envDebug.Append(CCFLAGS=Split("/MDd /Od /Z7 /RTC1"));
143        envDebug.Append(LINKFLAGS=["/debug"]);
144
145        # Environment for release builds:
146        envRelease=envCommon.Clone();
147        envRelease.Append(CCFLAGS=Split("/MD /O2 /Ob2"));
148
149        # Environment for profile builds:
150        envProfile=envCommon.Clone();
151        envProfile.Append(CCFLAGS=Split("/MD /O2 /Ob2 /Z7"));
152        envProfile.Append(LINKFLAGS=["/fixed:no", "/debug"]);
153
154    else:
155        ###############################
156        ### Win32, unknown compiler ###
157        ###############################
158
159        print "Unknown compiler on platform " + sys.platform + "."
160        exit
161
162elif sys.platform=="linux2":
163    ErrorMsg = "Please install the %s library (development files)!\nOn many systems, the required package is named %s (possibly with a different version number)."
164    conf = Configure(envCommon)
165
166    # conf.CheckLib(...)    # See http://www.cafu.de/wiki/cppdev:gettingstarted#linux_packages for additional libraries and headers that should be checked here.
167
168    #if not conf.CheckLibWithHeader("freetype", "ft2build.h", "c"):     # TODO: What is the proper way to check for freetype?
169        #print ErrorMsg % ("freetype", "libfreetype6-dev")
170        #Exit(1)
171
172    if not conf.CheckLibWithHeader("png", "png.h", "c"):
173        print ErrorMsg % ("png", "libpng12-dev")
174        Exit(1)
175
176    if not conf.CheckLibWithHeader("z", "zlib.h", "c"):
177        print ErrorMsg % ("zlib", "zlib1g-dev")
178        Exit(1)
179
180    envCommon = conf.Finish()
181
182    if envCommon["CXX"]=="g++":
183        ##################
184        ### Linux, g++ ###
185        ##################
186
187        compiler="g++"
188
189        # Begin with an environment with settings that are common for debug, release and profile builds.
190        envCommon.Append(CCFLAGS = Split(""))   # CCFLAGS is also taken as the default value for CXXFLAGS.
191
192        # Environment for debug builds:
193        envDebug=envCommon.Clone();
194        envDebug.Append(CCFLAGS=["-g"]);
195
196        # Environment for release builds:
197        envRelease=envCommon.Clone();
198        envRelease.Append(CCFLAGS=["-O3"]);
199        envRelease.Append(LINKFLAGS=["-Wl,--strip-all"]);  # Reduce file size, and keep nosy people from printing our symbol names (e.g. with strings -a).
200
201        # Environment for profile builds:
202        envProfile=envCommon.Clone();
203        envProfile.Append(CCFLAGS=["-O3", "-g"]);
204
205    else:
206        ###############################
207        ### Linux, unknown compiler ###
208        ###############################
209
210        print "Unknown compiler " + envCommon["CXX"] + " on platform " + sys.platform + "."
211        exit
212
213else:
214    print "Unknown platform '" + sys.platform + "'."
215    exit
216
217envDebug  .Append(CPPDEFINES=["DEBUG"]);
218envRelease.Append(CPPDEFINES=["NDEBUG"]);   # Need NDEBUG to have the assert macro generate no runtime code.
219envProfile.Append(CPPDEFINES=["NDEBUG"]);   # Need NDEBUG to have the assert macro generate no runtime code.
220
221
222####################################
223### Build all external libraries ###
224####################################
225
226# Set the list of variants (debug, profile, release) that should be built.
227BVs=ARGUMENTS.get("bv", CompilerSetup.buildVariants)
228
229# Set the build directories.
230my_build_dir="build/"+sys.platform+"/"+compiler
231if envCommon["TARGET_ARCH"]: my_build_dir += "/"+envCommon["TARGET_ARCH"];
232
233my_build_dir_dbg=my_build_dir+"/debug"
234my_build_dir_rel=my_build_dir+"/release"
235my_build_dir_prf=my_build_dir+"/profile"
236
237
238ExtLibsList = ["bullet",
239               "freealut",
240               "freetype",
241               "jpeg",
242               "libogg",
243               "libpng",
244               "libvorbis",
245               "lwo",
246               "lua",
247               "minizip",
248               "mpg123",
249               "noise",
250               "openal-soft",
251               "zlib"]
252
253if sys.platform=="win32":
254    ExtLibsList.remove("openal-soft")   # OpenAL-Soft is not built on Windows, use the OpenAL Windows SDK there.
255else:   # sys.platform=="linux2"
256    ExtLibsList.remove("freetype")      # We use the system copies of these libraries.
257    ExtLibsList.remove("libpng")
258    ExtLibsList.remove("zlib")
259
260for lib_name in ExtLibsList:
261    s_name=lib_name
262
263    if lib_name=="bullet": s_name+="/src";
264    if lib_name=="lua":    s_name+="/src";
265    if lib_name=="mpg123": s_name+="/src/libmpg123";
266
267    if "d" in BVs: SConscript("ExtLibs/"+s_name+"/SConscript", exports={ "env": envDebug },   variant_dir="ExtLibs/"+lib_name+"/"+my_build_dir_dbg, duplicate=0)
268    if "r" in BVs: SConscript("ExtLibs/"+s_name+"/SConscript", exports={ "env": envRelease }, variant_dir="ExtLibs/"+lib_name+"/"+my_build_dir_rel, duplicate=0)
269    if "p" in BVs: SConscript("ExtLibs/"+s_name+"/SConscript", exports={ "env": envProfile }, variant_dir="ExtLibs/"+lib_name+"/"+my_build_dir_prf, duplicate=0)
270
271
272# Compile wxWidgets for the current platform.
273if sys.platform=="win32":
274    if compiler.startswith("vc"):
275        # If we target a non-x86 architecture, the Makefiles automatically append a suffix to the directory names (no need to tweak COMPILER_PREFIX).
276        if   envCommon["TARGET_ARCH"] in ["x86_64", "amd64", "emt64"]: target_cpu=" TARGET_CPU=AMD64"
277        elif envCommon["TARGET_ARCH"] in ["ia64"]:                     target_cpu=" TARGET_CPU=IA64"
278        else:                                                          target_cpu=""
279
280        result=envDebug.  Execute("nmake /nologo /f makefile.vc BUILD=debug   SHARED=0 COMPILER_PREFIX="+compiler+target_cpu, chdir="ExtLibs/wxWidgets/build/msw");
281        if (result!=0): envDebug.  Exit(result);
282        result=envRelease.Execute("nmake /nologo /f makefile.vc BUILD=release SHARED=0 COMPILER_PREFIX="+compiler+target_cpu, chdir="ExtLibs/wxWidgets/build/msw");
283        if (result!=0): envRelease.Exit(result);
284        print "";   # Print just another empty line for better visual separation.
285
286elif sys.platform=="linux2":
287    # This automatic compilation of wxGTK requires that some library packages have been installed already,
288    # e.g. libgtk2.0-dev, libgl1-mesa-dev and libglu1-mesa-dev under Ubuntu 8.04.
289    # See the documentation at http://www.cafu.de/wiki/ for more details!
290    if not os.path.exists("ExtLibs/wxWidgets/build-gtk/make-ok-flag"):
291        envRelease.Execute(Mkdir("ExtLibs/wxWidgets/build-gtk"));
292        result=envRelease.Execute("../configure --with-gtk --disable-shared --without-libtiff --disable-pnm --disable-pcx --disable-iff --with-opengl --with-regex=builtin --disable-compat26 --disable-compat28", chdir="ExtLibs/wxWidgets/build-gtk");
293        if (result!=0): envRelease.Exit(result);
294        result=envRelease.Execute("make && touch make-ok-flag", chdir="ExtLibs/wxWidgets/build-gtk");
295        if (result!=0): envRelease.Exit(result);
296
297
298######################################
299### Install the external libraries ###
300######################################
301
302# "Install" (copy) all DLLs that are required at run-time into the main Cafu directory.
303# Some of them are self-built, others are provided ready-to-use by the vendor.
304#
305# They should work for the respective OS (.dll on Windows, .so on Linux) with all supported
306# compilers and build variants (debug, profile, release): All interfaces are pure C, no C++,
307# with the proper calling conventions etc. Therefore, matching the precise DLL built variant
308# with that of the main Cafu executable is not necessary, and overwriting (some of) these
309# DLLs with their debug build variants for debugging should not be a problem.
310#
311# We use release builds whenever we can, and assume that if the user has disabled them,
312# debug builds are available (i.e. the code below fails if neither "d" nor "r" is in BVs).
313if sys.platform=="win32":
314    if envCommon["TARGET_ARCH"]=="x86":
315        envRelease.Install(".", ["#/ExtLibs/Cg/bin/cg.dll", "#/ExtLibs/Cg/bin/cgGL.dll"]);
316        envRelease.Install(".", ["#/ExtLibs/openal-win/libs/Win32/OpenAL32.dll", "#/ExtLibs/openal-win/libs/Win32/wrap_oal.dll"]);
317        envRelease.Install(".", ["#/ExtLibs/fmod/api/fmod.dll"]);
318    else:
319        envRelease.Install(".", ["#/ExtLibs/Cg/bin.x64/cg.dll", "#/ExtLibs/Cg/bin.x64/cgGL.dll"]);
320        envRelease.Install(".", ["#/ExtLibs/openal-win/libs/Win64/OpenAL32.dll", "#/ExtLibs/openal-win/libs/Win64/wrap_oal.dll"]);
321
322elif sys.platform=="linux2":
323    if platform.machine()!="x86_64":
324        envRelease.Install(".", ["#/ExtLibs/Cg/lib/libCg.so", "#/ExtLibs/Cg/lib/libCgGL.so"]);
325        envRelease.Install(".", ["#/ExtLibs/fmod/api/libfmod-3.75.so"]);
326    else:
327        envRelease.Install(".", ["#/ExtLibs/Cg/lib.x64/libCg.so", "#/ExtLibs/Cg/lib.x64/libCgGL.so"]);
328
329
330############################################
331### Update the construction environments ###
332############################################
333
334# Note that modifying the original environments here affects the build of the external libraries above!
335envDebug_Cafu  =envDebug.Clone();
336envRelease_Cafu=envRelease.Clone();
337envProfile_Cafu=envProfile.Clone();
338
339envDebug_Cafu  .Append(CPPDEFINES=[("SCONS_BUILD_DIR", my_build_dir_dbg)]);
340envRelease_Cafu.Append(CPPDEFINES=[("SCONS_BUILD_DIR", my_build_dir_rel)]);
341envProfile_Cafu.Append(CPPDEFINES=[("SCONS_BUILD_DIR", my_build_dir_prf)]);
342
343envDebug_Cafu  .Append(CPPPATH=["#/Libs", "#/ExtLibs"]);
344envRelease_Cafu.Append(CPPPATH=["#/Libs", "#/ExtLibs"]);
345envProfile_Cafu.Append(CPPPATH=["#/Libs", "#/ExtLibs"]);
346
347envDebug_Cafu  .Append(LIBPATH=["#/ExtLibs/"+lib_name+"/"+my_build_dir_dbg for lib_name in ExtLibsList] + ["#/Libs/"+my_build_dir_dbg]);
348envRelease_Cafu.Append(LIBPATH=["#/ExtLibs/"+lib_name+"/"+my_build_dir_rel for lib_name in ExtLibsList] + ["#/Libs/"+my_build_dir_rel]);
349envProfile_Cafu.Append(LIBPATH=["#/ExtLibs/"+lib_name+"/"+my_build_dir_prf for lib_name in ExtLibsList] + ["#/Libs/"+my_build_dir_prf]);
350
351if compiler=="vc8":
352    envDebug_Cafu  .Append(CCFLAGS=Split("/J /W3 /WX"));
353    envRelease_Cafu.Append(CCFLAGS=Split("/J /W3 /WX"));
354    envProfile_Cafu.Append(CCFLAGS=Split("/J /W3 /WX"));
355
356elif compiler=="vc9":
357    envDebug_Cafu  .Append(CCFLAGS=Split("/J /W3 /WX"));
358    envRelease_Cafu.Append(CCFLAGS=Split("/J /W3 /WX"));
359    envProfile_Cafu.Append(CCFLAGS=Split("/J /W3 /WX"));
360
361elif compiler=="vc10":
362    envDebug_Cafu  .Append(CCFLAGS=Split("/J /W3 /WX"));
363    envRelease_Cafu.Append(CCFLAGS=Split("/J /W3 /WX"));
364    envProfile_Cafu.Append(CCFLAGS=Split("/J /W3 /WX"));
365
366elif compiler=="g++":
367    envDebug_Cafu  .Append(CCFLAGS=Split("-funsigned-char -Wall -Werror -Wno-char-subscripts"));
368    envRelease_Cafu.Append(CCFLAGS=Split("-funsigned-char -Wall -Werror -Wno-char-subscripts -fno-strict-aliasing"));
369    envProfile_Cafu.Append(CCFLAGS=Split("-funsigned-char -Wall -Werror -Wno-char-subscripts -fno-strict-aliasing"));
370
371
372###########################
373### Build all Cafu code ###
374###########################
375
376if os.path.exists("Libs/SConscript"):
377    # Build everything in the Libs/ directory.
378    if "d" in BVs: buildMode = "dbg"; SConscript('Libs/SConscript', exports=[{'env':envDebug_Cafu},   'buildMode'], variant_dir="Libs/"+my_build_dir_dbg, duplicate=0)
379    if "r" in BVs: buildMode = "rel"; SConscript('Libs/SConscript', exports=[{'env':envRelease_Cafu}, 'buildMode'], variant_dir="Libs/"+my_build_dir_rel, duplicate=0)
380    if "p" in BVs: buildMode = "prf"; SConscript('Libs/SConscript', exports=[{'env':envProfile_Cafu}, 'buildMode'], variant_dir="Libs/"+my_build_dir_prf, duplicate=0)
381
382if os.path.exists("SConscript"):
383    # Build the Cafu executables.
384    if "d" in BVs: buildMode = "dbg"; SConscript('SConscript', exports=[{'env':envDebug_Cafu},   'buildMode', 'compiler'], variant_dir=""+my_build_dir_dbg, duplicate=0)
385    if "r" in BVs: buildMode = "rel"; SConscript('SConscript', exports=[{'env':envRelease_Cafu}, 'buildMode', 'compiler'], variant_dir=""+my_build_dir_rel, duplicate=0)
386    if "p" in BVs: buildMode = "prf"; SConscript('SConscript', exports=[{'env':envProfile_Cafu}, 'buildMode', 'compiler'], variant_dir=""+my_build_dir_prf, duplicate=0)
387
388# Build the game DLLs.
389for GameName in os.listdir("Games/"):
390    CodeDir = "Games/" + GameName + "/Code/"
391
392    if os.path.exists(CodeDir + "SConscript"):
393        if "d" in BVs: buildMode = "dbg"; SConscript(CodeDir + "SConscript", exports=[{'env':envDebug_Cafu},   'buildMode'], variant_dir=CodeDir + my_build_dir_dbg, duplicate=0)
394        if "r" in BVs: buildMode = "rel"; SConscript(CodeDir + "SConscript", exports=[{'env':envRelease_Cafu}, 'buildMode'], variant_dir=CodeDir + my_build_dir_rel, duplicate=0)
395        if "p" in BVs: buildMode = "prf"; SConscript(CodeDir + "SConscript", exports=[{'env':envProfile_Cafu}, 'buildMode'], variant_dir=CodeDir + my_build_dir_prf, duplicate=0)
Note: See TracBrowser for help on using the browser.