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