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