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