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