changes to support packaging of the GTK-Quartz version of Ardour for OS X
[ardour.git] / SConstruct
1 # -*- python -*-
2
3 import os
4 import sys
5 import re
6 import shutil
7 import glob
8 import errno
9 import time
10 import platform
11 import string
12 import commands
13 from sets import Set
14 import SCons.Node.FS
15
16 SConsignFile()
17 EnsureSConsVersion(0, 96)
18
19 ardour_version = '2.0.5'
20
21 subst_dict = { }
22
23 #
24 # Command-line options
25 #
26
27 opts = Options('scache.conf')
28 opts.AddOptions(
29     ('ARCH', 'Set architecture-specific compilation flags by hand (all flags as 1 argument)',''),
30     BoolOption('AUDIOUNITS', 'Compile with Apple\'s AudioUnit library. (experimental)', 0),
31     BoolOption('COREAUDIO', 'Compile with Apple\'s CoreAudio library', 0),
32     BoolOption('GTKOSX', 'Compile for use with GTK-OSX, not GTK-X11', 0),
33     PathOption('GTKOSX_PREFIX', 'Configure-style prefix used to install GTK-Quartz', "/opt/gtk"),
34     BoolOption('DEBUG', 'Set to build with debugging information and no optimizations', 0),
35     PathOption('DESTDIR', 'Set the intermediate install "prefix"', '/'),
36     EnumOption('DIST_TARGET', 'Build target for cross compiling packagers', 'auto', allowed_values=('auto', 'i386', 'i686', 'x86_64', 'powerpc', 'tiger', 'panther', 'none' ), ignorecase=2),
37     BoolOption('DMALLOC', 'Compile and link using the dmalloc library', 0),
38     BoolOption('EXTRA_WARN', 'Compile with -Wextra, -ansi, and -pedantic.  Might break compilation.  For pedants', 0),
39     BoolOption('FFT_ANALYSIS', 'Include FFT analysis window', 0),
40     BoolOption('FPU_OPTIMIZATION', 'Build runtime checked assembler code', 1),
41     BoolOption('LIBLO', 'Compile with support for liblo library', 1),
42     BoolOption('NLS', 'Set to turn on i18n support', 1),
43     PathOption('PREFIX', 'Set the install "prefix"', '/usr/local'),
44     BoolOption('SURFACES', 'Build support for control surfaces', 1),
45     BoolOption('SYSLIBS', 'USE AT YOUR OWN RISK: CANCELS ALL SUPPORT FROM ARDOUR AUTHORS: Use existing system versions of various libraries instead of internal ones', 0),
46     BoolOption('UNIVERSAL', 'Compile as universal binary.  Requires that external libraries are already universal.', 0),
47     BoolOption('VERSIONED', 'Add revision information to ardour/gtk executable name inside the build directory', 0),
48     BoolOption('VST', 'Compile with support for VST', 0),
49     BoolOption('GPROFILE', 'Compile with support for gprofile (Developers only)', 0),
50     BoolOption('TRANZPORT', 'Compile with support for Frontier Designs (if libusb is available)', 1)
51 )
52
53 #----------------------------------------------------------------------
54 # a handy helper that provides a way to merge compile/link information
55 # from multiple different "environments"
56 #----------------------------------------------------------------------
57 #
58 class LibraryInfo(Environment):
59     def __init__(self,*args,**kw):
60         Environment.__init__ (self,*args,**kw)
61     
62     def Merge (self,others):
63         for other in others:
64             self.Append (LIBS = other.get ('LIBS',[]))
65             self.Append (LIBPATH = other.get ('LIBPATH', []))
66             self.Append (CPPPATH = other.get('CPPPATH', []))
67             self.Append (LINKFLAGS = other.get('LINKFLAGS', []))
68         self.Replace(LIBPATH = list(Set(self.get('LIBPATH', []))))
69         self.Replace(CPPPATH = list(Set(self.get('CPPPATH',[]))))
70         #doing LINKFLAGS breaks -framework
71         #doing LIBS break link order dependency
72     
73     def ENV_update(self, src_ENV):
74         for k in src_ENV.keys():
75             if k in self['ENV'].keys() and k in [ 'PATH', 'LD_LIBRARY_PATH',
76                                                   'LIB', 'INCLUDE' ]:
77                 self['ENV'][k]=SCons.Util.AppendPath(self['ENV'][k], src_ENV[k])
78             else:
79                 self['ENV'][k]=src_ENV[k]
80
81 env = LibraryInfo (options = opts,
82                    CPPPATH = [ '.' ],
83                    VERSION = ardour_version,
84                    TARBALL='ardour-' + ardour_version + '.tar.bz2',
85                    DISTFILES = [ ],
86                    DISTTREE  = '#ardour-' + ardour_version,
87                    DISTCHECKDIR = '#ardour-' + ardour_version + '/check'
88                    )
89
90 env.ENV_update(os.environ)
91
92 #----------------------------------------------------------------------
93 # Builders
94 #----------------------------------------------------------------------
95
96 # Handy subst-in-file builder
97 #
98
99 def do_subst_in_file(targetfile, sourcefile, dict):
100     """Replace all instances of the keys of dict with their values.
101     For example, if dict is {'%VERSION%': '1.2345', '%BASE%': 'MyProg'},
102     then all instances of %VERSION% in the file will be replaced with 1.2345 etc.
103     """
104     try:
105         f = open(sourcefile, 'rb')
106         contents = f.read()
107         f.close()
108     except:
109         raise SCons.Errors.UserError, "Can't read source file %s"%sourcefile
110     for (k,v) in dict.items():
111         contents = re.sub(k, v, contents)
112     try:
113         f = open(targetfile, 'wb')
114         f.write(contents)
115         f.close()
116     except:
117         raise SCons.Errors.UserError, "Can't write target file %s"%targetfile
118     return 0 # success
119
120 def subst_in_file(target, source, env):
121     if not env.has_key('SUBST_DICT'):
122         raise SCons.Errors.UserError, "SubstInFile requires SUBST_DICT to be set."
123     d = dict(env['SUBST_DICT']) # copy it
124     for (k,v) in d.items():
125         if callable(v):
126             d[k] = env.subst(v())
127         elif SCons.Util.is_String(v):
128             d[k]=env.subst(v)
129         else:
130             raise SCons.Errors.UserError, "SubstInFile: key %s: %s must be a string or callable"%(k, repr(v))
131     for (t,s) in zip(target, source):
132         return do_subst_in_file(str(t), str(s), d)
133
134 def subst_in_file_string(target, source, env):
135     """This is what gets printed on the console."""
136     return '\n'.join(['Substituting vars from %s into %s'%(str(s), str(t))
137                       for (t,s) in zip(target, source)])
138
139 def subst_emitter(target, source, env):
140     """Add dependency from substituted SUBST_DICT to target.
141     Returns original target, source tuple unchanged.
142     """
143     d = env['SUBST_DICT'].copy() # copy it
144     for (k,v) in d.items():
145         if callable(v):
146             d[k] = env.subst(v())
147         elif SCons.Util.is_String(v):
148             d[k]=env.subst(v)
149     Depends(target, SCons.Node.Python.Value(d))
150     # Depends(target, source) # this doesn't help the install-sapphire-linux.sh problem
151     return target, source
152
153 subst_action = Action (subst_in_file, subst_in_file_string)
154 env['BUILDERS']['SubstInFile'] = Builder(action=subst_action, emitter=subst_emitter)
155
156 #
157 # internationalization
158 #
159
160 # po_builder: builder function to copy po files to the parent directory while updating them
161 #
162 # first source:  .po file
163 # second source: .pot file
164 #
165
166 def po_builder(target,source,env):
167     os.spawnvp (os.P_WAIT, 'cp', ['cp', str(source[0]), str(target[0])])
168     args = [ 'msgmerge',
169              '--update',
170              str(target[0]),
171              str(source[1])
172              ]
173     print 'Updating ' + str(target[0])
174     return os.spawnvp (os.P_WAIT, 'msgmerge', args)
175
176 po_bld = Builder (action = po_builder)
177 env.Append(BUILDERS = {'PoBuild' : po_bld})
178
179 # mo_builder: builder function for (binary) message catalogs (.mo)
180 #
181 # first source:  .po file
182 #
183
184 def mo_builder(target,source,env):
185     args = [ 'msgfmt',
186              '-c',
187              '-o',
188              target[0].get_path(),
189              source[0].get_path()
190              ]
191     return os.spawnvp (os.P_WAIT, 'msgfmt', args)
192
193 mo_bld = Builder (action = mo_builder)
194 env.Append(BUILDERS = {'MoBuild' : mo_bld})
195
196 # pot_builder: builder function for message templates (.pot)
197 #
198 # source: list of C/C++ etc. files to extract messages from
199 #
200
201 def pot_builder(target,source,env):
202     args = [ 'xgettext',
203              '--keyword=_',
204              '--keyword=N_',
205              '--from-code=UTF-8',
206              '-o', target[0].get_path(),
207              "--default-domain=" + env['PACKAGE'],
208              '--copyright-holder="Paul Davis"' ]
209     args += [ src.get_path() for src in source ]
210     
211     return os.spawnvp (os.P_WAIT, 'xgettext', args)
212
213 pot_bld = Builder (action = pot_builder)
214 env.Append(BUILDERS = {'PotBuild' : pot_bld})
215
216 #
217 # utility function, not a builder
218 #
219
220 def i18n (buildenv, sources, installenv):
221     domain = buildenv['PACKAGE']
222     potfile = buildenv['POTFILE']
223     
224     installenv.Alias ('potupdate', buildenv.PotBuild (potfile, sources))
225     
226     p_oze = [ os.path.basename (po) for po in glob.glob ('po/*.po') ]
227     languages = [ po.replace ('.po', '') for po in p_oze ]
228     
229     for po_file in p_oze:
230         buildenv.PoBuild(po_file, ['po/'+po_file, potfile])
231         mo_file = po_file.replace (".po", ".mo")
232         installenv.Alias ('install', buildenv.MoBuild (mo_file, po_file))
233     
234     for lang in languages:
235         modir = (os.path.join (install_prefix, 'share/locale/' + lang + '/LC_MESSAGES/'))
236         moname = domain + '.mo'
237         installenv.Alias('install', installenv.InstallAs (os.path.join (modir, moname), lang + '.mo'))
238
239
240 def fetch_svn_revision (path):
241     cmd = "LANG= "
242     cmd += "svn info "
243     cmd += path
244     cmd += " | awk '/^Revision:/ { print $2}'"
245     return commands.getoutput (cmd)
246
247 def create_stored_revision (target = None, source = None, env = None):
248     if os.path.exists('.svn'):    
249         rev = fetch_svn_revision ('.');
250         try:
251             text  = "#ifndef __ardour_svn_revision_h__\n"
252             text += "#define __ardour_svn_revision_h__\n"
253             text += "static const char* ardour_svn_revision = \"" + rev + "\";\n";
254             text += "#endif\n"
255             print '============> writing svn revision info to svn_revision.h\n'
256             o = file ('svn_revision.h', 'w')
257             o.write (text)
258             o.close ()
259         except IOError:
260             print "Could not open svn_revision.h for writing\n"
261             sys.exit (-1)
262     else:
263         print "You cannot use \"scons revision\" on without using a checked out"
264         print "copy of the Ardour source code repository"
265         sys.exit (-1)
266
267 #
268 # A generic builder for version.cc files
269 #
270 # note: requires that DOMAIN, MAJOR, MINOR, MICRO are set in the construction environment
271 # note: assumes one source files, the header that declares the version variables
272 #
273
274 def version_builder (target, source, env):
275
276     text  = "int " + env['DOMAIN'] + "_major_version = " + str (env['MAJOR']) + ";\n"
277     text += "int " + env['DOMAIN'] + "_minor_version = " + str (env['MINOR']) + ";\n"
278     text += "int " + env['DOMAIN'] + "_micro_version = " + str (env['MICRO']) + ";\n"
279     
280     try:
281         o = file (target[0].get_path(), 'w')
282         o.write (text)
283         o.close ()
284     except IOError:
285         print "Could not open", target[0].get_path(), " for writing\n"
286         sys.exit (-1)
287
288     text  = "#ifndef __" + env['DOMAIN'] + "_version_h__\n"
289     text += "#define __" + env['DOMAIN'] + "_version_h__\n"
290     text += "extern const char* " + env['DOMAIN'] + "_revision;\n"
291     text += "extern int " + env['DOMAIN'] + "_major_version;\n"
292     text += "extern int " + env['DOMAIN'] + "_minor_version;\n"
293     text += "extern int " + env['DOMAIN'] + "_micro_version;\n"
294     text += "#endif /* __" + env['DOMAIN'] + "_version_h__ */\n"
295     
296     try:
297         o = file (target[1].get_path(), 'w')
298         o.write (text)
299         o.close ()
300     except IOError:
301         print "Could not open", target[1].get_path(), " for writing\n"
302         sys.exit (-1)
303         
304     return None
305
306 version_bld = Builder (action = version_builder)
307 env.Append (BUILDERS = {'VersionBuild' : version_bld})
308
309 #
310 # a builder that makes a hard link from the 'source' executable to a name with
311 # a "build ID" based on the most recent CVS activity that might be reasonably
312 # related to version activity. this relies on the idea that the SConscript
313 # file that builds the executable is updated with new version info and committed
314 # to the source code repository whenever things change.
315 #
316
317 def versioned_builder(target,source,env):
318     w, r = os.popen2( "LANG= svn info | awk '/^Revision:/ { print $2}'")
319     
320     last_revision = r.readline().strip()
321     w.close()
322     r.close()
323     if last_revision == "":
324         print "No SVN info found - versioned executable cannot be built"
325         return -1
326     
327     print "The current build ID is " + last_revision
328     
329     tagged_executable = source[0].get_path() + '-' + last_revision
330     
331     if os.path.exists (tagged_executable):
332         print "Replacing existing executable with the same build tag."
333         os.unlink (tagged_executable)
334     
335     return os.link (source[0].get_path(), tagged_executable)
336
337 verbuild = Builder (action = versioned_builder)
338 env.Append (BUILDERS = {'VersionedExecutable' : verbuild})
339
340 #
341 # source tar file builder
342 #
343
344 def distcopy (target, source, env):
345     treedir = str (target[0])
346     
347     try:
348         os.mkdir (treedir)
349     except OSError, (errnum, strerror):
350         if errnum != errno.EEXIST:
351             print 'mkdir ', treedir, ':', strerror
352     
353     cmd = 'tar cf - '
354     #
355     # we don't know what characters might be in the file names
356     # so quote them all before passing them to the shell
357     #
358     all_files = ([ str(s) for s in source ])
359     cmd += " ".join ([ "'%s'" % quoted for quoted in all_files])
360     cmd += ' | (cd ' + treedir + ' && tar xf -)'
361     p = os.popen (cmd)
362     return p.close ()
363
364 def tarballer (target, source, env):
365     cmd = 'tar -jcf ' + str (target[0]) +  ' ' + str(source[0]) + "  --exclude '*~'"
366     print 'running ', cmd, ' ... '
367     p = os.popen (cmd)
368     return p.close ()
369
370 dist_bld = Builder (action = distcopy,
371                     target_factory = SCons.Node.FS.default_fs.Entry,
372                     source_factory = SCons.Node.FS.default_fs.Entry,
373                     multi = 1)
374
375 tarball_bld = Builder (action = tarballer,
376                        target_factory = SCons.Node.FS.default_fs.Entry,
377                        source_factory = SCons.Node.FS.default_fs.Entry)
378
379 env.Append (BUILDERS = {'Distribute' : dist_bld})
380 env.Append (BUILDERS = {'Tarball' : tarball_bld})
381
382 #
383 # Make sure they know what they are doing
384 #
385
386 if env['VST']:
387     if os.path.isfile('.personal_use_only'):
388         print "Enabling VST support. Note that distributing a VST-enabled ardour\nis a violation of several different licences.\nBuild with VST=false if you intend to distribute ardour to others."
389     else:
390         sys.stdout.write ("Are you building Ardour for personal use (rather than distribution to others)? [no]: ")
391         answer = sys.stdin.readline ()
392         answer = answer.rstrip().strip()
393         if answer == "yes" or answer == "y":
394             fh = open('.personal_use_only', 'w')
395             fh.close()
396             print "OK, VST support will be enabled"
397         else:
398             print 'You cannot build Ardour with VST support for distribution to others.\nIt is a violation of several different licenses. Build with VST=false.'
399             sys.exit (-1);
400 else:
401     if os.path.isfile('.personal_use_only'):
402         os.remove('.personal_use_only')
403
404
405 #######################
406 # Dependency Checking #
407 #######################
408
409 deps = \
410 {
411         'glib-2.0'             : '2.10.1',
412         'gthread-2.0'          : '2.10.1',
413         'gtk+-2.0'             : '2.8.1',
414         'libxml-2.0'           : '2.6.0',
415         'samplerate'           : '0.1.0',
416         'raptor'               : '1.4.2',
417         'lrdf'                 : '0.4.0',
418         'jack'                 : '0.101.1',
419         'libgnomecanvas-2.0'   : '2.0'
420 }
421
422 def DependenciesRequiredMessage():
423         print 'You do not have the necessary dependencies required to build ardour'
424         print 'Please consult http://ardour.org/building for more information'
425
426 def CheckPKGConfig(context, version):
427      context.Message( 'Checking for pkg-config version >= %s... ' %version )
428      ret = context.TryAction('pkg-config --atleast-pkgconfig-version=%s' % version)[0]
429      context.Result( ret )
430      return ret
431
432 def CheckPKGVersion(context, name, version):
433      context.Message( 'Checking for %s... ' % name )
434      ret = context.TryAction('pkg-config --atleast-version=%s %s' %(version,name) )[0]
435      context.Result( ret )
436      return ret
437
438 conf = Configure(env, custom_tests = { 'CheckPKGConfig' : CheckPKGConfig,
439                                        'CheckPKGVersion' : CheckPKGVersion })
440
441 # I think a more recent version is needed on win32
442 min_pkg_config_version = '0.8.0'
443
444 if not conf.CheckPKGConfig(min_pkg_config_version):
445      print 'pkg-config >= %s not found.' % min_pkg_config_version
446      Exit(1)
447
448 for pkg, version in deps.iteritems():
449         if not conf.CheckPKGVersion( pkg, version ):
450                 print '%s >= %s not found.' %(pkg, version)
451                 DependenciesRequiredMessage()
452                 Exit(1)
453
454 env = conf.Finish()
455
456 # ----------------------------------------------------------------------
457 # Construction environment setup
458 # ----------------------------------------------------------------------
459
460 libraries = { }
461
462 libraries['core'] = LibraryInfo (CCFLAGS = '-Ilibs')
463
464 #libraries['sndfile'] = LibraryInfo()
465 #libraries['sndfile'].ParseConfig('pkg-config --cflags --libs sndfile')
466
467 libraries['lrdf'] = LibraryInfo()
468 libraries['lrdf'].ParseConfig('pkg-config --cflags --libs lrdf')
469
470 libraries['raptor'] = LibraryInfo()
471 libraries['raptor'].ParseConfig('pkg-config --cflags --libs raptor')
472
473 libraries['samplerate'] = LibraryInfo()
474 libraries['samplerate'].ParseConfig('pkg-config --cflags --libs samplerate')
475
476 if env['FFT_ANALYSIS']:
477         libraries['fftw3f'] = LibraryInfo()
478         libraries['fftw3f'].ParseConfig('pkg-config --cflags --libs fftw3f')
479         #
480         # Check for fftw3 header as well as the library
481         conf = Configure (libraries['fftw3f'])
482         if conf.CheckHeader ('fftw3.h') == False:
483                 print "FFT Analysis cannot be compiled without the FFTW3 headers, which don't seem to be installed"
484                 sys.exit (1)
485         libraries['fftw3f'] = conf.Finish();
486
487 libraries['jack'] = LibraryInfo()
488 libraries['jack'].ParseConfig('pkg-config --cflags --libs jack')
489
490 libraries['xml'] = LibraryInfo()
491 libraries['xml'].ParseConfig('pkg-config --cflags --libs libxml-2.0')
492
493 libraries['xslt'] = LibraryInfo()
494 libraries['xslt'].ParseConfig('pkg-config --cflags --libs libxslt')
495
496 libraries['glib2'] = LibraryInfo()
497 libraries['glib2'].ParseConfig ('pkg-config --cflags --libs glib-2.0')
498 libraries['glib2'].ParseConfig ('pkg-config --cflags --libs gobject-2.0')
499 libraries['glib2'].ParseConfig ('pkg-config --cflags --libs gmodule-2.0')
500 libraries['glib2'].ParseConfig ('pkg-config --cflags --libs gthread-2.0')
501
502 libraries['gtk2'] = LibraryInfo()
503 libraries['gtk2'].ParseConfig ('pkg-config --cflags --libs gtk+-2.0')
504
505 libraries['pango'] = LibraryInfo()
506 libraries['pango'].ParseConfig ('pkg-config --cflags --libs pango')
507
508 libraries['libgnomecanvas2'] = LibraryInfo()
509 libraries['libgnomecanvas2'].ParseConfig ('pkg-config --cflags --libs libgnomecanvas-2.0')
510
511 #libraries['flowcanvas'] = LibraryInfo(LIBS='flowcanvas', LIBPATH='#/libs/flowcanvas', CPPPATH='#libs/flowcanvas')
512
513 # The Ardour Control Protocol Library
514
515 libraries['ardour_cp'] = LibraryInfo (LIBS='ardour_cp', LIBPATH='#libs/surfaces/control_protocol',
516                                       CPPPATH='#libs/surfaces/control_protocol')
517
518 # The Ardour backend/engine
519
520 libraries['ardour'] = LibraryInfo (LIBS='ardour', LIBPATH='#libs/ardour', CPPPATH='#libs/ardour')
521 libraries['midi++2'] = LibraryInfo (LIBS='midi++', LIBPATH='#libs/midi++2', CPPPATH='#libs/midi++2')
522 libraries['pbd']    = LibraryInfo (LIBS='pbd', LIBPATH='#libs/pbd', CPPPATH='#libs/pbd')
523 libraries['gtkmm2ext'] = LibraryInfo (LIBS='gtkmm2ext', LIBPATH='#libs/gtkmm2ext', CPPPATH='#libs/gtkmm2ext')
524
525
526 # SCons should really do this for us
527
528 conf = Configure (env)
529
530 have_cxx = conf.TryAction (Action (str(env['CXX']) + ' --version'))
531 if have_cxx[0] != 1:
532     print "This system has no functional C++ compiler. You cannot build Ardour from source without one."
533     sys.exit (1)
534 else:
535     print "Congratulations, you have a functioning C++ compiler."
536
537 env = conf.Finish()
538
539
540 #
541 # Compiler flags and other system-dependent stuff
542 #
543
544 opt_flags = []
545 if env['GPROFILE'] == 1:
546     debug_flags = [ '-g', '-pg' ]
547 else:
548     debug_flags = [ '-g' ]
549
550 # guess at the platform, used to define compiler flags
551
552 config_guess = os.popen("tools/config.guess").read()[:-1]
553
554 config_cpu = 0
555 config_arch = 1
556 config_kernel = 2
557 config_os = 3
558 config = config_guess.split ("-")
559
560 print "system triple: " + config_guess
561
562 # Autodetect
563 if env['DIST_TARGET'] == 'auto':
564     if config[config_arch] == 'apple':
565         # The [.] matches to the dot after the major version, "." would match any character
566         if re.search ("darwin[0-7][.]", config[config_kernel]) != None:
567             env['DIST_TARGET'] = 'panther'
568         else:
569             env['DIST_TARGET'] = 'tiger'
570     else:
571         if re.search ("x86_64", config[config_cpu]) != None:
572             env['DIST_TARGET'] = 'x86_64'
573         elif re.search("i[0-5]86", config[config_cpu]) != None:
574             env['DIST_TARGET'] = 'i386'
575         elif re.search("powerpc", config[config_cpu]) != None:
576             env['DIST_TARGET'] = 'powerpc'
577         else:
578             env['DIST_TARGET'] = 'i686'
579     print "\n*******************************"
580     print "detected DIST_TARGET = " + env['DIST_TARGET']
581     print "*******************************\n"
582
583
584 if config[config_cpu] == 'powerpc' and env['DIST_TARGET'] != 'none':
585     #
586     # Apple/PowerPC optimization options
587     #
588     # -mcpu=7450 does not reliably work with gcc 3.*
589     #
590     if env['DIST_TARGET'] == 'panther' or env['DIST_TARGET'] == 'tiger':
591         if config[config_arch] == 'apple':
592             ## opt_flags.extend ([ "-mcpu=7450", "-faltivec"])
593             # to support g3s but still have some optimization for above
594             opt_flags.extend ([ "-mcpu=G3", "-mtune=7450"])
595         else:
596             opt_flags.extend ([ "-mcpu=7400", "-maltivec", "-mabi=altivec"])
597     else:
598         opt_flags.extend([ "-mcpu=750", "-mmultiple" ])
599     opt_flags.extend (["-mhard-float", "-mpowerpc-gfxopt"])
600     opt_flags.extend (["-Os"])
601
602 elif ((re.search ("i[0-9]86", config[config_cpu]) != None) or (re.search ("x86_64", config[config_cpu]) != None)) and env['DIST_TARGET'] != 'none':
603     
604     build_host_supports_sse = 0
605     
606     debug_flags.append ("-DARCH_X86")
607     opt_flags.append ("-DARCH_X86")
608     
609     if config[config_kernel] == 'linux' :
610         
611         if env['DIST_TARGET'] != 'i386':
612             
613             flag_line = os.popen ("cat /proc/cpuinfo | grep '^flags'").read()[:-1]
614             x86_flags = flag_line.split (": ")[1:][0].split ()
615             
616             if "mmx" in x86_flags:
617                 opt_flags.append ("-mmmx")
618             if "sse" in x86_flags:
619                 build_host_supports_sse = 1
620             if "3dnow" in x86_flags:
621                 opt_flags.append ("-m3dnow")
622             
623             if config[config_cpu] == "i586":
624                 opt_flags.append ("-march=i586")
625             elif config[config_cpu] == "i686":
626                 opt_flags.append ("-march=i686")
627     
628     if ((env['DIST_TARGET'] == 'i686') or (env['DIST_TARGET'] == 'x86_64')) and build_host_supports_sse:
629         opt_flags.extend (["-msse", "-mfpmath=sse", "-DUSE_XMMINTRIN"])
630         debug_flags.extend (["-msse", "-mfpmath=sse", "-DUSE_XMMINTRIN"])
631 # end of processor-specific section
632
633 # optimization section
634 if env['FPU_OPTIMIZATION']:
635     if env['DIST_TARGET'] == 'tiger':
636         opt_flags.append ("-DBUILD_VECLIB_OPTIMIZATIONS")
637         debug_flags.append ("-DBUILD_VECLIB_OPTIMIZATIONS")
638         libraries['core'].Append(LINKFLAGS= '-framework Accelerate')
639     elif env['DIST_TARGET'] == 'i686' or env['DIST_TARGET'] == 'x86_64':
640         opt_flags.append ("-DBUILD_SSE_OPTIMIZATIONS")
641         debug_flags.append ("-DBUILD_SSE_OPTIMIZATIONS")
642         if env['DIST_TARGET'] == 'x86_64':
643             opt_flags.append ("-DUSE_X86_64_ASM")
644             debug_flags.append ("-DUSE_X86_64_ASM")
645         if build_host_supports_sse != 1:
646             print "\nWarning: you are building Ardour with SSE support even though your system does not support these instructions. (This may not be an error, especially if you are a package maintainer)"
647 # end optimization section
648
649 # handle x86/x86_64 libdir properly
650
651 if env['DIST_TARGET'] == 'x86_64':
652     env['LIBDIR']='lib64'
653 else:
654     env['LIBDIR']='lib'
655
656 #
657 # save off guessed arch element in an env
658 #
659 env.Append(CONFIG_ARCH=config[config_arch])
660
661
662 #
663 # ARCH="..." overrides all
664 #
665
666 if env['ARCH'] != '':
667     opt_flags = env['ARCH'].split()
668
669 #
670 # prepend boiler plate optimization flags
671 #
672
673 opt_flags[:0] = [
674     "-O3",
675     "-fomit-frame-pointer",
676     "-ffast-math",
677     "-fstrength-reduce",
678     "-pipe"
679     ]
680
681 if env['DEBUG'] == 1:
682     env.Append(CCFLAGS=" ".join (debug_flags))
683     env.Append(LINKFLAGS=" ".join (debug_flags))
684 else:
685     env.Append(CCFLAGS=" ".join (opt_flags))
686     env.Append(LINKFLAGS=" ".join (opt_flags))
687
688 if env['UNIVERSAL'] == 1:
689     env.Append(CCFLAGS="-arch i386 -arch ppc")
690     env.Append(LINKFLAGS="-arch i386 -arch ppc")
691
692 #
693 # warnings flags
694 #
695
696 env.Append(CCFLAGS="-Wall")
697 env.Append(CXXFLAGS="-Woverloaded-virtual")
698
699 if env['EXTRA_WARN']:
700     env.Append(CCFLAGS="-Wextra -pedantic -ansi")
701     env.Append(CXXFLAGS="-ansi")
702 #    env.Append(CFLAGS="-iso")
703
704 if env['LIBLO']:
705     env.Append(CCFLAGS="-DHAVE_LIBLO")
706
707
708 #
709 # fix scons nitpickiness on APPLE
710 #
711
712
713 def prep_libcheck(topenv, libinfo):
714     if topenv['DIST_TARGET'] == 'panther' or topenv['DIST_TARGET'] == 'tiger':
715         #
716         # rationale: GTK-Quartz uses jhbuild and installs to /opt/gtk by default.
717         #            All libraries needed should be built against this location
718         if topenv['GTKOSX']:
719                 libinfo.Append(CCFLAGS="-I/opt/gtk/include", LINKFLAGS="-L/opt/gtk/lib")
720         libinfo.Append(CCFLAGS="-I/opt/local/include", LINKFLAGS="-L/opt/local/lib")
721
722 prep_libcheck(env, env)
723
724 #
725 # Check for libusb
726
727 libraries['usb'] = LibraryInfo ()
728 prep_libcheck(env, libraries['usb'])
729
730 conf = Configure (libraries['usb'])
731 if conf.CheckLib ('usb', 'usb_interrupt_write'):
732     have_libusb = True
733 else:
734     have_libusb = False
735
736 # check for linux/input.h while we're at it for powermate
737 if conf.CheckHeader('linux/input.h'):
738     have_linux_input = True
739 else:
740     have_linux_input = False
741
742 libraries['usb'] = conf.Finish ()
743
744 #
745 # Check for FLAC
746
747 libraries['flac'] = LibraryInfo ()
748 prep_libcheck(env, libraries['flac'])
749 libraries['flac'].Append(CCFLAGS="-I/usr/local/include", LINKFLAGS="-L/usr/local/lib")
750
751 #
752 # june 1st 2007: look for a function that is in FLAC 1.1.2 and not in later versions
753 #                since the version of libsndfile we have internally does not support
754 #                the new API that libFLAC has adopted
755 #
756
757 conf = Configure (libraries['flac'])
758 if conf.CheckLib ('FLAC', 'FLAC__seekable_stream_decoder_init', language='CXX'):
759     conf.env.Append(CCFLAGS='-DHAVE_FLAC')
760     use_flac = True
761 else:
762     use_flac = False
763     
764 libraries['flac'] = conf.Finish ()
765
766 # or if that fails...
767 #libraries['flac']    = LibraryInfo (LIBS='FLAC')
768
769 # boost (we don't link against boost, just use some header files)
770
771 libraries['boost'] = LibraryInfo ()
772 prep_libcheck(env, libraries['boost'])
773 libraries['boost'].Append(CCFLAGS="-I/usr/local/include", LINKFLAGS="-L/usr/local/lib")
774 conf = Configure (libraries['boost'])
775 if conf.CheckHeader ('boost/shared_ptr.hpp', language='CXX') == False:
776         print "Boost header files do not appear to be installed."
777         sys.exit (1)
778     
779 libraries['boost'] = conf.Finish ()
780
781 #
782 # Check for liblo
783
784 if env['LIBLO']:
785     libraries['lo'] = LibraryInfo ()
786     prep_libcheck(env, libraries['lo'])
787
788     conf = Configure (libraries['lo'])
789     if conf.CheckLib ('lo', 'lo_server_new') == False:
790         print "liblo does not appear to be installed."
791         sys.exit (1)
792     
793     libraries['lo'] = conf.Finish ()
794
795 #
796 # Check for dmalloc
797
798 libraries['dmalloc'] = LibraryInfo ()
799 prep_libcheck(env, libraries['dmalloc'])
800
801 #
802 # look for the threaded version
803 #
804
805 conf = Configure (libraries['dmalloc'])
806 if conf.CheckLib ('dmallocth', 'dmalloc_shutdown'):
807     have_libdmalloc = True
808 else:
809     have_libdmalloc = False
810
811 libraries['dmalloc'] = conf.Finish ()
812
813 #
814 # Audio/MIDI library (needed for MIDI, since audio is all handled via JACK)
815 #
816
817 conf = Configure(env)
818
819 if conf.CheckCHeader('alsa/asoundlib.h'):
820     libraries['sysmidi'] = LibraryInfo (LIBS='asound')
821     env['SYSMIDI'] = 'ALSA Sequencer'
822     subst_dict['%MIDITAG%'] = "seq"
823     subst_dict['%MIDITYPE%'] = "alsa/sequencer"
824 elif conf.CheckCHeader('/System/Library/Frameworks/CoreMIDI.framework/Headers/CoreMIDI.h'):
825     # this line is needed because scons can't handle -framework in ParseConfig() yet.
826     if env['GTKOSX']:
827         # We need Carbon as well as the rest
828         libraries['sysmidi'] = LibraryInfo (
829                 LINKFLAGS = ' -framework CoreMIDI -framework CoreFoundation -framework CoreAudio -framework CoreServices -framework AudioUnit -framework AudioToolbox -framework Carbon -bind_at_load' )
830     else:
831         libraries['sysmidi'] = LibraryInfo (
832                 LINKFLAGS = ' -framework CoreMIDI -framework CoreFoundation -framework CoreAudio -framework CoreServices -framework AudioUnit -framework AudioToolbox -bind_at_load' )
833     env['SYSMIDI'] = 'CoreMIDI'
834     subst_dict['%MIDITAG%'] = "ardour"
835     subst_dict['%MIDITYPE%'] = "coremidi"
836 else:
837     print "It appears you don't have the required MIDI libraries installed. For Linux this means you are missing the development package for ALSA libraries."
838     sys.exit (1)
839
840 env = conf.Finish()
841
842 if env['SYSLIBS']:
843
844     syslibdeps = \
845     {
846         'sigc++-2.0'           : '2.0',
847         'gtkmm-2.4'            : '2.8',
848         'libgnomecanvasmm-2.6' : '2.12.0'
849     }
850
851     conf = Configure(env, custom_tests = { 'CheckPKGConfig' : CheckPKGConfig,
852                     'CheckPKGVersion' : CheckPKGVersion })
853
854     for pkg, version in syslibdeps.iteritems():
855         if not conf.CheckPKGVersion( pkg, version ):
856             print '%s >= %s not found.' %(pkg, version)
857             DependenciesRequiredMessage()
858             Exit(1)
859         
860     env = conf.Finish()
861     
862     libraries['sigc2'] = LibraryInfo()
863     libraries['sigc2'].ParseConfig('pkg-config --cflags --libs sigc++-2.0')
864     libraries['glibmm2'] = LibraryInfo()
865     libraries['glibmm2'].ParseConfig('pkg-config --cflags --libs glibmm-2.4')
866     libraries['cairomm'] = LibraryInfo()
867     libraries['cairomm'].ParseConfig('pkg-config --cflags --libs cairomm-1.0')
868     libraries['gdkmm2'] = LibraryInfo()
869     libraries['gdkmm2'].ParseConfig ('pkg-config --cflags --libs gdkmm-2.4')
870     libraries['gtkmm2'] = LibraryInfo()
871     libraries['gtkmm2'].ParseConfig ('pkg-config --cflags --libs gtkmm-2.4')
872     libraries['atkmm'] = LibraryInfo()
873     libraries['atkmm'].ParseConfig ('pkg-config --cflags --libs atkmm-1.6')
874     libraries['pangomm'] = LibraryInfo()
875     libraries['pangomm'].ParseConfig ('pkg-config --cflags --libs pangomm-1.4')
876     libraries['libgnomecanvasmm'] = LibraryInfo()
877     libraries['libgnomecanvasmm'].ParseConfig ('pkg-config --cflags --libs libgnomecanvasmm-2.6')
878
879 #
880 # cannot use system one for the time being
881 #
882     
883     libraries['sndfile-ardour'] = LibraryInfo(LIBS='libsndfile-ardour',
884                                     LIBPATH='#libs/libsndfile',
885                                     CPPPATH=['#libs/libsndfile/src'])
886
887 #    libraries['libglademm'] = LibraryInfo()
888 #    libraries['libglademm'].ParseConfig ('pkg-config --cflags --libs libglademm-2.4')
889
890 #    libraries['flowcanvas'] = LibraryInfo(LIBS='flowcanvas', LIBPATH='#/libs/flowcanvas', CPPPATH='#libs/flowcanvas')
891     libraries['soundtouch'] = LibraryInfo()
892     libraries['soundtouch'].ParseConfig ('pkg-config --cflags --libs soundtouch-1.0')
893     # Comment the previous line and uncomment this for Debian:
894     #libraries['soundtouch'].ParseConfig ('pkg-config --cflags --libs libSoundTouch')
895
896     libraries['appleutility'] = LibraryInfo(LIBS='libappleutility',
897                                             LIBPATH='#libs/appleutility',
898                                             CPPPATH='#libs/appleutility')
899     
900     coredirs = [
901         'templates'
902     ]
903     
904     subdirs = [
905         'libs/libsndfile',
906         'libs/pbd',
907         'libs/midi++2',
908         'libs/ardour',
909     # these are unconditionally included but have
910     # tests internally to avoid compilation etc
911     # if VST is not set
912         'libs/fst',
913         'vst',
914     # this is unconditionally included but has
915     # tests internally to avoid compilation etc
916     # if COREAUDIO is not set
917         'libs/appleutility'
918         ]
919     
920     gtk_subdirs = [
921 #        'libs/flowcanvas',
922         'libs/gtkmm2ext',
923         'gtk2_ardour',
924         'libs/clearlooks'
925         ]
926
927 else:
928     libraries['sigc2'] = LibraryInfo(LIBS='sigc++2',
929                                     LIBPATH='#libs/sigc++2',
930                                     CPPPATH='#libs/sigc++2')
931     libraries['glibmm2'] = LibraryInfo(LIBS='glibmm2',
932                                     LIBPATH='#libs/glibmm2',
933                                     CPPPATH='#libs/glibmm2')
934     libraries['pangomm'] = LibraryInfo(LIBS='pangomm',
935                                     LIBPATH='#libs/gtkmm2/pango',
936                                     CPPPATH='#libs/gtkmm2/pango')
937     libraries['atkmm'] = LibraryInfo(LIBS='atkmm',
938                                      LIBPATH='#libs/gtkmm2/atk',
939                                      CPPPATH='#libs/gtkmm2/atk')
940     libraries['gdkmm2'] = LibraryInfo(LIBS='gdkmm2',
941                                       LIBPATH='#libs/gtkmm2/gdk',
942                                       CPPPATH='#libs/gtkmm2/gdk')
943     libraries['gtkmm2'] = LibraryInfo(LIBS='gtkmm2',
944                                      LIBPATH="#libs/gtkmm2/gtk",
945                                      CPPPATH='#libs/gtkmm2/gtk/')
946     libraries['libgnomecanvasmm'] = LibraryInfo(LIBS='libgnomecanvasmm',
947                                                 LIBPATH='#libs/libgnomecanvasmm',
948                                                 CPPPATH='#libs/libgnomecanvasmm')
949     
950     libraries['soundtouch'] = LibraryInfo(LIBS='soundtouch',
951                                           LIBPATH='#libs/soundtouch',
952                                           CPPPATH=['#libs', '#libs/soundtouch'])
953     libraries['sndfile-ardour'] = LibraryInfo(LIBS='libsndfile-ardour',
954                                     LIBPATH='#libs/libsndfile',
955                                     CPPPATH=['#libs/libsndfile', '#libs/libsndfile/src'])
956 #    libraries['libglademm'] = LibraryInfo(LIBS='libglademm',
957 #                                          LIBPATH='#libs/libglademm',
958 #                                          CPPPATH='#libs/libglademm')
959     libraries['appleutility'] = LibraryInfo(LIBS='libappleutility',
960                                             LIBPATH='#libs/appleutility',
961                                             CPPPATH='#libs/appleutility')
962
963     coredirs = [
964         'libs/soundtouch',
965         'templates'
966     ]
967     
968     subdirs = [
969         'libs/sigc++2',
970         'libs/libsndfile',
971         'libs/pbd',
972         'libs/midi++2',
973         'libs/ardour',
974     # these are unconditionally included but have
975     # tests internally to avoid compilation etc
976     # if VST is not set
977         'libs/fst',
978         'vst',
979     # this is unconditionally included but has
980     # tests internally to avoid compilation etc
981     # if COREAUDIO is not set
982         'libs/appleutility'
983         ]
984     
985     gtk_subdirs = [
986         'libs/glibmm2',
987         'libs/gtkmm2/pango',
988         'libs/gtkmm2/atk',
989         'libs/gtkmm2/gdk',
990         'libs/gtkmm2/gtk',
991         'libs/libgnomecanvasmm',
992 #       'libs/flowcanvas',
993         'libs/gtkmm2ext',
994         'gtk2_ardour',
995         'libs/clearlooks'
996         ]
997
998 #
999 # * always build the LGPL control protocol lib, since we link against it from libardour
1000 # * ditto for generic MIDI
1001 # * tranzport checks whether it should build internally, but we need here so that
1002 #   its included in the tarball
1003 #
1004
1005 surface_subdirs = [ 'libs/surfaces/control_protocol',
1006                     'libs/surfaces/generic_midi',
1007                     'libs/surfaces/tranzport',
1008                     'libs/surfaces/mackie',
1009                     'libs/surfaces/powermate'
1010                     ]
1011
1012 if env['SURFACES']:
1013     if have_libusb:
1014         env['TRANZPORT'] = 1
1015     else:
1016         env['TRANZPORT'] = 0
1017         print 'Disabled building Tranzport code because libusb could not be found'
1018
1019     if have_linux_input:
1020         env['POWERMATE'] = 1
1021     else:
1022         env['POWERMATE'] = 0
1023         print 'Disabled building Powermate code because linux/input.h could not be found'
1024
1025     if os.access ('libs/surfaces/sony9pin', os.F_OK):
1026         surface_subdirs += [ 'libs/surfaces/sony9pin' ]
1027 else:
1028     env['POWERMATE'] = 0
1029     env['TRANZPORT'] = 0
1030     
1031 opts.Save('scache.conf', env)
1032 Help(opts.GenerateHelpText(env))
1033
1034 if os.environ.has_key('PATH'):
1035     env.Append(PATH = os.environ['PATH'])
1036
1037 if os.environ.has_key('PKG_CONFIG_PATH'):
1038     env.Append(PKG_CONFIG_PATH = os.environ['PKG_CONFIG_PATH'])
1039
1040 if os.environ.has_key('CC'):
1041     env['CC'] = os.environ['CC']
1042
1043 if os.environ.has_key('CXX'):
1044     env['CXX'] = os.environ['CXX']
1045
1046 if os.environ.has_key('DISTCC_HOSTS'):
1047     env['ENV']['DISTCC_HOSTS'] = os.environ['DISTCC_HOSTS']
1048     env['ENV']['HOME'] = os.environ['HOME']
1049
1050 final_prefix = '$PREFIX'
1051
1052 if env['DESTDIR'] :
1053     install_prefix = '$DESTDIR/$PREFIX'
1054 else:
1055     install_prefix = env['PREFIX']
1056
1057 subst_dict['%INSTALL_PREFIX%'] = install_prefix;
1058 subst_dict['%FINAL_PREFIX%'] = final_prefix;
1059 subst_dict['%PREFIX%'] = final_prefix;
1060
1061 if env['PREFIX'] == '/usr':
1062     final_config_prefix = '/etc'
1063 else:
1064     final_config_prefix = env['PREFIX'] + '/etc'
1065
1066 config_prefix = '$DESTDIR' + final_config_prefix
1067
1068 #
1069 # everybody needs this
1070 #
1071
1072 env.Merge ([ libraries['core'] ])
1073
1074
1075 #
1076 # i18n support
1077 #
1078
1079 conf = Configure (env)
1080 if env['NLS']:
1081     nls_error = 'This system is not configured for internationalized applications.  An english-only version will be built:'
1082     print 'Checking for internationalization support ...'
1083     have_gettext = conf.TryAction(Action('xgettext --version'))
1084     if have_gettext[0] != 1:
1085         nls_error += ' No xgettext command.'
1086         env['NLS'] = 0
1087     else:
1088         print "Found xgettext"
1089     
1090     have_msgmerge = conf.TryAction(Action('msgmerge --version'))
1091     if have_msgmerge[0] != 1:
1092         nls_error += ' No msgmerge command.'
1093         env['NLS'] = 0
1094     else:
1095         print "Found msgmerge"
1096     
1097     if not conf.CheckCHeader('libintl.h'):
1098         nls_error += ' No libintl.h.'
1099         env['NLS'] = 0
1100         
1101     if env['NLS'] == 0:
1102         print nls_error
1103     else:
1104         print "International version will be built."
1105 env = conf.Finish()
1106
1107 if env['NLS'] == 1:
1108     env.Append(CCFLAGS="-DENABLE_NLS")
1109
1110 Export('env install_prefix final_prefix config_prefix final_config_prefix libraries i18n ardour_version subst_dict use_flac')
1111
1112 #
1113 # the configuration file may be system dependent
1114 #
1115
1116 conf = env.Configure ()
1117
1118 if conf.CheckCHeader('/System/Library/Frameworks/CoreAudio.framework/Versions/A/Headers/CoreAudio.h'):
1119     subst_dict['%JACK_INPUT%'] = "coreaudio:Built-in Audio:in"
1120     subst_dict['%JACK_OUTPUT%'] = "coreaudio:Built-in Audio:out"
1121 else:
1122     subst_dict['%JACK_INPUT%'] = "alsa_pcm:playback_"
1123     subst_dict['%JACK_OUTPUT%'] = "alsa_pcm:capture_"
1124
1125 # posix_memalign available
1126 if not conf.CheckFunc('posix_memalign'):
1127     print 'Did not find posix_memalign(), using malloc'
1128     env.Append(CCFLAGS='-DNO_POSIX_MEMALIGN')
1129
1130
1131 env = conf.Finish()
1132
1133 # generate the per-user and system rc files from the same source
1134
1135 sysrcbuild = env.SubstInFile ('ardour_system.rc','ardour.rc.in', SUBST_DICT = subst_dict)
1136
1137 # add to the substitution dictionary
1138
1139 subst_dict['%VERSION%'] = ardour_version[0:3]
1140 subst_dict['%EXTRA_VERSION%'] = ardour_version[3:]
1141 subst_dict['%REVISION_STRING%'] = ''
1142 if os.path.exists('.svn'):
1143     subst_dict['%REVISION_STRING%'] = '.' + fetch_svn_revision ('.') + 'svn'
1144
1145 # specbuild = env.SubstInFile ('ardour.spec','ardour.spec.in', SUBST_DICT = subst_dict)
1146
1147 the_revision = env.Command ('frobnicatory_decoy', [], create_stored_revision)
1148
1149 env.Alias('revision', the_revision)
1150 env.Alias('install', env.Install(os.path.join(config_prefix, 'ardour2'), 'ardour_system.rc'))
1151
1152 Default (sysrcbuild)
1153
1154 # source tarball
1155
1156 Precious (env['DISTTREE'])
1157
1158 env.Distribute (env['DISTTREE'],
1159                [ 'SConstruct', 'svn_revision.h',
1160                   'COPYING', 'PACKAGER_README', 'README',
1161                   'ardour.rc.in',
1162                   'tools/config.guess',
1163                   'icons/icon/ardour_icon_mac_mask.png',
1164                   'icons/icon/ardour_icon_mac.png',
1165                   'icons/icon/ardour_icon_tango_16px_blue.png',
1166                   'icons/icon/ardour_icon_tango_16px_red.png',
1167                   'icons/icon/ardour_icon_tango_22px_blue.png',
1168                   'icons/icon/ardour_icon_tango_22px_red.png',
1169                   'icons/icon/ardour_icon_tango_32px_blue.png',
1170                   'icons/icon/ardour_icon_tango_32px_red.png',
1171                   'icons/icon/ardour_icon_tango_48px_blue.png',
1172                   'icons/icon/ardour_icon_tango_48px_red.png'
1173                   ] +
1174                 glob.glob ('DOCUMENTATION/AUTHORS*') +
1175                 glob.glob ('DOCUMENTATION/CONTRIBUTORS*') +
1176                 glob.glob ('DOCUMENTATION/TRANSLATORS*') +
1177                 glob.glob ('DOCUMENTATION/BUILD*') +
1178                 glob.glob ('DOCUMENTATION/FAQ*') +
1179                 glob.glob ('DOCUMENTATION/README*')
1180                 )
1181
1182 srcdist = env.Tarball(env['TARBALL'], [ env['DISTTREE'], the_revision ])
1183 env.Alias ('srctar', srcdist)
1184
1185 #
1186 # don't leave the distree around
1187 #
1188
1189 env.AddPreAction (env['DISTTREE'], Action ('rm -rf ' + str (File (env['DISTTREE']))))
1190 env.AddPostAction (srcdist, Action ('rm -rf ' + str (File (env['DISTTREE']))))
1191
1192 #
1193 # the subdirs
1194 #
1195
1196 for subdir in coredirs:
1197     SConscript (subdir + '/SConscript')
1198
1199 for sublistdir in [ subdirs, gtk_subdirs, surface_subdirs ]:
1200     for subdir in sublistdir:
1201         SConscript (subdir + '/SConscript')
1202
1203 # cleanup
1204 env.Clean ('scrub', [ 'scache.conf', '.sconf_temp', '.sconsign.dblite', 'config.log'])
1205