Fix the debug build on linux.
[dolphin.git] / SConstruct
blob64669145bdc4b100945a1f279e76bc4c11f2b92d
1 # -*- python -*-
3 import os
4 import sys
5 import platform
7 # Home made tests
8 from SconsTests import utils
9 from SconsTests import wxconfig
11 # Some features need at least SCons 1.2
12 EnsureSConsVersion(1, 2)
14 # Construction presets for platform
15 env = Environment(ENV = os.environ)
17 # Handle command line options
18 vars = Variables('args.cache')
20 vars.AddVariables(
21 BoolVariable('verbose', 'Set to show compilation lines', False),
22 BoolVariable('bundle', 'Set to create distribution bundle', False),
23 BoolVariable('lint', 'Set for lint build (fail on warnings)', False),
24 BoolVariable('nowx', 'Set for building without wxWidgets', False),
25 PathVariable('wxconfig', 'Path to wxconfig', None),
26 EnumVariable('flavor', 'Choose a build flavor', 'release', allowed_values =
27 ('release','devel','debug','fastlog','prof'), ignorecase = 2),
30 if env['PLATFORM'] == 'posix': vars.AddVariables(
31 PathVariable('destdir', 'Temporary install location (for package building)',
32 None, PathVariable.PathAccept),
33 EnumVariable('install', 'Choose a local or global installation', 'local',
34 allowed_values = ('local', 'global'), ignorecase = 2),
35 PathVariable('prefix', 'Installation prefix (only used for a global build)',
36 '/usr', PathVariable.PathAccept),
37 PathVariable('userdir', 'Set the name of the user data directory in home',
38 '.dolphin-emu', PathVariable.PathAccept),
39 BoolVariable('opencl', 'Build with OpenCL', False),
40 EnumVariable('pgo', 'Profile-Guided Optimization (generate or use)', 'none',
41 allowed_values = ('none', 'generate', 'use'), ignorecase = 2),
42 BoolVariable('shared_glew', 'Use system shared libGLEW', True),
43 BoolVariable('shared_lzo', 'Use system shared liblzo2', True),
44 BoolVariable('shared_sdl', 'Use system shared libSDL', True),
45 BoolVariable('shared_sfml', 'Use system shared libsfml-network', True),
46 BoolVariable('shared_soil', 'Use system shared libSOIL', True),
47 BoolVariable('shared_zlib', 'Use system shared libz', True),
48 PathVariable('CC', 'The C compiler', 'gcc', PathVariable.PathAccept),
49 PathVariable('CXX', 'The C++ compiler', 'g++', PathVariable.PathAccept),
52 # Save the given command line options
53 vars.Update(env)
54 vars.Save('args.cache', env)
56 # Die on unknown variables
57 unknown = vars.UnknownVariables()
58 if unknown:
59 print "Unknown variables:", unknown.keys()
60 Exit(1)
62 # Verbose compile
63 if not env['verbose']:
64 env['ARCOMSTR'] = "Archiving $TARGET"
65 env['ASCOMSTR'] = "Assembling $TARGET"
66 env['ASPPCOMSTR'] = "Assembling $TARGET"
67 env['CCCOMSTR'] = "Compiling $TARGET"
68 env['CXXCOMSTR'] = "Compiling $TARGET"
69 env['LINKCOMSTR'] = "Linking $TARGET"
70 env['RANLIBCOMSTR'] = "Indexing $TARGET"
71 env['SHCCCOMSTR'] = "Compiling $TARGET"
72 env['SHCXXCOMSTR'] = "Compiling $TARGET"
73 env['SHLINKCOMSTR'] = "Linking $TARGET"
74 env['TARCOMSTR'] = "Creating $TARGET"
76 if not env['flavor'] == 'debug':
77 env['CCFLAGS'] += ['-O3']
78 if env['flavor'] == 'release':
79 env['CCFLAGS'] += ['-fomit-frame-pointer']
80 elif not env['flavor'] == 'fastlog':
81 env['CCFLAGS'] += ['-ggdb']
82 env['CCFLAGS'] += ['-fno-exceptions', '-fno-strict-aliasing']
83 if env['CCVERSION'] >= '4.2.0':
84 env['CCFLAGS'] += ['-fvisibility=hidden']
85 env['CXXFLAGS'] += ['-fvisibility-inlines-hidden']
87 if env['lint']:
88 env['CCFLAGS'] += ['-Werror']
89 env['CCFLAGS'] += ['-Wall', '-Wextra']
90 env['CCFLAGS'] += ['-Wno-missing-field-initializers', '-Wno-unused-parameter']
91 env['CCFLAGS'] += ['-Wpacked', '-Wpointer-arith', '-Wshadow', '-Wwrite-strings']
92 if env['CCVERSION'] < '4.2.0':
93 env['CCFLAGS'] += ['-Wno-pragmas']
94 if env['CCVERSION'] >= '4.3.0':
95 env['CCFLAGS'] += ['-Wno-array-bounds', '-Wno-unused-result']
97 env['CPPDEFINES'] = []
98 if env['flavor'] == 'debug':
99 env['CPPDEFINES'] += ['_DEBUG']
100 if sys.platform == 'linux2':
101 # FIXME: This disables wx debugging how do we make it work?
102 env['CPPDEFINES'] += ['NDEBUG']
103 elif env['flavor'] == 'fastlog':
104 env['CPPDEFINES'] += ['DEBUGFAST']
105 env['CPPPATH'] = ['#Source/PluginSpecs']
106 env['LIBPATH'] = []
107 env['LIBS'] = []
109 # Object files
110 env['build_dir'] = 'Build' + os.sep + platform.system() + \
111 '-' + platform.machine() + '-' + env['flavor']
113 # Static libs go here
114 env['local_libs'] = '#' + env['build_dir'] + os.sep + 'libs' + os.sep
116 # Default install path
117 if not env.has_key('install') or env['install'] == 'local':
118 env['prefix'] = 'Binary' + os.sep + platform.system() + \
119 '-' + platform.machine()
120 if env['flavor'] == 'debug':
121 env['prefix'] += '-debug'
122 elif env['flavor'] == 'prof':
123 env['prefix'] += '-prof'
125 rev = utils.GenerateRevFile(env['flavor'], '.', None)
127 # OS X specifics
128 if sys.platform == 'darwin':
129 ccld = ['-arch', 'x86_64', '-arch', 'i386', '-mmacosx-version-min=10.5']
130 env['CCFLAGS'] += ccld
131 env['CCFLAGS'] += ['-msse3']
132 env['CC'] = "gcc-4.2 -ObjC"
133 env['CXX'] = "g++-4.2 -ObjC++"
134 #env['FRAMEWORKPATH'] += [
135 # '/Developer/SDKs/MacOSX10.6.sdk/System/Library/Frameworks',
136 # '/Developer/SDKs/MacOSX10.5.sdk/System/Library/Frameworks']
137 env['FRAMEWORKS'] += ['AppKit', 'CoreFoundation', 'CoreServices']
138 env['FRAMEWORKS'] += ['AudioUnit', 'CoreAudio']
139 env['FRAMEWORKS'] += ['IOBluetooth', 'IOKit', 'OpenGL']
140 #env['LIBPATH'] += ['/Developer/SDKs/MacOSX10.5.sdk/usr/lib']
141 env['LIBS'] = ['gcc_s.10.5', 'iconv'] # , 'stdc++-static'] # XXX
142 env['LINKFLAGS'] += ccld
143 env['LINKFLAGS'] += ['-Wl,-search_paths_first', '-Wl,-Z']
144 env['LINKFLAGS'] += ['-L/Developer/SDKs/MacOSX10.5.sdk/usr/lib',
145 '-F/Developer/SDKs/MacOSX10.5.sdk/System/Library/Frameworks',
146 '-F/Developer/SDKs/MacOSX10.6.sdk/System/Library/Frameworks']
148 if platform.mac_ver()[0] < '10.6.0':
149 env['HAVE_OPENCL'] = 0
150 else:
151 env['CCFLAGS'] += ['-Wextra-tokens', '-Wnewline-eof']
152 env['HAVE_OPENCL'] = 1
153 env['FRAMEWORKSFLAGS'] = ['-weak_framework', 'OpenCL']
155 if env['nowx']:
156 env['HAVE_WX'] = 0
157 else:
158 wxenv = env.Clone(LIBPATH = '')
159 conf = wxenv.Configure(conf_dir = None, log_file = None,
160 custom_tests = {'CheckWXConfig' : wxconfig.CheckWXConfig})
161 env['HAVE_WX'] = \
162 conf.CheckWXConfig(2.9, 'aui adv core base gl'.split(), 0)
163 conf.Finish()
164 if not env['HAVE_WX']:
165 print "wxWidgets 2.9 not found using " + env['wxconfig']
166 Exit(1)
167 wxconfig.ParseWXConfig(wxenv)
168 env['CPPDEFINES'] += ['__WXOSX_COCOA__']
169 env['CPPPATH'] = wxenv['CPPPATH']
170 if not wxenv['CPPDEFINES'].count('WXUSINGDLL'):
171 env['FRAMEWORKS'] = wxenv['FRAMEWORKS']
172 env['LIBPATH'] += wxenv['LIBPATH']
173 env['LIBS'] = wxenv['LIBS']
175 env['CPPPATH'] += ['#Externals']
176 env['FRAMEWORKPATH'] += ['Externals/Cg']
177 env['FRAMEWORKS'] += ['Cg']
178 env['shared_zlib'] = True
180 env['data_dir'] = '#' + env['prefix'] + '/Dolphin.app/Contents/Resources'
181 env['plugin_dir'] = '#' + env['prefix'] + '/Dolphin.app/Contents/PlugIns'
183 if env['bundle']:
184 app = env['prefix'] + '/Dolphin.app'
185 dmg = env['prefix'] + '/Dolphin-r' + rev + '.dmg'
186 env.Command(dmg, app, 'rm -f ' + dmg +
187 ' && hdiutil create -srcfolder ' + app + ' -format UDBZ ' + dmg +
188 ' && hdiutil internet-enable -yes ' + dmg)
190 elif sys.platform == 'win32':
191 pass
193 else:
194 env['CCFLAGS'] += ['-fPIC', '-msse2']
195 env['CPPPATH'].insert(0, '#') # Make sure we pick up our own config.h
196 if sys.platform == 'linux2':
197 env['CPPDEFINES'] += [('_FILE_OFFSET_BITS', 64), '_LARGEFILE_SOURCE']
198 env['CXXFLAGS'] += ['-Wno-deprecated'] # XXX <hash_map>
199 env['LINKFLAGS'] += ['-pthread']
200 env['RPATH'] = []
202 conf = env.Configure(config_h = "#config.h", custom_tests = {
203 'CheckPKG' : utils.CheckPKG,
204 'CheckPKGConfig' : utils.CheckPKGConfig,
205 'CheckPortaudio' : utils.CheckPortaudio,
206 'CheckSDL' : utils.CheckSDL,
207 'CheckWXConfig' : wxconfig.CheckWXConfig,
210 if not conf.CheckPKGConfig('0.15.0'):
211 print "Can't find pkg-config, some tests will fail"
213 if env['shared_glew']:
214 env['shared_glew'] = conf.CheckPKG('GLEW')
215 if env['shared_sdl']:
216 env['shared_sdl'] = conf.CheckPKG('SDL')
217 if env['shared_zlib']:
218 env['shared_zlib'] = conf.CheckPKG('z')
219 if env['shared_lzo']:
220 env['shared_lzo'] = conf.CheckPKG('lzo2')
221 # TODO: Check the version of sfml. It should be at least version 1.5
222 if env['shared_sfml']:
223 env['shared_sfml'] = conf.CheckPKG('sfml-network') and \
224 conf.CheckCXXHeader("SFML/Network/Ftp.hpp")
225 if env['shared_soil']:
226 env['shared_soil'] = conf.CheckPKG('SOIL')
227 for var in env.items():
228 if var[0].startswith('shared_') and var[1] == False:
229 print "Shared library " + var[0][7:] + " not detected, " \
230 "falling back to the static library"
232 if env['nowx']:
233 env['HAVE_WX'] = 0
234 else:
235 env['HAVE_WX'] = conf.CheckWXConfig(2.8, 'aui adv core base'.split(), 0)
236 conf.Define('HAVE_WX', env['HAVE_WX'])
237 wxconfig.ParseWXConfig(env)
238 if not env['HAVE_WX']:
239 print "wxWidgets not found - see config.log"
240 Exit(1)
242 env['HAVE_BLUEZ'] = conf.CheckPKG('bluez')
243 conf.Define('HAVE_BLUEZ', env['HAVE_BLUEZ'])
245 env['HAVE_ALSA'] = conf.CheckPKG('alsa')
246 conf.Define('HAVE_ALSA', env['HAVE_ALSA'])
247 env['HAVE_AO'] = conf.CheckPKG('ao')
248 conf.Define('HAVE_AO', env['HAVE_AO'])
249 env['HAVE_OPENAL'] = conf.CheckPKG('openal')
250 conf.Define('HAVE_OPENAL', env['HAVE_OPENAL'])
251 env['HAVE_PORTAUDIO'] = conf.CheckPortaudio(1890)
252 conf.Define('HAVE_PORTAUDIO', env['HAVE_PORTAUDIO'])
253 env['HAVE_PULSEAUDIO'] = conf.CheckPKG('libpulse-simple')
254 conf.Define('HAVE_PULSEAUDIO', env['HAVE_PULSEAUDIO'])
256 env['HAVE_X11'] = conf.CheckPKG('x11')
257 env['HAVE_XRANDR'] = env['HAVE_X11'] and conf.CheckPKG('xrandr')
258 conf.Define('HAVE_XRANDR', env['HAVE_XRANDR'])
259 conf.Define('HAVE_X11', env['HAVE_X11'])
261 if env['HAVE_WX'] and not conf.CheckPKG('gtk+-2.0'):
262 print "gtk+-2.0 developement headers not detected"
263 print "gtk+-2.0 is required to build the WX GUI"
264 Exit(1)
266 if not conf.CheckPKG('GL'):
267 print "Must have OpenGL to build"
268 Exit(1)
269 if not conf.CheckPKG('GLU'):
270 print "Must have GLU to build"
271 Exit(1)
272 if not conf.CheckPKG('Cg') and sys.platform == 'linux2':
273 print "Must have Cg toolkit from NVidia to build"
274 Exit(1)
275 if not conf.CheckPKG('CgGL') and sys.platform == 'linux2':
276 print "Must have CgGL to build"
277 Exit(1)
279 if env['opencl']:
280 env['HAVE_OPENCL'] = conf.CheckPKG('OpenCL')
281 conf.Define('HAVE_OPENCL', env['HAVE_OPENCL'])
282 else:
283 env['HAVE_OPENCL'] = 0
285 # PGO - Profile Guided Optimization
286 if env['pgo'] == 'generate':
287 env['CCFLAGS'] += ['-fprofile-generate']
288 env['LINKFLAGS'] += ['-fprofile-generate']
289 if env['pgo'] == 'use':
290 env['CCFLAGS'] += ['-fprofile-use']
291 env['LINKFLAGS'] += ['-fprofile-use']
293 # Profiling
294 if env['flavor'] == 'prof':
295 proflibs = ['/usr/lib/oprofile', '/usr/local/lib/oprofile']
296 env['LIBPATH'] += ['proflibs']
297 env['RPATH'] += ['proflibs']
298 if conf.CheckPKG('opagent'):
299 conf.Define('USE_OPROFILE', 1)
300 else:
301 print "Can't build prof without oprofile, disabling"
303 tarname = 'dolphin-' + rev
304 env['TARFLAGS'] = '-cj'
305 env['TARSUFFIX'] = '.tar.bz2'
307 if env['install'] == 'local':
308 env['binary_dir'] = '#' + env['prefix']
309 env['data_dir'] = '#' + env['prefix']
310 env['plugin_dir'] = '#' + env['prefix'] + '/plugins'
311 if env['bundle']:
312 env.Tar(tarname, env['prefix'])
313 else:
314 env['prefix'] = Dir(env['prefix']).abspath
315 env['binary_dir'] = env['prefix'] + '/bin'
316 env['data_dir'] = env['prefix'] + "/share/dolphin-emu"
317 env['plugin_dir'] = env['prefix'] + '/lib/dolphin-emu'
318 conf.Define('DATA_DIR', "\"" + env['data_dir'] + "\"")
319 conf.Define('LIBS_DIR', "\"" + env['prefix'] + '/lib/' + "\"")
320 # Setup destdir for package building
321 # Warning: The program will not run from this location.
322 # It is assumed the package will later install it to the prefix.
323 if env.has_key('destdir'):
324 env['destdir'] = Dir(env['destdir']).abspath
325 env['binary_dir'] = env['destdir'] + env['binary_dir']
326 env['data_dir'] = env['destdir'] + env['data_dir']
327 env['plugin_dir'] = env['destdir'] + env['plugin_dir']
328 env['prefix'] = env['destdir'] + env['prefix']
329 if env['bundle']:
330 env.Command(tarname + env['TARSUFFIX'], env['prefix'],
331 'tar ' + env['TARFLAGS'] + 'C ' + env['destdir'] + \
332 ' -f ' + tarname + env['TARSUFFIX'] + ' ' + \
333 env['prefix'].split(env['destdir'], 1)[1][1:])
335 conf.Define('USER_DIR', "\"" + env['userdir'] + "\"")
337 # After all configuration tests are done
338 conf.Finish()
340 env.Alias('install', env['prefix'])
342 # Local (static) libraries must be first in the search path for the build in
343 # order that they can override system libraries, but they must not be found
344 # during autoconfiguration as they will then be detected as system libraries.
345 env['LIBPATH'].insert(0, env['local_libs'])
347 dirs = [
348 'Externals/Bochs_disasm',
349 #'Externals/CLRun',
350 'Externals/Lua',
351 'Externals/MemcardManager',
352 'Externals/WiiUse/Src',
353 'Externals/GLew',
354 'Externals/LZO',
355 #'Externals/OpenAL',
356 'Externals/SDL',
357 'Externals/SOIL',
358 'Externals/SFML/src',
359 #'Externals/wxWidgets',
360 'Externals/zlib',
361 'Source/Core/AudioCommon/Src',
362 'Source/Core/Common/Src',
363 'Source/Core/Core/Src',
364 'Source/Core/DSPCore/Src',
365 'Source/Core/DebuggerUICommon/Src',
366 'Source/Core/DebuggerWX/Src',
367 'Source/Core/DiscIO/Src',
368 'Source/Core/DolphinWX/Src',
369 'Source/Core/InputCommon/Src',
370 'Source/Core/InputUICommon/Src',
371 'Source/Core/VideoCommon/Src',
372 'Source/DSPTool/Src',
373 'Source/Plugins/Plugin_DSP_HLE/Src',
374 'Source/Plugins/Plugin_DSP_LLE/Src',
375 #'Source/Plugins/Plugin_VideoDX11/Src',
376 #'Source/Plugins/Plugin_VideoDX9/Src',
377 'Source/Plugins/Plugin_VideoOGL/Src',
378 'Source/Plugins/Plugin_VideoSoftware/Src',
379 'Source/Plugins/Plugin_Wiimote/Src',
380 'Source/Plugins/Plugin_WiimoteNew/Src',
381 'Source/UnitTests',
384 # Now that platform configuration is done, propagate it to modules
385 for subdir in dirs:
386 SConscript(dirs = subdir, duplicate = 0, exports = 'env',
387 variant_dir = env['build_dir'] + os.sep + subdir)
388 if subdir.startswith('Source/Core'):
389 env['CPPPATH'] += ['#' + subdir]
391 # Print a nice progress indication when not compiling
392 Progress(['-\r', '\\\r', '|\r', '/\r'], interval = 5)
394 # Generate help, printing current status of options
395 Help(vars.GenerateHelpText(env))