Merge with 2.0-ongoing R2988
[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 = '3.0'
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.6.0\"'):
535                 libraries['slv2'] = LibraryInfo()
536                 libraries['slv2'].ParseConfig('pkg-config --cflags --libs slv2')
537                 env.Append (CCFLAGS="-DHAVE_LV2")
538         else:
539                 print 'Building Ardour with LV2 support requires SLV2 >= 0.6.0'
540                 print 'WARNING: SLV2 not found, or too old.  Ardour will be built without LV2 support.'
541                 print 'Until the 2.3 release, Ardour requires SLV2 out of SVN.'
542                 print 'Testing would be very much appreciated!  svn co http://svn.drobilla.net/lad/slv2'
543                 env['LV2'] = 0
544         conf.Finish()
545 else:
546         print 'LV2 support is not enabled.  Build with \'scons LV2=1\' to enable.'
547
548 libraries['jack'] = LibraryInfo()
549 libraries['jack'].ParseConfig('pkg-config --cflags --libs jack')
550
551 libraries['xml'] = LibraryInfo()
552 libraries['xml'].ParseConfig('pkg-config --cflags --libs libxml-2.0')
553
554 libraries['xslt'] = LibraryInfo()
555 libraries['xslt'].ParseConfig('pkg-config --cflags --libs libxslt')
556
557 libraries['glib2'] = LibraryInfo()
558 libraries['glib2'].ParseConfig ('pkg-config --cflags --libs glib-2.0')
559 libraries['glib2'].ParseConfig ('pkg-config --cflags --libs gobject-2.0')
560 libraries['glib2'].ParseConfig ('pkg-config --cflags --libs gmodule-2.0')
561 libraries['glib2'].ParseConfig ('pkg-config --cflags --libs gthread-2.0')
562
563 libraries['gtk2'] = LibraryInfo()
564 libraries['gtk2'].ParseConfig ('pkg-config --cflags --libs gtk+-2.0')
565
566 libraries['pango'] = LibraryInfo()
567 libraries['pango'].ParseConfig ('pkg-config --cflags --libs pango')
568
569 libraries['libgnomecanvas2'] = LibraryInfo()
570 libraries['libgnomecanvas2'].ParseConfig ('pkg-config --cflags --libs libgnomecanvas-2.0')
571
572 #libraries['flowcanvas'] = LibraryInfo(LIBS='flowcanvas', LIBPATH='#/libs/flowcanvas', CPPPATH='#libs/flowcanvas')
573
574 # The Ardour Control Protocol Library
575
576 libraries['ardour_cp'] = LibraryInfo (LIBS='ardour_cp', LIBPATH='#libs/surfaces/control_protocol',
577                                       CPPPATH='#libs/surfaces/control_protocol')
578
579 # The Ardour backend/engine
580
581 libraries['ardour'] = LibraryInfo (LIBS='ardour', LIBPATH='#libs/ardour', CPPPATH='#libs/ardour')
582 libraries['midi++2'] = LibraryInfo (LIBS='midi++', LIBPATH='#libs/midi++2', CPPPATH='#libs/midi++2')
583 libraries['pbd']    = LibraryInfo (LIBS='pbd', LIBPATH='#libs/pbd', CPPPATH='#libs/pbd')
584 libraries['gtkmm2ext'] = LibraryInfo (LIBS='gtkmm2ext', LIBPATH='#libs/gtkmm2ext', CPPPATH='#libs/gtkmm2ext')
585
586
587 # SCons should really do this for us
588
589 conf = env.Configure ()
590
591 have_cxx = conf.TryAction (Action (str(env['CXX']) + ' --version'))
592 if have_cxx[0] != 1:
593     print "This system has no functional C++ compiler. You cannot build Ardour from source without one."
594     sys.exit (1)
595 else:
596     print "Congratulations, you have a functioning C++ compiler."
597
598 env = conf.Finish()
599
600
601 #
602 # Compiler flags and other system-dependent stuff
603 #
604
605 opt_flags = []
606 if env['GPROFILE'] == 1:
607     debug_flags = [ '-g', '-pg' ]
608 else:
609     debug_flags = [ '-g' ]
610
611 # guess at the platform, used to define compiler flags
612
613 config_guess = os.popen("tools/config.guess").read()[:-1]
614
615 config_cpu = 0
616 config_arch = 1
617 config_kernel = 2
618 config_os = 3
619 config = config_guess.split ("-")
620
621 print "system triple: " + config_guess
622
623 # Autodetect
624 if env['DIST_TARGET'] == 'auto':
625     if config[config_arch] == 'apple':
626         # The [.] matches to the dot after the major version, "." would match any character
627         if re.search ("darwin[0-7][.]", config[config_kernel]) != None:
628             env['DIST_TARGET'] = 'panther'
629         if re.search ("darwin8[.]", config[config_kernel]) != None:
630             env['DIST_TARGET'] = 'tiger'
631         else:
632             env['DIST_TARGET'] = 'leopard'
633     else:
634         if re.search ("x86_64", config[config_cpu]) != None:
635             env['DIST_TARGET'] = 'x86_64'
636         elif re.search("i[0-5]86", config[config_cpu]) != None:
637             env['DIST_TARGET'] = 'i386'
638         elif re.search("powerpc", config[config_cpu]) != None:
639             env['DIST_TARGET'] = 'powerpc'
640         else:
641             env['DIST_TARGET'] = 'i686'
642     print "\n*******************************"
643     print "detected DIST_TARGET = " + env['DIST_TARGET']
644     print "*******************************\n"
645
646
647 if config[config_cpu] == 'powerpc' and env['DIST_TARGET'] != 'none':
648     #
649     # Apple/PowerPC optimization options
650     #
651     # -mcpu=7450 does not reliably work with gcc 3.*
652     #
653     if env['DIST_TARGET'] == 'panther' or env['DIST_TARGET'] == 'tiger':
654         if config[config_arch] == 'apple':
655             ## opt_flags.extend ([ "-mcpu=7450", "-faltivec"])
656             # to support g3s but still have some optimization for above
657             opt_flags.extend ([ "-mcpu=G3", "-mtune=7450"])
658         else:
659             opt_flags.extend ([ "-mcpu=7400", "-maltivec", "-mabi=altivec"])
660     else:
661         opt_flags.extend([ "-mcpu=750", "-mmultiple" ])
662     opt_flags.extend (["-mhard-float", "-mpowerpc-gfxopt"])
663     opt_flags.extend (["-Os"])
664
665 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':
666     
667     build_host_supports_sse = 0
668     
669     debug_flags.append ("-DARCH_X86")
670     opt_flags.append ("-DARCH_X86")
671     
672     if config[config_kernel] == 'linux' :
673         
674         if env['DIST_TARGET'] != 'i386':
675             
676             flag_line = os.popen ("cat /proc/cpuinfo | grep '^flags'").read()[:-1]
677             x86_flags = flag_line.split (": ")[1:][0].split ()
678             
679             if "mmx" in x86_flags:
680                 opt_flags.append ("-mmmx")
681             if "sse" in x86_flags:
682                 build_host_supports_sse = 1
683             if "3dnow" in x86_flags:
684                 opt_flags.append ("-m3dnow")
685             
686             if config[config_cpu] == "i586":
687                 opt_flags.append ("-march=i586")
688             elif config[config_cpu] == "i686":
689                 opt_flags.append ("-march=i686")
690     
691     if ((env['DIST_TARGET'] == 'i686') or (env['DIST_TARGET'] == 'x86_64')) and build_host_supports_sse:
692         opt_flags.extend (["-msse", "-mfpmath=sse", "-DUSE_XMMINTRIN"])
693         debug_flags.extend (["-msse", "-mfpmath=sse", "-DUSE_XMMINTRIN"])
694 # end of processor-specific section
695
696 # optimization section
697 if env['FPU_OPTIMIZATION']:
698     if env['DIST_TARGET'] == 'tiger' or env['DIST_TARGET'] == 'leopard':
699         opt_flags.append ("-DBUILD_VECLIB_OPTIMIZATIONS");
700         debug_flags.append ("-DBUILD_VECLIB_OPTIMIZATIONS");
701         libraries['core'].Append(LINKFLAGS= '-framework Accelerate')
702     elif env['DIST_TARGET'] == 'i686' or env['DIST_TARGET'] == 'x86_64':
703         opt_flags.append ("-DBUILD_SSE_OPTIMIZATIONS")
704         debug_flags.append ("-DBUILD_SSE_OPTIMIZATIONS")
705         if env['DIST_TARGET'] == 'x86_64':
706             opt_flags.append ("-DUSE_X86_64_ASM")
707             debug_flags.append ("-DUSE_X86_64_ASM")
708         if build_host_supports_sse != 1:
709             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)"
710 # end optimization section
711
712 # handle x86/x86_64 libdir properly
713
714 if env['DIST_TARGET'] == 'x86_64':
715     env['LIBDIR']='lib64'
716 else:
717     env['LIBDIR']='lib'
718
719 #
720 # a single way to test if we're on OS X
721 #
722
723 if env['DIST_TARGET'] in ['panther', 'tiger', 'leopard' ]:
724     env['IS_OSX'] = 1
725     # force tiger or later, to avoid issues on PPC which defaults
726     # back to 10.1 if we don't tell it otherwise.
727     env.Append (CCFLAGS="-DMAC_OS_X_VERSION_MIN_REQUIRED=1040")
728 else:
729     env['IS_OSX'] = 0
730
731 #
732 # save off guessed arch element in an env
733 #
734 env.Append(CONFIG_ARCH=config[config_arch])
735
736
737 #
738 # ARCH="..." overrides all
739 #
740
741 if env['ARCH'] != '':
742     opt_flags = env['ARCH'].split()
743
744 #
745 # prepend boiler plate optimization flags
746 #
747
748 opt_flags[:0] = [
749     "-O3",
750     "-fomit-frame-pointer",
751     "-ffast-math",
752     "-fstrength-reduce",
753     "-pipe"
754     ]
755
756 if env['DEBUG'] == 1:
757     env.Append(CCFLAGS=" ".join (debug_flags))
758     env.Append(LINKFLAGS=" ".join (debug_flags))
759 else:
760     env.Append(CCFLAGS=" ".join (opt_flags))
761     env.Append(LINKFLAGS=" ".join (opt_flags))
762
763 if env['UNIVERSAL'] == 1:
764     env.Append(CCFLAGS="-arch i386 -arch ppc")
765     env.Append(LINKFLAGS="-arch i386 -arch ppc")
766
767 #
768 # warnings flags
769 #
770
771 env.Append(CCFLAGS="-Wall")
772 env.Append(CXXFLAGS="-Woverloaded-virtual")
773
774 if env['EXTRA_WARN']:
775     env.Append(CCFLAGS="-Wextra -pedantic -ansi")
776     env.Append(CXXFLAGS="-ansi")
777 #    env.Append(CFLAGS="-iso")
778
779 if env['LIBLO']:
780     env.Append(CCFLAGS="-DHAVE_LIBLO")
781
782
783 #
784 # fix scons nitpickiness on APPLE
785 #
786
787
788 def prep_libcheck(topenv, libinfo):
789     if topenv['IS_OSX']:
790         #
791         # rationale: GTK-Quartz uses jhbuild and installs to /opt/gtk by default.
792         #            All libraries needed should be built against this location
793         if topenv['GTKOSX']:
794                 libinfo.Append(CPPPATH="/opt/gtk/include", LIBPATH="/opt/gtk/lib")
795                 libinfo.Append(CXXFLAGS="-I/opt/gtk/include", LINKFLAGS="-L/opt/gtk/lib")
796         libinfo.Append(CPPPATH="/opt/local/include", LIBPATH="/opt/local/lib")
797         libinfo.Append(CXXFLAGS="-I/opt/local/include", LINKFLAGS="-L/opt/local/lib")
798
799 prep_libcheck(env, env)
800
801
802 #
803 # these are part of the Ardour source tree because they are C++
804
805
806 libraries['vamp'] = LibraryInfo (LIBS='vampsdk',
807                                  LIBPATH='#libs/vamp-sdk',
808                                  CPPPATH='#libs/vamp-sdk')
809 libraries['vamphost'] = LibraryInfo (LIBS='vamphostsdk',
810                                  LIBPATH='#libs/vamp-sdk',
811                                  CPPPATH='#libs/vamp-sdk')
812
813 env['RUBBERBAND'] = False
814
815 #conf = Configure (env)
816 #
817 #if conf.CheckHeader ('fftw3.h'):
818 #    env['RUBBERBAND'] = True
819 #    libraries['rubberband'] = LibraryInfo (LIBS='rubberband',
820 #                                           LIBPATH='#libs/rubberband',
821 #                                           CPPPATH='#libs/rubberband',
822 #                                           CCFLAGS='-DUSE_RUBBERBAND')
823 #else:
824 #    print ""
825 #    print "-------------------------------------------------------------------------"
826 #    print "You do not have the FFTW single-precision development package installed."
827 #    print "This prevents Ardour from using the Rubberband library for timestretching"
828 #    print "and pitchshifting. It will fall back on SoundTouch for timestretch, and "
829 #    print "pitchshifting will not be available."
830 #    print "-------------------------------------------------------------------------"
831 #    print ""
832 #
833 #conf.Finish()
834
835 #
836 # Check for libusb
837
838 libraries['usb'] = LibraryInfo ()
839 prep_libcheck(env, libraries['usb'])
840
841 conf = Configure (libraries['usb'])
842 if conf.CheckLib ('usb', 'usb_interrupt_write'):
843     have_libusb = True
844 else:
845     have_libusb = False
846
847 # check for linux/input.h while we're at it for powermate
848 if conf.CheckHeader('linux/input.h'):
849     have_linux_input = True
850 else:
851     have_linux_input = False
852
853 libraries['usb'] = conf.Finish ()
854
855 #
856 # Check for FLAC
857
858 libraries['flac'] = LibraryInfo ()
859 prep_libcheck(env, libraries['flac'])
860 libraries['flac'].Append(CPPPATH="/usr/local/include", LIBPATH="/usr/local/lib")
861
862 #
863 # june 1st 2007: look for a function that is in FLAC 1.1.2 and not in later versions
864 #                since the version of libsndfile we have internally does not support
865 #                the new API that libFLAC has adopted
866 #
867
868 conf = Configure (libraries['flac'])
869 if conf.CheckLib ('FLAC', 'FLAC__seekable_stream_decoder_init', language='CXX'):
870     conf.env.Append(CCFLAGS='-DHAVE_FLAC')
871     use_flac = True
872 else:
873     use_flac = False
874     
875 libraries['flac'] = conf.Finish ()
876
877 # or if that fails...
878 #libraries['flac']    = LibraryInfo (LIBS='FLAC')
879
880 # boost (we don't link against boost, just use some header files)
881
882 libraries['boost'] = LibraryInfo ()
883 prep_libcheck(env, libraries['boost'])
884 libraries['boost'].Append(CPPPATH="/usr/local/include", LIBPATH="/usr/local/lib")
885 conf = Configure (libraries['boost'])
886 if conf.CheckHeader ('boost/shared_ptr.hpp', language='CXX') == False:
887         print "Boost header files do not appear to be installed."
888         sys.exit (1)
889     
890 libraries['boost'] = conf.Finish ()
891
892 #
893 # Check for liblo
894
895 if env['LIBLO']:
896     libraries['lo'] = LibraryInfo ()
897     prep_libcheck(env, libraries['lo'])
898
899     conf = Configure (libraries['lo'])
900     if conf.CheckLib ('lo', 'lo_server_new') == False:
901         print "liblo does not appear to be installed."
902         sys.exit (1)
903     
904     libraries['lo'] = conf.Finish ()
905
906 #
907 # Check for dmalloc
908
909 libraries['dmalloc'] = LibraryInfo ()
910 prep_libcheck(env, libraries['dmalloc'])
911
912 #
913 # look for the threaded version
914 #
915
916 conf = Configure (libraries['dmalloc'])
917 if conf.CheckLib ('dmallocth', 'dmalloc_shutdown'):
918     have_libdmalloc = True
919 else:
920     have_libdmalloc = False
921
922 libraries['dmalloc'] = conf.Finish ()
923
924 #
925 # Audio/MIDI library (needed for MIDI, since audio is all handled via JACK)
926 #
927
928 conf = Configure(env)
929     
930 # ALSA, for engine dialog
931 libraries['asound'] = LibraryInfo ()
932
933 if conf.CheckCHeader('alsa/asoundlib.h'):
934     libraries['asound'] = LibraryInfo (LIBS='asound')
935
936 if conf.CheckCHeader('jack/midiport.h'):
937     libraries['sysmidi'] = LibraryInfo (LIBS='jack')
938     env['SYSMIDI'] = 'JACK MIDI'
939     subst_dict['%MIDITAG%'] = "control"
940     subst_dict['%MIDITYPE%'] = "jack"
941     print "Using JACK MIDI"
942 elif conf.CheckCHeader('alsa/asoundlib.h'):
943     libraries['sysmidi'] = LibraryInfo (LIBS='asound')
944     env['SYSMIDI'] = 'ALSA Sequencer'
945     subst_dict['%MIDITAG%'] = "seq"
946     subst_dict['%MIDITYPE%'] = "alsa/sequencer"
947     print "Using ALSA MIDI"
948 elif conf.CheckCHeader('/System/Library/Frameworks/CoreMIDI.framework/Headers/CoreMIDI.h'):
949     # this line is needed because scons can't handle -framework in ParseConfig() yet.
950     if env['GTKOSX']:
951         # We need Carbon as well as the rest
952         libraries['sysmidi'] = LibraryInfo (
953                 LINKFLAGS = ' -framework CoreMIDI -framework CoreFoundation -framework CoreAudio -framework CoreServices -framework AudioUnit -framework AudioToolbox -framework Carbon -bind_at_load' )
954     else:
955         libraries['sysmidi'] = LibraryInfo (
956                 LINKFLAGS = ' -framework CoreMIDI -framework CoreFoundation -framework CoreAudio -framework CoreServices -framework AudioUnit -framework AudioToolbox -bind_at_load' )
957     env['SYSMIDI'] = 'CoreMIDI'
958     subst_dict['%MIDITAG%'] = "ardour"
959     subst_dict['%MIDITYPE%'] = "coremidi"
960 else:
961     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."
962     sys.exit (1)
963
964 env = conf.Finish()
965
966 if env['SYSLIBS']:
967
968     syslibdeps = \
969     {
970         'sigc++-2.0'           : '2.0',
971         'gtkmm-2.4'            : '2.8',
972         'libgnomecanvasmm-2.6' : '2.12.0'
973     }
974
975     conf = Configure(env, custom_tests = { 'CheckPKGConfig' : CheckPKGConfig,
976                     'CheckPKGVersion' : CheckPKGVersion })
977
978     for pkg, version in syslibdeps.iteritems():
979         if not conf.CheckPKGVersion( pkg, version ):
980             print '%s >= %s not found.' %(pkg, version)
981             DependenciesRequiredMessage()
982             Exit(1)
983     
984     env = conf.Finish()
985     
986     libraries['sigc2'] = LibraryInfo()
987     libraries['sigc2'].ParseConfig('pkg-config --cflags --libs sigc++-2.0')
988     libraries['glibmm2'] = LibraryInfo()
989     libraries['glibmm2'].ParseConfig('pkg-config --cflags --libs glibmm-2.4')
990     libraries['cairo'] = LibraryInfo()
991     libraries['cairo'].ParseConfig('pkg-config --cflags --libs cairo')
992     libraries['cairomm'] = LibraryInfo()
993     libraries['cairomm'].ParseConfig('pkg-config --cflags --libs cairomm-1.0')
994     libraries['gdkmm2'] = LibraryInfo()
995     libraries['gdkmm2'].ParseConfig ('pkg-config --cflags --libs gdkmm-2.4')
996     libraries['gtkmm2'] = LibraryInfo()
997     libraries['gtkmm2'].ParseConfig ('pkg-config --cflags --libs gtkmm-2.4')
998     libraries['atkmm'] = LibraryInfo()
999     libraries['atkmm'].ParseConfig ('pkg-config --cflags --libs atkmm-1.6')
1000     libraries['pangomm'] = LibraryInfo()
1001     libraries['pangomm'].ParseConfig ('pkg-config --cflags --libs pangomm-1.4')
1002     libraries['libgnomecanvasmm'] = LibraryInfo()
1003     libraries['libgnomecanvasmm'].ParseConfig ('pkg-config --cflags --libs libgnomecanvasmm-2.6')
1004
1005 #
1006 # cannot use system one for the time being
1007 #
1008     
1009     libraries['sndfile-ardour'] = LibraryInfo(LIBS='libsndfile-ardour',
1010                                     LIBPATH='#libs/libsndfile',
1011                                     CPPPATH=['#libs/libsndfile/src'])
1012
1013 #    libraries['libglademm'] = LibraryInfo()
1014 #    libraries['libglademm'].ParseConfig ('pkg-config --cflags --libs libglademm-2.4')
1015
1016 #    libraries['flowcanvas'] = LibraryInfo(LIBS='flowcanvas', LIBPATH='#/libs/flowcanvas', CPPPATH='#libs/flowcanvas')
1017     libraries['soundtouch'] = LibraryInfo()
1018     #libraries['soundtouch'].ParseConfig ('pkg-config --cflags --libs soundtouch-1.0')
1019     # Comment the previous line and uncomment this for Debian:
1020     libraries['soundtouch'].ParseConfig ('pkg-config --cflags --libs libSoundTouch')
1021
1022     libraries['appleutility'] = LibraryInfo(LIBS='libappleutility',
1023                                             LIBPATH='#libs/appleutility',
1024                                             CPPPATH='#libs/appleutility')
1025     
1026     coredirs = [
1027         'templates'
1028     ]
1029     
1030     subdirs = [
1031         'libs/libsndfile',
1032         'libs/pbd',
1033         'libs/midi++2',
1034         'libs/ardour',
1035         'libs/vamp-sdk',
1036         'libs/vamp-plugins/',
1037     # these are unconditionally included but have
1038     # tests internally to avoid compilation etc
1039     # if VST is not set
1040         'libs/fst',
1041         'vst',
1042     # this is unconditionally included but has
1043     # tests internally to avoid compilation etc
1044     # if COREAUDIO is not set
1045         'libs/appleutility'
1046         ]
1047     
1048     gtk_subdirs = [
1049 #        'libs/flowcanvas',
1050         'libs/gtkmm2ext',
1051         'gtk2_ardour',
1052         'libs/clearlooks'
1053         ]
1054
1055 else:
1056     libraries['cairo'] = LibraryInfo()
1057     libraries['cairo'].ParseConfig('pkg-config --cflags --libs cairo')
1058     
1059     libraries['gtk2-unix-print'] = LibraryInfo()
1060     libraries['gtk2-unix-print'].ParseConfig('pkg-config --cflags --libs gtk+-unix-print-2.0')
1061     
1062     libraries['sigc2'] = LibraryInfo(LIBS='sigc++2',
1063                                     LIBPATH='#libs/sigc++2',
1064                                     CPPPATH='#libs/sigc++2')
1065     libraries['glibmm2'] = LibraryInfo(LIBS='glibmm2',
1066                                     LIBPATH='#libs/glibmm2',
1067                                     CPPPATH='#libs/glibmm2/glib')
1068     libraries['pangomm'] = LibraryInfo(LIBS='pangomm',
1069                                     LIBPATH='#libs/gtkmm2/pango',
1070                                     CPPPATH='#libs/gtkmm2/pango')
1071     libraries['atkmm'] = LibraryInfo(LIBS='atkmm',
1072                                      LIBPATH='#libs/gtkmm2/atk',
1073                                      CPPPATH='#libs/gtkmm2/atk')
1074     libraries['cairomm'] = LibraryInfo(LIBS='cairomm',
1075                                       LIBPATH='#libs/cairomm',
1076                                       CPPPATH='#libs/cairomm')
1077     libraries['gdkmm2'] = LibraryInfo(LIBS='gdkmm2',
1078                                       LIBPATH='#libs/gtkmm2/gdk',
1079                                       CPPPATH='#libs/gtkmm2/gdk')
1080     libraries['gtkmm2'] = LibraryInfo(LIBS='gtkmm2',
1081                                      LIBPATH="#libs/gtkmm2/gtk",
1082                                      CPPPATH='#libs/gtkmm2/gtk/')
1083     libraries['libgnomecanvasmm'] = LibraryInfo(LIBS='libgnomecanvasmm',
1084                                                 LIBPATH='#libs/libgnomecanvasmm',
1085                                                 CPPPATH='#libs/libgnomecanvasmm')
1086     
1087     libraries['soundtouch'] = LibraryInfo(LIBS='soundtouch',
1088                                           LIBPATH='#libs/soundtouch',
1089                                           CPPPATH=['#libs', '#libs/soundtouch'])
1090     libraries['sndfile-ardour'] = LibraryInfo(LIBS='libsndfile-ardour',
1091                                     LIBPATH='#libs/libsndfile',
1092                                     CPPPATH=['#libs/libsndfile', '#libs/libsndfile/src'])
1093 #    libraries['libglademm'] = LibraryInfo(LIBS='libglademm',
1094 #                                          LIBPATH='#libs/libglademm',
1095 #                                          CPPPATH='#libs/libglademm')
1096     libraries['appleutility'] = LibraryInfo(LIBS='libappleutility',
1097                                             LIBPATH='#libs/appleutility',
1098                                             CPPPATH='#libs/appleutility')
1099
1100     coredirs = [
1101         'templates'
1102     ]
1103     
1104     subdirs = [
1105         'libs/sigc++2',
1106         'libs/libsndfile',
1107         'libs/pbd',
1108         'libs/midi++2',
1109         'libs/ardour',
1110         'libs/vamp-sdk',
1111         'libs/vamp-plugins/',
1112     # these are unconditionally included but have
1113     # tests internally to avoid compilation etc
1114     # if VST is not set
1115         'libs/fst',
1116         'vst',
1117     # this is unconditionally included but has
1118     # tests internally to avoid compilation etc
1119     # if COREAUDIO is not set
1120         'libs/appleutility'
1121         ]
1122     
1123     gtk_subdirs = [
1124         'libs/glibmm2',
1125         'libs/gtkmm2/pango',
1126         'libs/gtkmm2/atk',
1127         'libs/gtkmm2/gdk',
1128         'libs/gtkmm2/gtk',
1129         'libs/libgnomecanvasmm',
1130         'libs/gtkmm2ext',
1131         'gtk2_ardour',
1132         'libs/clearlooks',
1133         'libs/cairomm'
1134         ]
1135
1136 #
1137 # * always build the LGPL control protocol lib, since we link against it from libardour
1138 # * ditto for generic MIDI
1139 # * tranzport checks whether it should build internally, but we need here so that
1140 #   its included in the tarball
1141 #
1142
1143 surface_subdirs = [ 'libs/surfaces/control_protocol',
1144                     'libs/surfaces/generic_midi',
1145                     'libs/surfaces/tranzport',
1146                     'libs/surfaces/mackie',
1147                     'libs/surfaces/powermate'
1148                     ]
1149
1150 if env['SURFACES']:
1151     if have_libusb:
1152         env['TRANZPORT'] = 1
1153     else:
1154         env['TRANZPORT'] = 0
1155         print 'Disabled building Tranzport code because libusb could not be found'
1156
1157     if have_linux_input:
1158         env['POWERMATE'] = 1
1159     else:
1160         env['POWERMATE'] = 0
1161         print 'Disabled building Powermate code because linux/input.h could not be found'
1162
1163     if os.access ('libs/surfaces/sony9pin', os.F_OK):
1164         surface_subdirs += [ 'libs/surfaces/sony9pin' ]
1165 else:
1166     env['POWERMATE'] = 0
1167     env['TRANZPORT'] = 0
1168
1169 #
1170 # timestretch libraries
1171 #
1172
1173 timefx_subdirs = ['libs/soundtouch']
1174 #if env['RUBBERBAND']:
1175 #    timefx_subdirs += ['libs/rubberband']
1176
1177 opts.Save('scache.conf', env)
1178 Help(opts.GenerateHelpText(env))
1179
1180 final_prefix = '$PREFIX'
1181
1182 if env['DESTDIR'] :
1183     install_prefix = '$DESTDIR/$PREFIX'
1184 else:
1185     install_prefix = env['PREFIX']
1186
1187 subst_dict['%INSTALL_PREFIX%'] = install_prefix;
1188 subst_dict['%FINAL_PREFIX%'] = final_prefix;
1189 subst_dict['%PREFIX%'] = final_prefix;
1190
1191 if env['PREFIX'] == '/usr':
1192     final_config_prefix = '/etc'
1193 else:
1194     final_config_prefix = env['PREFIX'] + '/etc'
1195
1196 config_prefix = '$DESTDIR' + final_config_prefix
1197
1198 #
1199 # everybody needs this
1200 #
1201
1202 env.Merge ([ libraries['core'] ])
1203
1204
1205 #
1206 # i18n support
1207 #
1208
1209 conf = Configure (env)
1210 if env['NLS']:
1211     nls_error = 'This system is not configured for internationalized applications.  An english-only version will be built:'
1212     print 'Checking for internationalization support ...'
1213     have_gettext = conf.TryAction(Action('xgettext --version'))
1214     if have_gettext[0] != 1:
1215         nls_error += ' No xgettext command.'
1216         env['NLS'] = 0
1217     else:
1218         print "Found xgettext"
1219     
1220     have_msgmerge = conf.TryAction(Action('msgmerge --version'))
1221     if have_msgmerge[0] != 1:
1222         nls_error += ' No msgmerge command.'
1223         env['NLS'] = 0
1224     else:
1225         print "Found msgmerge"
1226     
1227     if not conf.CheckCHeader('libintl.h'):
1228         nls_error += ' No libintl.h.'
1229         env['NLS'] = 0
1230         
1231     if env['NLS'] == 0:
1232         print nls_error
1233     else:
1234         print "International version will be built."
1235 env = conf.Finish()
1236
1237 if env['NLS'] == 1:
1238     env.Append(CCFLAGS="-DENABLE_NLS")
1239
1240 Export('env install_prefix final_prefix config_prefix final_config_prefix libraries i18n ardour_version subst_dict use_flac')
1241
1242 #
1243 # the configuration file may be system dependent
1244 #
1245
1246 conf = env.Configure ()
1247
1248 if conf.CheckCHeader('/System/Library/Frameworks/CoreAudio.framework/Versions/A/Headers/CoreAudio.h'):
1249     subst_dict['%JACK_INPUT%'] = "coreaudio:Built-in Audio:in"
1250     subst_dict['%JACK_OUTPUT%'] = "coreaudio:Built-in Audio:out"
1251 else:
1252     subst_dict['%JACK_INPUT%'] = "alsa_pcm:playback_"
1253     subst_dict['%JACK_OUTPUT%'] = "alsa_pcm:capture_"
1254
1255 # posix_memalign available
1256 if not conf.CheckFunc('posix_memalign'):
1257     print 'Did not find posix_memalign(), using malloc'
1258     env.Append(CCFLAGS='-DNO_POSIX_MEMALIGN')
1259
1260
1261 env = conf.Finish()
1262
1263 # generate the per-user and system rc files from the same source
1264
1265 sysrcbuild = env.SubstInFile ('ardour_system.rc','ardour.rc.in', SUBST_DICT = subst_dict)
1266
1267 # add to the substitution dictionary
1268
1269 subst_dict['%VERSION%'] = ardour_version[0:3]
1270 subst_dict['%EXTRA_VERSION%'] = ardour_version[3:]
1271 subst_dict['%REVISION_STRING%'] = ''
1272 if os.path.exists('.svn'):
1273     subst_dict['%REVISION_STRING%'] = '.' + fetch_svn_revision ('.') + 'svn'
1274
1275 # specbuild = env.SubstInFile ('ardour.spec','ardour.spec.in', SUBST_DICT = subst_dict)
1276
1277 the_revision = env.Command ('frobnicatory_decoy', [], create_stored_revision)
1278 remove_ardour = env.Command ('frobnicatory_decoy2', [],
1279                              [ Delete ('$PREFIX/etc/ardour3'),
1280                                Delete ('$PREFIX/lib/ardour3'),
1281                                Delete ('$PREFIX/bin/ardour3')])
1282
1283 env.Alias('revision', the_revision)
1284 env.Alias('install', env.Install(os.path.join(config_prefix, 'ardour3'), 'ardour_system.rc'))
1285 env.Alias('uninstall', remove_ardour)
1286
1287 Default (sysrcbuild)
1288
1289 # source tarball
1290
1291 Precious (env['DISTTREE'])
1292
1293 env.Distribute (env['DISTTREE'],
1294                [ 'SConstruct', 'svn_revision.h',
1295                   'COPYING', 'PACKAGER_README', 'README',
1296                   'ardour.rc.in',
1297                   'tools/config.guess',
1298                   'icons/icon/ardour_icon_mac_mask.png',
1299                   'icons/icon/ardour_icon_mac.png',
1300                   'icons/icon/ardour_icon_tango_16px_blue.png',
1301                   'icons/icon/ardour_icon_tango_16px_red.png',
1302                   'icons/icon/ardour_icon_tango_22px_blue.png',
1303                   'icons/icon/ardour_icon_tango_22px_red.png',
1304                   'icons/icon/ardour_icon_tango_32px_blue.png',
1305                   'icons/icon/ardour_icon_tango_32px_red.png',
1306                   'icons/icon/ardour_icon_tango_48px_blue.png',
1307                   'icons/icon/ardour_icon_tango_48px_red.png'
1308                   ] +
1309                 glob.glob ('DOCUMENTATION/AUTHORS*') +
1310                 glob.glob ('DOCUMENTATION/CONTRIBUTORS*') +
1311                 glob.glob ('DOCUMENTATION/TRANSLATORS*') +
1312                 glob.glob ('DOCUMENTATION/BUILD*') +
1313                 glob.glob ('DOCUMENTATION/FAQ*') +
1314                 glob.glob ('DOCUMENTATION/README*')
1315                 )
1316
1317 srcdist = env.Tarball(env['TARBALL'], [ env['DISTTREE'], the_revision ])
1318 env.Alias ('srctar', srcdist)
1319
1320 #
1321 # don't leave the distree around
1322 #
1323
1324 env.AddPreAction (env['DISTTREE'], Action ('rm -rf ' + str (File (env['DISTTREE']))))
1325 env.AddPostAction (srcdist, Action ('rm -rf ' + str (File (env['DISTTREE']))))
1326
1327 #
1328 # the subdirs
1329 #
1330
1331 for subdir in coredirs:
1332     SConscript (subdir + '/SConscript')
1333
1334 for sublistdir in [ subdirs, timefx_subdirs, gtk_subdirs, surface_subdirs ]:
1335     for subdir in sublistdir:
1336         SConscript (subdir + '/SConscript')
1337
1338 # cleanup
1339 env.Clean ('scrub', [ 'scache.conf', '.sconf_temp', '.sconsign.dblite', 'config.log'])
1340