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