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