Build fix.
[dolphin.git] / SConstruct
blob58228075d139fe1d1a53744cd4540d8bdd54d423
1 # -*- python -*-
3 import os
4 import sys
5 import platform
7 # Home made tests
8 sys.path.append('SconsTests')
9 import wxconfig
10 import utils
12 # Some features needs at least scons 0.98
13 EnsureSConsVersion(1, 2)
15 # TODO: how do we use it in help?
16 name="Dolphin"
17 version="SVN"
18 description="A wii/gamecube emulator"
19 license="GPL v2"
21 warnings = [
22 'all',
23 'write-strings',
24 'shadow',
25 'pointer-arith',
26 'packed',
27 'no-conversion',
28 # 'no-unused-result', (need a newer gcc for this?)
30 compileFlags = [
31 '-fno-exceptions',
32 '-fno-strict-aliasing',
33 '-msse2',
34 # '-fomit-frame-pointer',
35 # '-flto',
38 cppDefines = [
39 ( '_FILE_OFFSET_BITS', 64),
40 '_LARGEFILE_SOURCE',
41 'GCC_HASCLASSVISIBILITY',
44 basedir = os.getcwd()+ '/'
46 include_paths = [
47 basedir + 'Source/Core/Common/Src',
48 basedir + 'Source/Core/DiscIO/Src',
49 basedir + 'Source/PluginSpecs',
50 basedir + 'Source/Core/Core/Src',
51 basedir + 'Source/Core/DebuggerWX/Src',
52 basedir + 'Externals/Bochs_disasm',
53 basedir + 'Externals/Lua',
54 basedir + 'Externals/WiiUseSrc/Src',
55 basedir + 'Source/Core/VideoCommon/Src',
56 basedir + 'Source/Core/InputCommon/Src',
57 basedir + 'Source/Plugins/InputPluginCommon/Src',
58 basedir + 'Source/Core/AudioCommon/Src',
59 basedir + 'Source/Core/DebuggerUICommon/Src',
60 basedir + 'Source/Core/DSPCore/Src',
63 dirs = [
64 'Externals/Bochs_disasm',
65 'Externals/Lua',
66 'Externals/WiiUseSrc/Src',
67 'Source/Core/Common/Src',
68 'Source/Core/Core/Src',
69 'Source/Core/DiscIO/Src',
70 'Source/Core/VideoCommon/Src',
71 'Source/Core/InputCommon/Src',
72 'Source/Core/AudioCommon/Src',
73 'Source/Core/DebuggerUICommon/Src',
74 'Source/Core/DSPCore/Src',
75 'Source/DSPTool/Src',
76 'Source/Plugins/Plugin_VideoOGL/Src',
77 'Source/Plugins/Plugin_VideoSoftware/Src',
78 'Source/Plugins/Plugin_DSP_HLE/Src',
79 'Source/Plugins/Plugin_DSP_LLE/Src',
80 'Source/Plugins/Plugin_GCPad/Src',
81 'Source/Plugins/Plugin_GCPadNew/Src',
82 'Source/Plugins/Plugin_Wiimote/Src',
83 'Source/Core/DolphinWX/Src',
84 'Source/Core/DebuggerWX/Src',
85 'Source/UnitTests/',
86 'Source/Plugins/InputPluginCommon/Src/',
87 'Source/Plugins/Plugin_WiimoteNew/Src/',
90 builders = {}
91 if sys.platform == 'darwin':
92 from plistlib import writePlist
93 def createPlist(target, source, env):
94 properties = {}
95 for srcNode in source:
96 properties.update(srcNode.value)
97 for dstNode in target:
98 writePlist(properties, str(dstNode))
99 builders['Plist'] = Builder(action = createPlist)
101 # handle command line options
102 vars = Variables('args.cache')
104 vars.AddVariables(
105 BoolVariable('verbose', 'Set for compilation line', False),
106 BoolVariable('bundle', 'Set to create bundle', False),
107 BoolVariable('lint', 'Set for lint build (extra warnings)', False),
108 BoolVariable('nowx', 'Set For Building with no WX libs (WIP)', False),
109 BoolVariable('openal', 'Build with OpenAL', False),
110 BoolVariable('noao', 'Build without AO', False),
111 BoolVariable('wxgl', 'Set For Building with WX GL libs (WIP)', False),
112 BoolVariable('opencl', 'Build with OpenCL', False),
113 BoolVariable('nojit', 'Remove entire jit cores', False),
114 BoolVariable('shared_soil', 'Use system shared libSOIL', False),
115 BoolVariable('shared_lzo', 'Use system shared liblzo2', False),
116 BoolVariable('shared_sfml', 'Use system shared libsfml-network', False),
117 PathVariable('userdir', 'Set the name of the user data directory in home', '.dolphin-emu', PathVariable.PathAccept),
118 EnumVariable('install', 'Choose a local or global installation', 'local',
119 allowed_values = ('local', 'global'),
120 ignorecase = 2
122 PathVariable('prefix', 'Installation prefix (only used for a global build)', '/usr', PathVariable.PathAccept),
123 PathVariable('destdir', 'Temporary install location (for package building)', None, PathVariable.PathAccept),
124 EnumVariable('flavor', 'Choose a build flavor', 'release',
125 allowed_values = ('release', 'devel', 'debug', 'fastlog', 'prof'),
126 ignorecase = 2
128 EnumVariable('osx', 'Choose a backend (WIP)', '32cocoa',
129 allowed_values = ('32x11', '32cocoa', '64cocoa', 'universal'),
130 ignorecase = 2
132 PathVariable('wxconfig', 'Path to the wxconfig', None),
133 EnumVariable('pgo', 'Profile-Guided Optimization (generate or use)', 'none',
134 allowed_values = ('none', 'generate', 'use'),
135 ignorecase = 2
137 ('CC', 'The c compiler', 'gcc'),
138 ('CXX', 'The c++ compiler', 'g++'),
141 if sys.platform == 'win32':
142 env = Environment(
143 CPPPATH = include_paths,
144 RPATH = [],
145 LIBS = [],
146 LIBPATH = [],
147 tools = [ 'mingw' ],
148 variables = vars,
149 ENV = os.environ,
150 BUILDERS = builders,
151 DESCRIPTION = description,
152 SUMMARY = description,
153 LICENSE = license,
154 NAME = name,
155 VERSION = version,
157 else:
158 env = Environment(
159 CPPPATH = include_paths,
160 RPATH = [],
161 LIBS = [],
162 LIBPATH = [],
163 variables = vars,
164 ENV = {
165 'PATH' : os.environ['PATH'],
166 'HOME' : os.environ['HOME']
168 BUILDERS = builders,
169 DESCRIPTION = description,
170 SUMMARY = description,
171 LICENSE = license,
172 NAME = name,
173 VERSION = version,
176 # save the given command line options
177 vars.Save('args.cache', env)
179 # verbose compile
180 if not env['verbose']:
181 env['CCCOMSTR'] = "Compiling $TARGET"
182 env['CXXCOMSTR'] = "Compiling $TARGET"
183 env['ARCOMSTR'] = "Archiving $TARGET"
184 env['LINKCOMSTR'] = "Linking $TARGET"
185 env['ASCOMSTR'] = "Assembling $TARGET"
186 env['ASPPCOMSTR'] = "Assembling $TARGET"
187 env['SHCCCOMSTR'] = "Compiling shared $TARGET"
188 env['SHCXXCOMSTR'] = "Compiling shared $TARGET"
189 env['SHLINKCOMSTR'] = "Linking shared $TARGET"
190 env['RANLIBCOMSTR'] = "Indexing $TARGET"
192 # build flavor
193 flavour = env['flavor']
194 if (flavour == 'debug'):
195 compileFlags.append('-ggdb')
196 cppDefines.append('_DEBUG') #enables LOGGING
197 # FIXME: this disable wx debugging how do we make it work?
198 cppDefines.append('NDEBUG')
199 elif (flavour == 'devel'):
200 compileFlags.append('-ggdb')
201 elif (flavour == 'fastlog'):
202 compileFlags.append('-O3')
203 cppDefines.append('DEBUGFAST')
204 elif (flavour == 'prof'):
205 compileFlags.append('-O3')
206 compileFlags.append('-ggdb')
207 elif (flavour == 'release'):
208 compileFlags.append('-O3')
209 compileFlags.append('-fomit-frame-pointer');
210 # more warnings
211 if env['lint']:
212 warnings.append('error')
213 warnings.append('unreachable-code')
214 warnings.append('float-equal')
216 # add the warnings to the compile flags
217 compileFlags += [ ('-W' + warning) for warning in warnings ]
219 env['CCFLAGS'] = compileFlags
220 if sys.platform == 'win32':
221 env['CXXFLAGS'] = compileFlags
222 else:
223 env['CXXFLAGS'] = compileFlags + [ '-fvisibility-inlines-hidden' ]
224 env['CPPDEFINES'] = cppDefines
226 # pgo - Profile Guided Optimization
227 if env['pgo']=='generate':
228 compileFlags.append('-fprofile-generate')
229 env['LINKFLAGS']='-fprofile-generate'
230 if env['pgo']=='use':
231 compileFlags.append('-fprofile-use')
232 env['LINKFLAGS']='-fprofile-use'
235 # Configuration tests section
236 tests = {'CheckWXConfig' : wxconfig.CheckWXConfig,
237 'CheckPKGConfig' : utils.CheckPKGConfig,
238 'CheckPKG' : utils.CheckPKG,
239 'CheckSDL' : utils.CheckSDL,
240 'CheckFink' : utils.CheckFink,
241 'CheckMacports' : utils.CheckMacports,
242 'CheckPortaudio' : utils.CheckPortaudio,
245 #object files
246 env['build_dir'] = os.path.join(basedir, 'Build', platform.system() + '-' + platform.machine() + '-' + env['flavor'] + os.sep)
249 VariantDir(env['build_dir'], '.', duplicate=0)
251 # Where do we run from
252 env['base_dir'] = os.getcwd()+ '/'
254 # install paths
255 extra=''
256 if flavour == 'debug':
257 extra = '-debug'
258 elif flavour == 'prof':
259 extra = '-prof'
261 # Set up the install locations
262 if (env['install'] == 'global'):
263 env['prefix'] = os.path.join(env['prefix'] + os.sep)
264 env['binary_dir'] = env['prefix'] + 'bin/'
265 env['libs_dir'] = env['prefix'] + 'lib/'
266 env['plugin_dir'] = env['prefix'] + 'lib/dolphin-emu/'
267 env['data_dir'] = env['prefix'] + "share/dolphin-emu/"
268 else:
269 env['prefix'] = os.path.join(env['base_dir'] + 'Binary', platform.system() + '-' + platform.machine() + extra + os.sep)
270 env['binary_dir'] = env['prefix']
271 if sys.platform == 'darwin':
272 env['plugin_dir'] = env['prefix'] + 'Dolphin.app/Contents/PlugIns/'
273 env['data_dir'] = env['prefix'] + 'Dolphin.app/Contents/'
274 env['libs_dir'] = env['prefix'] + 'Libs/'
275 else:
276 env['plugin_dir'] = env['prefix'] + 'plugins/'
277 env['data_dir'] = env['prefix']
278 env['libs_dir'] = env['prefix'] + 'lib/'
280 env['RPATH'].append(env['libs_dir'])
282 # static libs goes here
283 env['local_libs'] = env['build_dir'] + os.sep + 'libs' + os.sep
285 env['LIBPATH'].append(env['local_libs'])
286 env['LIBPATH'].append(env['libs_dir'])
288 conf = env.Configure(custom_tests = tests,
289 config_h="Source/Core/Common/Src/Config.h")
291 if not conf.CheckPKGConfig('0.15.0'):
292 print "Can't find pkg-config, some tests will fail"
294 # find ports/fink for library and include path
295 if sys.platform == 'darwin':
296 #ports usually has newer versions
297 conf.CheckMacports()
298 conf.CheckFink()
300 env['HAVE_SDL'] = conf.CheckSDL('1.0.0')
302 # Bluetooth for wii support
303 env['HAVE_BLUEZ'] = conf.CheckPKG('bluez')
305 # needed for sound
306 env['HAVE_AO'] = 0
307 if not env['noao']:
308 env['HAVE_AO'] = conf.CheckPKG('ao')
310 env['HAVE_OPENAL'] = 0
311 if env['openal']:
312 env['HAVE_OPENAL'] = conf.CheckPKG('openal')
314 env['HAVE_ALSA'] = conf.CheckPKG('alsa')
316 env['HAVE_PULSEAUDIO'] = 0
317 #env['HAVE_PULSEAUDIO'] = conf.CheckPKG('libpulse')
319 # OpenCL
320 env['HAVE_OPENCL'] = 0
321 if env['opencl']:
322 env['HAVE_OPENCL'] = conf.CheckPKG('OpenCL')
324 env['HAVE_PORTAUDIO'] = 0
325 if sys.platform != 'darwin':
326 # needed for mic
327 env['HAVE_PORTAUDIO'] = conf.CheckPortaudio(1890)
329 # SOIL
330 env['SHARED_SOIL'] = 0;
331 if env['shared_soil']:
332 env['SHARED_SOIL'] = conf.CheckPKG('SOIL')
333 if not env['SHARED_SOIL']:
334 print "shared SOIL library not detected"
335 print "falling back to the static library"
336 if not env['SHARED_SOIL']:
337 env['CPPPATH'] += [ basedir + 'Externals/SOIL' ]
338 dirs += ['Externals/SOIL']
340 # LZO
341 env['SHARED_LZO'] = 0;
342 if env['shared_lzo']:
343 env['SHARED_LZO'] = conf.CheckPKG('lzo2')
344 if not env['SHARED_LZO']:
345 print "shared LZO library not detected"
346 print "falling back to the static library"
347 if not env['SHARED_LZO']:
348 env['CPPPATH'] += [ basedir + 'Externals/LZO' ]
349 dirs += ['Externals/LZO']
351 # SFML
352 env['SHARED_SFML'] = 0;
353 if env['shared_sfml']:
354 # TODO: Check the version of sfml. It should be at least version 1.5
355 env['SHARED_SFML'] = conf.CheckPKG('sfml-network') and conf.CheckCXXHeader("SFML/Network/Ftp.hpp")
356 if not env['SHARED_SFML']:
357 print "shared sfml-network library not detected"
358 print "falling back to the static library"
359 if not env['SHARED_SFML']:
360 env['CPPPATH'] += [ basedir + 'Externals/SFML/include' ]
361 dirs += ['Externals/SFML/src']
363 #osx 64 specifics
364 if sys.platform == 'darwin':
365 env['HAVE_XRANDR'] = 0
366 if env['osx'] == '64cocoa':
367 compileFlags += ['-arch' , 'x86_64', '-m64' ]
368 env['LINKFLAGS'] += ['-arch' , 'x86_64', '-m64' ]
369 conf.Define('MAP_32BIT', 0)
370 if env['osx'] == '32cocoa':
371 compileFlags += ['-arch' , 'i386', '-m32' ]
372 env['LINKFLAGS'] += ['-arch' , 'i386', '-m32' ]
373 if env['osx'] == 'universal':
374 compileFlags += ['-arch i386', '-arch x86_64']
375 env['LINKFLAGS'] += ['-arch i386', '-arch x86_64']
376 if not env['osx'] == '32x11':
377 env['HAVE_X11'] = 0
378 env['HAVE_COCOA'] = 1
380 else:
381 env['HAVE_X11'] = conf.CheckPKG('x11')
382 env['HAVE_XRANDR'] = env['HAVE_X11'] and conf.CheckPKG('xrandr')
383 env['HAVE_COCOA'] = 0
385 # handling wx flags CCFLAGS should be created before
386 wxmods = ['aui', 'adv', 'core', 'base']
388 env['USE_WX'] = 0
389 if env['wxgl']:
390 wxmods.append('gl')
391 env['USE_WX'] = 1
393 if sys.platform == 'win32':
394 env['HAVE_WX'] = 1
395 env['USE_WX'] = 1
397 # Gui less build
398 if env['nowx']:
399 env['HAVE_WX'] = 0;
400 else:
401 env['HAVE_WX'] = conf.CheckWXConfig('2.8', wxmods, 0)
403 # check for libgtk2.0
404 env['HAVE_GTK2'] = 0
405 if sys.platform == 'linux2':
406 env['HAVE_GTK2'] = env['HAVE_WX'] and conf.CheckPKG('gtk+-2.0')
407 if env['HAVE_WX'] and not env['HAVE_GTK2']:
408 print "gtk+-2.0 developement headers not detected"
409 print "gtk+-2.0 is required to build the WX GUI"
410 Exit(1)
412 env['NOJIT'] = 0
413 if env['nojit']:
414 env['NOJIT'] = 1
416 conf.Define('NOJIT', env['NOJIT'])
418 # Creating config.h defines
419 conf.Define('HAVE_SDL', env['HAVE_SDL'])
420 conf.Define('HAVE_BLUEZ', env['HAVE_BLUEZ'])
421 conf.Define('HAVE_AO', env['HAVE_AO'])
422 conf.Define('HAVE_OPENCL', env['HAVE_OPENCL'])
423 conf.Define('HAVE_OPENAL', env['HAVE_OPENAL'])
424 conf.Define('HAVE_ALSA', env['HAVE_ALSA'])
425 conf.Define('HAVE_WX', env['HAVE_WX'])
426 conf.Define('USE_WX', env['USE_WX'])
427 conf.Define('HAVE_X11', env['HAVE_X11'])
428 conf.Define('HAVE_XRANDR', env['HAVE_XRANDR'])
429 conf.Define('HAVE_COCOA', env['HAVE_COCOA'])
430 conf.Define('HAVE_PORTAUDIO', env['HAVE_PORTAUDIO'])
431 conf.Define('SHARED_SOIL', env['SHARED_SOIL'])
432 conf.Define('SHARED_LZO', env['SHARED_LZO'])
433 conf.Define('SHARED_SFML', env['SHARED_SFML'])
434 conf.Define('USER_DIR', "\"" + env['userdir'] + "\"")
435 if (env['install'] == 'global'):
436 conf.Define('DATA_DIR', "\"" + env['data_dir'] + "\"")
437 conf.Define('LIBS_DIR', "\"" + env['libs_dir'] + "\"")
439 # lua
440 env['LUA_USE_MACOSX'] = 0
441 env['LUA_USE_LINUX'] = 0
442 env['LUA_USE_POSIX'] = 0
443 if sys.platform == 'darwin':
444 env['LUA_USE_MACOSX'] = 1
445 elif sys.platform == 'linux2':
446 env['LUA_USE_LINUX'] = 1
448 conf.Define('LUA_USE_MACOSX', env['LUA_USE_MACOSX'])
449 conf.Define('LUA_USE_LINUX', env['LUA_USE_LINUX'])
451 # profile
452 env['USE_OPROFILE'] = 0
453 if (flavour == 'prof'):
454 proflibs = [ '/usr/lib/oprofile', '/usr/local/lib/oprofile' ]
455 env['LIBPATH'].append(proflibs)
456 env['RPATH'].append(proflibs)
457 if conf.CheckPKG('opagent'):
458 env['USE_OPROFILE'] = 1
459 else:
460 print "Can't build prof without oprofile, disabling"
462 conf.Define('USE_OPROFILE', env['USE_OPROFILE'])
463 # After all configuration tests are done
464 conf.Finish()
466 #wx windows flags
467 if env['HAVE_WX']:
468 wxconfig.ParseWXConfig(env)
469 #this smells like a hack, but i dont know any other way to fix this
470 #right now. ParseWXConfig calls wx-config --libs, which returns
471 #"-arch i386" on my box (and probably also tmator's).
472 #SCons.ParseConfig makes this a tuple, which is
473 # 1) a problem for utils.filterWarnings
474 # 2) a duplicate (and conflicting) set of arch specifiers
475 #this mainly affects MacOSX, since darwin builds explicitly get
476 #those set around line 280.
477 if sys.platform == 'darwin':
478 env['CCFLAGS'] = [
480 for f in filter(lambda x:isinstance(x, basestring), env['CCFLAGS'])
482 else:
483 print "WX not found or disabled, not building GUI"
485 # add methods from utils to env
486 env.AddMethod(utils.filterWarnings)
488 rev = utils.GenerateRevFile(env['flavor'],
489 "Source/Core/Common/Src/svnrev_template.h",
490 "Source/Core/Common/Src/svnrev.h")
491 # print a nice progress indication when not compiling
492 Progress(['-\r', '\\\r', '|\r', '/\r'], interval = 5)
494 # Setup destdir for package building
495 # Warning: The program will not run from this location. It is assumed the
496 # package will later install it to the prefix as it was defined before this.
497 if env.has_key('destdir'):
498 env['prefix'] = env['destdir'] + env['prefix']
499 env['plugin_dir'] = env['destdir'] + env['plugin_dir']
500 env['binary_dir'] = env['destdir'] + env['binary_dir']
501 env['libs_dir'] = env['destdir'] + env['libs_dir']
502 env['data_dir'] = env['destdir'] + env['data_dir']
504 # die on unknown variables
505 unknown = vars.UnknownVariables()
506 if unknown:
507 print "Unknown variables:", unknown.keys()
508 Exit(1)
510 # generate help
511 Help(vars.GenerateHelpText(env))
513 Export('env')
515 for subdir in dirs:
516 SConscript(
517 subdir + os.sep + 'SConscript',
518 variant_dir = env[ 'build_dir' ] + subdir + os.sep,
519 duplicate=0
522 # Data install
523 if sys.platform == 'darwin':
524 env.Install(env['data_dir'], 'Data/Sys')
525 env.Install(env['data_dir'], 'Data/User')
526 env.Install(env['binary_dir'] + 'Dolphin.app/Contents/Resources/',
527 'Source/Core/DolphinWX/resources/Dolphin.icns')
528 else:
529 env.InstallAs(env['data_dir'] + 'sys', 'Data/Sys')
530 env.InstallAs(env['data_dir'] + 'user', 'Data/User')
532 env.Alias('install', env['prefix'])
534 if env['bundle']:
535 # Make tar ball (TODO put inside normal dir)
536 tar_env = env.Clone()
537 tarball = tar_env.Tar('dolphin-'+rev +'.tar.bz2', env['prefix'])
538 tar_env.Append(TARFLAGS='-j',
539 TARCOMSTR="Creating release tarball")
542 #TODO clean all bundles
543 #env.Clean(all, 'dolphin-*'+ '.tar.bz2')