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