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