Fix indentation.
[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 sndfile')
1075     
1076     libraries['taglib'] = LibraryInfo(LIBS='libtaglib',
1077                                       LIBPATH='#libs/taglib',
1078                                       CPPPATH=['#libs/taglib/headers','#libs/taglib/headers/taglib'])
1079
1080     coredirs = [
1081         'templates',
1082         'manual'
1083     ]
1084     
1085     subdirs = [
1086         'libs/pbd',
1087         'libs/midi++2',
1088         'libs/ardour',
1089         'libs/vamp-sdk',
1090         'libs/vamp-plugins/',
1091     # these are unconditionally included but have
1092     # tests internally to avoid compilation etc
1093     # if VST is not set
1094         'libs/fst',
1095         'vst',
1096     # this is unconditionally included but has
1097     # tests internally to avoid compilation etc
1098     # if COREAUDIO is not set
1099         'libs/appleutility'
1100         ]
1101     
1102     gtk_subdirs = [
1103 #        'libs/flowcanvas',
1104         'libs/gtkmm2ext',
1105         'gtk2_ardour',
1106         'libs/clearlooks'
1107         ]
1108
1109 else:
1110     libraries['cairo'] = LibraryInfo()
1111     libraries['cairo'].ParseConfig('pkg-config --cflags --libs cairo')
1112     
1113     libraries['gtk2-unix-print'] = LibraryInfo()
1114     libraries['gtk2-unix-print'].ParseConfig('pkg-config --cflags --libs gtk+-unix-print-2.0')
1115     
1116     libraries['sigc2'] = LibraryInfo(LIBS='sigc++2',
1117                                     LIBPATH='#libs/sigc++2',
1118                                     CPPPATH='#libs/sigc++2')
1119     libraries['glibmm2'] = LibraryInfo(LIBS='glibmm2',
1120                                     LIBPATH='#libs/glibmm2',
1121                                     CPPPATH='#libs/glibmm2/glib')
1122     libraries['pangomm'] = LibraryInfo(LIBS='pangomm',
1123                                     LIBPATH='#libs/gtkmm2/pango',
1124                                     CPPPATH='#libs/gtkmm2/pango')
1125     libraries['atkmm'] = LibraryInfo(LIBS='atkmm',
1126                                      LIBPATH='#libs/gtkmm2/atk',
1127                                      CPPPATH='#libs/gtkmm2/atk')
1128     libraries['cairomm'] = LibraryInfo(LIBS='cairomm',
1129                                       LIBPATH='#libs/cairomm',
1130                                       CPPPATH='#libs/cairomm')
1131     libraries['gdkmm2'] = LibraryInfo(LIBS='gdkmm2',
1132                                       LIBPATH='#libs/gtkmm2/gdk',
1133                                       CPPPATH='#libs/gtkmm2/gdk')
1134     libraries['gtkmm2'] = LibraryInfo(LIBS='gtkmm2',
1135                                      LIBPATH="#libs/gtkmm2/gtk",
1136                                      CPPPATH='#libs/gtkmm2/gtk/')
1137     libraries['libgnomecanvasmm'] = LibraryInfo(LIBS='libgnomecanvasmm',
1138                                                 LIBPATH='#libs/libgnomecanvasmm',
1139                                                 CPPPATH='#libs/libgnomecanvasmm')
1140     
1141     libraries['soundtouch'] = LibraryInfo(LIBS='soundtouch',
1142                                           LIBPATH='#libs/soundtouch',
1143                                           CPPPATH=['#libs', '#libs/soundtouch'])
1144     libraries['taglib'] = LibraryInfo(LIBS='libtaglib',
1145                                       LIBPATH='#libs/taglib',
1146                                       CPPPATH=['#libs/taglib/headers','#libs/taglib/headers/taglib'])
1147 #    libraries['libglademm'] = LibraryInfo(LIBS='libglademm',
1148 #                                          LIBPATH='#libs/libglademm',
1149 #                                          CPPPATH='#libs/libglademm')
1150     libraries['appleutility'] = LibraryInfo(LIBS='libappleutility',
1151                                             LIBPATH='#libs/appleutility',
1152                                             CPPPATH='#libs/appleutility')
1153
1154     coredirs = [
1155         'templates',
1156         'manual'
1157     ]
1158     
1159     subdirs = [
1160         'libs/sigc++2',
1161         'libs/taglib',
1162         'libs/pbd',
1163         'libs/midi++2',
1164         'libs/ardour',
1165         'libs/vamp-sdk',
1166         'libs/vamp-plugins/',
1167     # these are unconditionally included but have
1168     # tests internally to avoid compilation etc
1169     # if VST is not set
1170         'libs/fst',
1171         'vst',
1172     # this is unconditionally included but has
1173     # tests internally to avoid compilation etc
1174     # if COREAUDIO is not set
1175         'libs/appleutility'
1176         ]
1177     
1178     gtk_subdirs = [
1179         'libs/glibmm2',
1180         'libs/gtkmm2/pango',
1181         'libs/gtkmm2/atk',
1182         'libs/gtkmm2/gdk',
1183         'libs/gtkmm2/gtk',
1184         'libs/libgnomecanvasmm',
1185         'libs/gtkmm2ext',
1186         'gtk2_ardour',
1187         'libs/clearlooks',
1188         'libs/cairomm'
1189         ]
1190
1191 #
1192 # * always build the LGPL control protocol lib, since we link against it from libardour
1193 # * ditto for generic MIDI
1194 # * tranzport checks whether it should build internally, but we need here so that
1195 #   its included in the tarball
1196 #
1197
1198 surface_subdirs = [ 'libs/surfaces/control_protocol',
1199                     'libs/surfaces/generic_midi',
1200                     'libs/surfaces/tranzport',
1201                     'libs/surfaces/mackie',
1202                     'libs/surfaces/powermate'
1203                     ]
1204
1205 if env['SURFACES']:
1206     if have_libusb:
1207         env['TRANZPORT'] = 1
1208     else:
1209         env['TRANZPORT'] = 0
1210         print 'Disabled building Tranzport code because libusb could not be found'
1211
1212     if have_linux_input:
1213         env['POWERMATE'] = 1
1214     else:
1215         env['POWERMATE'] = 0
1216         print 'Disabled building Powermate code because linux/input.h could not be found'
1217
1218     if os.access ('libs/surfaces/sony9pin', os.F_OK):
1219         surface_subdirs += [ 'libs/surfaces/sony9pin' ]
1220 else:
1221     env['POWERMATE'] = 0
1222     env['TRANZPORT'] = 0
1223
1224 #
1225 # timestretch libraries
1226 #
1227
1228 timefx_subdirs = ['libs/soundtouch']
1229 if env['RUBBERBAND']:
1230     timefx_subdirs += ['libs/rubberband']
1231
1232 opts.Save('scache.conf', env)
1233 Help(opts.GenerateHelpText(env))
1234
1235 final_prefix = '$PREFIX'
1236
1237 if env['DESTDIR'] :
1238     install_prefix = '$DESTDIR/$PREFIX'
1239 else:
1240     install_prefix = env['PREFIX']
1241
1242 subst_dict['%INSTALL_PREFIX%'] = install_prefix;
1243 subst_dict['%FINAL_PREFIX%'] = final_prefix;
1244 subst_dict['%PREFIX%'] = final_prefix;
1245
1246 if env['PREFIX'] == '/usr':
1247     final_config_prefix = '/etc'
1248 else:
1249     final_config_prefix = env['PREFIX'] + '/etc'
1250
1251 config_prefix = '$DESTDIR' + final_config_prefix
1252
1253 #
1254 # everybody needs this
1255 #
1256
1257 env.Merge ([ libraries['core'] ])
1258
1259
1260 #
1261 # i18n support
1262 #
1263
1264 conf = Configure (env)
1265 if env['NLS']:
1266     nls_error = 'This system is not configured for internationalized applications.  An english-only version will be built:'
1267     print 'Checking for internationalization support ...'
1268     have_gettext = conf.TryAction(Action('xgettext --version'))
1269     if have_gettext[0] != 1:
1270         nls_error += ' No xgettext command.'
1271         env['NLS'] = 0
1272     else:
1273         print "Found xgettext"
1274     
1275     have_msgmerge = conf.TryAction(Action('msgmerge --version'))
1276     if have_msgmerge[0] != 1:
1277         nls_error += ' No msgmerge command.'
1278         env['NLS'] = 0
1279     else:
1280         print "Found msgmerge"
1281     
1282     if not conf.CheckCHeader('libintl.h'):
1283         nls_error += ' No libintl.h.'
1284         env['NLS'] = 0
1285         
1286     if env['NLS'] == 0:
1287         print nls_error
1288     else:
1289         print "International version will be built."
1290 env = conf.Finish()
1291
1292 if env['NLS'] == 1:
1293     env.Append(CCFLAGS="-DENABLE_NLS")
1294
1295 Export('env install_prefix final_prefix config_prefix final_config_prefix libraries i18n ardour_version subst_dict')
1296
1297 #
1298 # the configuration file may be system dependent
1299 #
1300
1301 conf = env.Configure ()
1302
1303 if conf.CheckCHeader('/System/Library/Frameworks/CoreAudio.framework/Versions/A/Headers/CoreAudio.h'):
1304     subst_dict['%JACK_INPUT%'] = "coreaudio:Built-in Audio:in"
1305     subst_dict['%JACK_OUTPUT%'] = "coreaudio:Built-in Audio:out"
1306 else:
1307     subst_dict['%JACK_INPUT%'] = "alsa_pcm:playback_"
1308     subst_dict['%JACK_OUTPUT%'] = "alsa_pcm:capture_"
1309
1310 # posix_memalign available
1311 if not conf.CheckFunc('posix_memalign'):
1312     print 'Did not find posix_memalign(), using malloc'
1313     env.Append(CCFLAGS='-DNO_POSIX_MEMALIGN')
1314
1315
1316 env = conf.Finish()
1317
1318 # generate the per-user and system rc files from the same source
1319
1320 sysrcbuild = env.SubstInFile ('ardour_system.rc','ardour.rc.in', SUBST_DICT = subst_dict)
1321
1322 # add to the substitution dictionary
1323
1324 subst_dict['%VERSION%'] = ardour_version[0:3]
1325 subst_dict['%EXTRA_VERSION%'] = ardour_version[3:]
1326 subst_dict['%REVISION_STRING%'] = ''
1327 if os.path.exists('.svn'):
1328     subst_dict['%REVISION_STRING%'] = '.' + fetch_svn_revision ('.') + 'svn'
1329
1330 # specbuild = env.SubstInFile ('ardour.spec','ardour.spec.in', SUBST_DICT = subst_dict)
1331
1332 the_revision = env.Command ('frobnicatory_decoy', [], create_stored_revision)
1333 remove_ardour = env.Command ('frobnicatory_decoy2', [],
1334                              [ Delete ('$PREFIX/etc/ardour3'),
1335                                Delete ('$PREFIX/lib/ardour3'),
1336                                Delete ('$PREFIX/bin/ardour3'),
1337                                Delete ('$PREFIX/share/ardour3')])
1338
1339 env.Alias('revision', the_revision)
1340 env.Alias('install', env.Install(os.path.join(config_prefix, 'ardour3'), 'ardour_system.rc'))
1341 env.Alias('uninstall', remove_ardour)
1342
1343 Default (sysrcbuild)
1344
1345 # source tarball
1346
1347 Precious (env['DISTTREE'])
1348
1349 env.Distribute (env['DISTTREE'],
1350                [ 'SConstruct', 'svn_revision.h',
1351                   'COPYING', 'PACKAGER_README', 'README',
1352                   'ardour.rc.in',
1353                   'tools/config.guess',
1354                   'icons/icon/ardour_icon_mac_mask.png',
1355                   'icons/icon/ardour_icon_mac.png',
1356                   'icons/icon/ardour_icon_tango_16px_blue.png',
1357                   'icons/icon/ardour_icon_tango_16px_red.png',
1358                   'icons/icon/ardour_icon_tango_22px_blue.png',
1359                   'icons/icon/ardour_icon_tango_22px_red.png',
1360                   'icons/icon/ardour_icon_tango_32px_blue.png',
1361                   'icons/icon/ardour_icon_tango_32px_red.png',
1362                   'icons/icon/ardour_icon_tango_48px_blue.png',
1363                   'icons/icon/ardour_icon_tango_48px_red.png'
1364                   ] +
1365                 glob.glob ('DOCUMENTATION/AUTHORS*') +
1366                 glob.glob ('DOCUMENTATION/CONTRIBUTORS*') +
1367                 glob.glob ('DOCUMENTATION/TRANSLATORS*') +
1368                 glob.glob ('DOCUMENTATION/BUILD*') +
1369                 glob.glob ('DOCUMENTATION/FAQ*') +
1370                 glob.glob ('DOCUMENTATION/README*')
1371                 )
1372
1373 srcdist = env.Tarball(env['TARBALL'], [ env['DISTTREE'], the_revision ])
1374 env.Alias ('srctar', srcdist)
1375
1376 #
1377 # don't leave the distree around
1378 #
1379
1380 env.AddPreAction (env['DISTTREE'], Action ('rm -rf ' + str (File (env['DISTTREE']))))
1381 env.AddPostAction (srcdist, Action ('rm -rf ' + str (File (env['DISTTREE']))))
1382
1383 #
1384 # Update revision info before going into subdirs
1385 #
1386
1387 create_stored_revision()
1388
1389 #
1390 # the subdirs
1391 #
1392
1393 for subdir in coredirs:
1394     SConscript (subdir + '/SConscript')
1395
1396 for sublistdir in [ subdirs, timefx_subdirs, gtk_subdirs, surface_subdirs ]:
1397     for subdir in sublistdir:
1398         SConscript (subdir + '/SConscript')
1399
1400 # cleanup
1401 env.Clean ('scrub', [ 'scache.conf', '.sconf_temp', '.sconsign.dblite', 'config.log'])
1402