520bcdd058b4f5b3e3ba4e89d0cee94db08bad1c
[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['freetype2'] = LibraryInfo()
566 libraries['freetype2'].ParseConfig ('pkg-config --cflags --libs freetype2')
567
568 libraries['gtk2'] = LibraryInfo()
569 libraries['gtk2'].ParseConfig ('pkg-config --cflags --libs gtk+-2.0')
570
571 libraries['pango'] = LibraryInfo()
572 libraries['pango'].ParseConfig ('pkg-config --cflags --libs pango')
573
574 libraries['libgnomecanvas2'] = LibraryInfo()
575 libraries['libgnomecanvas2'].ParseConfig ('pkg-config --cflags --libs libgnomecanvas-2.0')
576
577 #libraries['flowcanvas'] = LibraryInfo(LIBS='flowcanvas', LIBPATH='#/libs/flowcanvas', CPPPATH='#libs/flowcanvas')
578
579 # The Ardour Control Protocol Library
580
581 libraries['ardour_cp'] = LibraryInfo (LIBS='ardour_cp', LIBPATH='#libs/surfaces/control_protocol',
582                                       CPPPATH='#libs/surfaces/control_protocol')
583
584 # The Ardour backend/engine
585
586 libraries['ardour'] = LibraryInfo (LIBS='ardour', LIBPATH='#libs/ardour', CPPPATH='#libs/ardour')
587 libraries['midi++2'] = LibraryInfo (LIBS='midi++', LIBPATH='#libs/midi++2', CPPPATH='#libs/midi++2')
588 libraries['pbd']    = LibraryInfo (LIBS='pbd', LIBPATH='#libs/pbd', CPPPATH='#libs/pbd')
589 libraries['gtkmm2ext'] = LibraryInfo (LIBS='gtkmm2ext', LIBPATH='#libs/gtkmm2ext', CPPPATH='#libs/gtkmm2ext')
590
591
592 # SCons should really do this for us
593
594 conf = env.Configure ()
595
596 have_cxx = conf.TryAction (Action (str(env['CXX']) + ' --version'))
597 if have_cxx[0] != 1:
598     print "This system has no functional C++ compiler. You cannot build Ardour from source without one."
599     sys.exit (1)
600 else:
601     print "Congratulations, you have a functioning C++ compiler."
602
603 env = conf.Finish()
604
605
606 #
607 # Compiler flags and other system-dependent stuff
608 #
609
610 opt_flags = []
611 if env['GPROFILE'] == 1:
612     debug_flags = [ '-g', '-pg' ]
613 else:
614     debug_flags = [ '-g' ]
615
616 # guess at the platform, used to define compiler flags
617
618 config_guess = os.popen("tools/config.guess").read()[:-1]
619
620 config_cpu = 0
621 config_arch = 1
622 config_kernel = 2
623 config_os = 3
624 config = config_guess.split ("-")
625
626 print "system triple: " + config_guess
627
628 # Autodetect
629 if env['DIST_TARGET'] == 'auto':
630     if config[config_arch] == 'apple':
631         # The [.] matches to the dot after the major version, "." would match any character
632         if re.search ("darwin[0-7][.]", config[config_kernel]) != None:
633             env['DIST_TARGET'] = 'panther'
634         if re.search ("darwin8[.]", config[config_kernel]) != None:
635             env['DIST_TARGET'] = 'tiger'
636         else:
637             env['DIST_TARGET'] = 'leopard'
638     else:
639         if re.search ("x86_64", config[config_cpu]) != None:
640             env['DIST_TARGET'] = 'x86_64'
641         elif re.search("i[0-5]86", config[config_cpu]) != None:
642             env['DIST_TARGET'] = 'i386'
643         elif re.search("powerpc", config[config_cpu]) != None:
644             env['DIST_TARGET'] = 'powerpc'
645         else:
646             env['DIST_TARGET'] = 'i686'
647     print "\n*******************************"
648     print "detected DIST_TARGET = " + env['DIST_TARGET']
649     print "*******************************\n"
650
651
652 if config[config_cpu] == 'powerpc' and env['DIST_TARGET'] != 'none':
653     #
654     # Apple/PowerPC optimization options
655     #
656     # -mcpu=7450 does not reliably work with gcc 3.*
657     #
658     if env['DIST_TARGET'] == 'panther' or env['DIST_TARGET'] == 'tiger':
659         if config[config_arch] == 'apple':
660             ## opt_flags.extend ([ "-mcpu=7450", "-faltivec"])
661             # to support g3s but still have some optimization for above
662             opt_flags.extend ([ "-mcpu=G3", "-mtune=7450"])
663         else:
664             opt_flags.extend ([ "-mcpu=7400", "-maltivec", "-mabi=altivec"])
665     else:
666         opt_flags.extend([ "-mcpu=750", "-mmultiple" ])
667     opt_flags.extend (["-mhard-float", "-mpowerpc-gfxopt"])
668     opt_flags.extend (["-Os"])
669
670 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':
671     
672     build_host_supports_sse = 0
673     
674     debug_flags.append ("-DARCH_X86")
675     opt_flags.append ("-DARCH_X86")
676     
677     if config[config_kernel] == 'linux' :
678         
679         if env['DIST_TARGET'] != 'i386':
680             
681             flag_line = os.popen ("cat /proc/cpuinfo | grep '^flags'").read()[:-1]
682             x86_flags = flag_line.split (": ")[1:][0].split ()
683             
684             if "mmx" in x86_flags:
685                 opt_flags.append ("-mmmx")
686             if "sse" in x86_flags:
687                 build_host_supports_sse = 1
688             if "3dnow" in x86_flags:
689                 opt_flags.append ("-m3dnow")
690             
691             if config[config_cpu] == "i586":
692                 opt_flags.append ("-march=i586")
693             elif config[config_cpu] == "i686":
694                 opt_flags.append ("-march=i686")
695     
696     if ((env['DIST_TARGET'] == 'i686') or (env['DIST_TARGET'] == 'x86_64')) and build_host_supports_sse:
697         opt_flags.extend (["-msse", "-mfpmath=sse", "-DUSE_XMMINTRIN"])
698         debug_flags.extend (["-msse", "-mfpmath=sse", "-DUSE_XMMINTRIN"])
699 # end of processor-specific section
700
701 # optimization section
702 if env['FPU_OPTIMIZATION']:
703     if env['DIST_TARGET'] == 'tiger' or env['DIST_TARGET'] == 'leopard':
704         opt_flags.append ("-DBUILD_VECLIB_OPTIMIZATIONS");
705         debug_flags.append ("-DBUILD_VECLIB_OPTIMIZATIONS");
706         libraries['core'].Append(LINKFLAGS= '-framework Accelerate')
707     elif env['DIST_TARGET'] == 'i686' or env['DIST_TARGET'] == 'x86_64':
708         opt_flags.append ("-DBUILD_SSE_OPTIMIZATIONS")
709         debug_flags.append ("-DBUILD_SSE_OPTIMIZATIONS")
710         if env['DIST_TARGET'] == 'x86_64':
711             opt_flags.append ("-DUSE_X86_64_ASM")
712             debug_flags.append ("-DUSE_X86_64_ASM")
713         if build_host_supports_sse != 1:
714             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)"
715 # end optimization section
716
717 # handle x86/x86_64 libdir properly
718
719 if env['DIST_TARGET'] == 'x86_64':
720     env['LIBDIR']='lib64'
721 else:
722     env['LIBDIR']='lib'
723
724 #
725 # a single way to test if we're on OS X
726 #
727
728 if env['DIST_TARGET'] in ['panther', 'tiger', 'leopard' ]:
729     env['IS_OSX'] = 1
730     # force tiger or later, to avoid issues on PPC which defaults
731     # back to 10.1 if we don't tell it otherwise.
732     env.Append (CCFLAGS="-DMAC_OS_X_VERSION_MIN_REQUIRED=1040")
733 else:
734     env['IS_OSX'] = 0
735
736 #
737 # save off guessed arch element in an env
738 #
739 env.Append(CONFIG_ARCH=config[config_arch])
740
741
742 #
743 # ARCH="..." overrides all
744 #
745
746 if env['ARCH'] != '':
747     opt_flags = env['ARCH'].split()
748
749 #
750 # prepend boiler plate optimization flags
751 #
752
753 opt_flags[:0] = [
754     "-O3",
755     "-fomit-frame-pointer",
756     "-ffast-math",
757     "-fstrength-reduce",
758     "-pipe"
759     ]
760
761 if env['DEBUG'] == 1:
762     env.Append(CCFLAGS=" ".join (debug_flags))
763     env.Append(LINKFLAGS=" ".join (debug_flags))
764 else:
765     env.Append(CCFLAGS=" ".join (opt_flags))
766     env.Append(LINKFLAGS=" ".join (opt_flags))
767
768 if env['UNIVERSAL'] == 1:
769     env.Append(CCFLAGS="-arch i386 -arch ppc")
770     env.Append(LINKFLAGS="-arch i386 -arch ppc")
771
772 #
773 # warnings flags
774 #
775
776 env.Append(CCFLAGS="-Wall")
777 env.Append(CXXFLAGS="-Woverloaded-virtual")
778
779 if env['EXTRA_WARN']:
780     env.Append(CCFLAGS="-Wextra -pedantic -ansi")
781     env.Append(CXXFLAGS="-ansi")
782 #    env.Append(CFLAGS="-iso")
783
784 if env['LIBLO']:
785     env.Append(CCFLAGS="-DHAVE_LIBLO")
786
787
788 #
789 # fix scons nitpickiness on APPLE
790 #
791
792
793 def prep_libcheck(topenv, libinfo):
794     if topenv['IS_OSX']:
795         #
796         # rationale: GTK-Quartz uses jhbuild and installs to /opt/gtk by default.
797         #            All libraries needed should be built against this location
798         if topenv['GTKOSX']:
799                 libinfo.Append(CPPPATH="/opt/gtk/include", LIBPATH="/opt/gtk/lib")
800                 libinfo.Append(CXXFLAGS="-I/opt/gtk/include", LINKFLAGS="-L/opt/gtk/lib")
801         libinfo.Append(CPPPATH="/opt/local/include", LIBPATH="/opt/local/lib")
802         libinfo.Append(CXXFLAGS="-I/opt/local/include", LINKFLAGS="-L/opt/local/lib")
803
804 prep_libcheck(env, env)
805
806
807 #
808 # these are part of the Ardour source tree because they are C++
809
810
811 libraries['vamp'] = LibraryInfo (LIBS='vampsdk',
812                                  LIBPATH='#libs/vamp-sdk',
813                                  CPPPATH='#libs/vamp-sdk')
814 libraries['vamphost'] = LibraryInfo (LIBS='vamphostsdk',
815                                  LIBPATH='#libs/vamp-sdk',
816                                  CPPPATH='#libs/vamp-sdk')
817
818 env['RUBBERBAND'] = False
819
820 conf = Configure (env)
821
822 if conf.CheckHeader ('fftw3.h'):
823     env['RUBBERBAND'] = True
824     libraries['rubberband'] = LibraryInfo (LIBS='rubberband',
825                                            LIBPATH='#libs/rubberband',
826                                            CPPPATH='#libs/rubberband',
827                                            CCFLAGS='-DUSE_RUBBERBAND')
828 else:
829     print ""
830     print "-------------------------------------------------------------------------"
831     print "You do not have the FFTW single-precision development package installed."
832     print "This prevents Ardour from using the Rubberband library for timestretching"
833     print "and pitchshifting. It will fall back on SoundTouch for timestretch, and "
834     print "pitchshifting will not be available."
835     print "-------------------------------------------------------------------------"
836     print ""
837
838 conf.Finish()
839
840 #
841 # Check for libusb
842
843 libraries['usb'] = LibraryInfo ()
844 prep_libcheck(env, libraries['usb'])
845
846 conf = Configure (libraries['usb'])
847 if conf.CheckLib ('usb', 'usb_interrupt_write'):
848     have_libusb = True
849 else:
850     have_libusb = False
851
852 # check for linux/input.h while we're at it for powermate
853 if conf.CheckHeader('linux/input.h'):
854     have_linux_input = True
855 else:
856     have_linux_input = False
857
858 libraries['usb'] = conf.Finish ()
859
860 #
861 # Check for FLAC
862
863 libraries['flac'] = LibraryInfo ()
864 prep_libcheck(env, libraries['flac'])
865 libraries['flac'].Append(CPPPATH="/usr/local/include", LIBPATH="/usr/local/lib")
866
867 #
868 # june 1st 2007: look for a function that is in FLAC 1.1.2 and not in later versions
869 #                since the version of libsndfile we have internally does not support
870 #                the new API that libFLAC has adopted
871 #
872
873 conf = Configure (libraries['flac'])
874 if conf.CheckLib ('FLAC', 'FLAC__seekable_stream_decoder_init', language='CXX'):
875     conf.env.Append(CCFLAGS='-DHAVE_FLAC')
876     use_flac = True
877 else:
878     use_flac = False
879     
880 libraries['flac'] = conf.Finish ()
881
882 # or if that fails...
883 #libraries['flac']    = LibraryInfo (LIBS='FLAC')
884
885 # boost (we don't link against boost, just use some header files)
886
887 libraries['boost'] = LibraryInfo ()
888 prep_libcheck(env, libraries['boost'])
889 libraries['boost'].Append(CPPPATH="/usr/local/include", LIBPATH="/usr/local/lib")
890 conf = Configure (libraries['boost'])
891 if conf.CheckHeader ('boost/shared_ptr.hpp', language='CXX') == False:
892         print "Boost header files do not appear to be installed."
893         sys.exit (1)
894     
895 libraries['boost'] = conf.Finish ()
896
897 #
898 # Check for liblo
899
900 if env['LIBLO']:
901     libraries['lo'] = LibraryInfo ()
902     prep_libcheck(env, libraries['lo'])
903
904     conf = Configure (libraries['lo'])
905     if conf.CheckLib ('lo', 'lo_server_new') == False:
906         print "liblo does not appear to be installed."
907         sys.exit (1)
908     
909     libraries['lo'] = conf.Finish ()
910
911 #
912 # Check for dmalloc
913
914 libraries['dmalloc'] = LibraryInfo ()
915 prep_libcheck(env, libraries['dmalloc'])
916
917 #
918 # look for the threaded version
919 #
920
921 conf = Configure (libraries['dmalloc'])
922 if conf.CheckLib ('dmallocth', 'dmalloc_shutdown'):
923     have_libdmalloc = True
924 else:
925     have_libdmalloc = False
926
927 libraries['dmalloc'] = conf.Finish ()
928
929 #
930 # Audio/MIDI library (needed for MIDI, since audio is all handled via JACK)
931 #
932
933 conf = Configure(env)
934
935 if conf.CheckCHeader('alsa/asoundlib.h'):
936     libraries['sysmidi'] = LibraryInfo (LIBS='asound')
937     env['SYSMIDI'] = 'ALSA Sequencer'
938     subst_dict['%MIDITAG%'] = "seq"
939     subst_dict['%MIDITYPE%'] = "alsa/sequencer"
940 elif conf.CheckCHeader('/System/Library/Frameworks/CoreMIDI.framework/Headers/CoreMIDI.h'):
941     # this line is needed because scons can't handle -framework in ParseConfig() yet.
942     if env['GTKOSX']:
943         # We need Carbon as well as the rest
944         libraries['sysmidi'] = LibraryInfo (
945                 LINKFLAGS = ' -framework CoreMIDI -framework CoreFoundation -framework CoreAudio -framework CoreServices -framework AudioUnit -framework AudioToolbox -framework Carbon -bind_at_load' )
946     else:
947         libraries['sysmidi'] = LibraryInfo (
948                 LINKFLAGS = ' -framework CoreMIDI -framework CoreFoundation -framework CoreAudio -framework CoreServices -framework AudioUnit -framework AudioToolbox -bind_at_load' )
949     env['SYSMIDI'] = 'CoreMIDI'
950     subst_dict['%MIDITAG%'] = "ardour"
951     subst_dict['%MIDITYPE%'] = "coremidi"
952 else:
953     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."
954     sys.exit (1)
955
956 env = conf.Finish()
957
958 if env['SYSLIBS']:
959
960     syslibdeps = \
961     {
962         'sigc++-2.0'           : '2.0',
963         'gtkmm-2.4'            : '2.8',
964         'libgnomecanvasmm-2.6' : '2.12.0'
965     }
966
967     conf = Configure(env, custom_tests = { 'CheckPKGConfig' : CheckPKGConfig,
968                     'CheckPKGVersion' : CheckPKGVersion })
969
970     for pkg, version in syslibdeps.iteritems():
971         if not conf.CheckPKGVersion( pkg, version ):
972             print '%s >= %s not found.' %(pkg, version)
973             DependenciesRequiredMessage()
974             Exit(1)
975     
976     env = conf.Finish()
977     
978     libraries['sigc2'] = LibraryInfo()
979     libraries['sigc2'].ParseConfig('pkg-config --cflags --libs sigc++-2.0')
980     libraries['glibmm2'] = LibraryInfo()
981     libraries['glibmm2'].ParseConfig('pkg-config --cflags --libs glibmm-2.4')
982     libraries['cairomm'] = LibraryInfo()
983     libraries['cairomm'].ParseConfig('pkg-config --cflags --libs cairomm-1.0')
984     libraries['gdkmm2'] = LibraryInfo()
985     libraries['gdkmm2'].ParseConfig ('pkg-config --cflags --libs gdkmm-2.4')
986     libraries['gtkmm2'] = LibraryInfo()
987     libraries['gtkmm2'].ParseConfig ('pkg-config --cflags --libs gtkmm-2.4')
988     libraries['atkmm'] = LibraryInfo()
989     libraries['atkmm'].ParseConfig ('pkg-config --cflags --libs atkmm-1.6')
990     libraries['pangomm'] = LibraryInfo()
991     libraries['pangomm'].ParseConfig ('pkg-config --cflags --libs pangomm-1.4')
992     libraries['libgnomecanvasmm'] = LibraryInfo()
993     libraries['libgnomecanvasmm'].ParseConfig ('pkg-config --cflags --libs libgnomecanvasmm-2.6')
994
995 #
996 # cannot use system one for the time being
997 #
998     
999     libraries['sndfile-ardour'] = LibraryInfo(LIBS='libsndfile-ardour',
1000                                     LIBPATH='#libs/libsndfile',
1001                                     CPPPATH=['#libs/libsndfile/src'])
1002
1003 #    libraries['libglademm'] = LibraryInfo()
1004 #    libraries['libglademm'].ParseConfig ('pkg-config --cflags --libs libglademm-2.4')
1005
1006 #    libraries['flowcanvas'] = LibraryInfo(LIBS='flowcanvas', LIBPATH='#/libs/flowcanvas', CPPPATH='#libs/flowcanvas')
1007     libraries['soundtouch'] = LibraryInfo()
1008     #libraries['soundtouch'].ParseConfig ('pkg-config --cflags --libs soundtouch-1.0')
1009     # Comment the previous line and uncomment this for Debian:
1010     libraries['soundtouch'].ParseConfig ('pkg-config --cflags --libs libSoundTouch')
1011
1012     libraries['appleutility'] = LibraryInfo(LIBS='libappleutility',
1013                                             LIBPATH='#libs/appleutility',
1014                                             CPPPATH='#libs/appleutility')
1015     
1016     coredirs = [
1017         'templates'
1018     ]
1019     
1020     subdirs = [
1021         'libs/libsndfile',
1022         'libs/pbd',
1023         'libs/midi++2',
1024         'libs/ardour',
1025         'libs/vamp-sdk',
1026         'libs/vamp-plugins/',
1027     # these are unconditionally included but have
1028     # tests internally to avoid compilation etc
1029     # if VST is not set
1030         'libs/fst',
1031         'vst',
1032     # this is unconditionally included but has
1033     # tests internally to avoid compilation etc
1034     # if COREAUDIO is not set
1035         'libs/appleutility'
1036         ]
1037     
1038     gtk_subdirs = [
1039 #        'libs/flowcanvas',
1040         'libs/gtkmm2ext',
1041         'gtk2_ardour',
1042         'libs/clearlooks'
1043         ]
1044
1045 else:
1046     libraries['sigc2'] = LibraryInfo(LIBS='sigc++2',
1047                                     LIBPATH='#libs/sigc++2',
1048                                     CPPPATH='#libs/sigc++2')
1049     libraries['glibmm2'] = LibraryInfo(LIBS='glibmm2',
1050                                     LIBPATH='#libs/glibmm2',
1051                                     CPPPATH='#libs/glibmm2')
1052     libraries['pangomm'] = LibraryInfo(LIBS='pangomm',
1053                                     LIBPATH='#libs/gtkmm2/pango',
1054                                     CPPPATH='#libs/gtkmm2/pango')
1055     libraries['atkmm'] = LibraryInfo(LIBS='atkmm',
1056                                      LIBPATH='#libs/gtkmm2/atk',
1057                                      CPPPATH='#libs/gtkmm2/atk')
1058     libraries['gdkmm2'] = LibraryInfo(LIBS='gdkmm2',
1059                                       LIBPATH='#libs/gtkmm2/gdk',
1060                                       CPPPATH='#libs/gtkmm2/gdk')
1061     libraries['gtkmm2'] = LibraryInfo(LIBS='gtkmm2',
1062                                      LIBPATH="#libs/gtkmm2/gtk",
1063                                      CPPPATH='#libs/gtkmm2/gtk/')
1064     libraries['libgnomecanvasmm'] = LibraryInfo(LIBS='libgnomecanvasmm',
1065                                                 LIBPATH='#libs/libgnomecanvasmm',
1066                                                 CPPPATH='#libs/libgnomecanvasmm')
1067     
1068     libraries['soundtouch'] = LibraryInfo(LIBS='soundtouch',
1069                                           LIBPATH='#libs/soundtouch',
1070                                           CPPPATH=['#libs', '#libs/soundtouch'])
1071     libraries['sndfile-ardour'] = LibraryInfo(LIBS='libsndfile-ardour',
1072                                     LIBPATH='#libs/libsndfile',
1073                                     CPPPATH=['#libs/libsndfile', '#libs/libsndfile/src'])
1074 #    libraries['libglademm'] = LibraryInfo(LIBS='libglademm',
1075 #                                          LIBPATH='#libs/libglademm',
1076 #                                          CPPPATH='#libs/libglademm')
1077     libraries['appleutility'] = LibraryInfo(LIBS='libappleutility',
1078                                             LIBPATH='#libs/appleutility',
1079                                             CPPPATH='#libs/appleutility')
1080
1081     coredirs = [
1082         'templates'
1083     ]
1084     
1085     subdirs = [
1086         'libs/sigc++2',
1087         'libs/libsndfile',
1088         'libs/pbd',
1089         'libs/midi++2',
1090         'libs/ardour',
1091         'libs/vamp-sdk',
1092         'libs/vamp-plugins/',
1093     # these are unconditionally included but have
1094     # tests internally to avoid compilation etc
1095     # if VST is not set
1096         'libs/fst',
1097         'vst',
1098     # this is unconditionally included but has
1099     # tests internally to avoid compilation etc
1100     # if COREAUDIO is not set
1101         'libs/appleutility'
1102         ]
1103     
1104     gtk_subdirs = [
1105         'libs/glibmm2',
1106         'libs/gtkmm2/pango',
1107         'libs/gtkmm2/atk',
1108         'libs/gtkmm2/gdk',
1109         'libs/gtkmm2/gtk',
1110         'libs/libgnomecanvasmm',
1111         'libs/gtkmm2ext',
1112         'gtk2_ardour',
1113         'libs/clearlooks'
1114         ]
1115
1116 #
1117 # * always build the LGPL control protocol lib, since we link against it from libardour
1118 # * ditto for generic MIDI
1119 # * tranzport checks whether it should build internally, but we need here so that
1120 #   its included in the tarball
1121 #
1122
1123 surface_subdirs = [ 'libs/surfaces/control_protocol',
1124                     'libs/surfaces/generic_midi',
1125                     'libs/surfaces/tranzport',
1126                     'libs/surfaces/mackie',
1127                     'libs/surfaces/powermate'
1128                     ]
1129
1130 if env['SURFACES']:
1131     if have_libusb:
1132         env['TRANZPORT'] = 1
1133     else:
1134         env['TRANZPORT'] = 0
1135         print 'Disabled building Tranzport code because libusb could not be found'
1136
1137     if have_linux_input:
1138         env['POWERMATE'] = 1
1139     else:
1140         env['POWERMATE'] = 0
1141         print 'Disabled building Powermate code because linux/input.h could not be found'
1142
1143     if os.access ('libs/surfaces/sony9pin', os.F_OK):
1144         surface_subdirs += [ 'libs/surfaces/sony9pin' ]
1145 else:
1146     env['POWERMATE'] = 0
1147     env['TRANZPORT'] = 0
1148
1149 #
1150 # timestretch libraries
1151 #
1152
1153 timefx_subdirs = ['libs/soundtouch']
1154 if env['RUBBERBAND']:
1155     timefx_subdirs += ['libs/rubberband']
1156
1157 opts.Save('scache.conf', env)
1158 Help(opts.GenerateHelpText(env))
1159
1160 final_prefix = '$PREFIX'
1161
1162 if env['DESTDIR'] :
1163     install_prefix = '$DESTDIR/$PREFIX'
1164 else:
1165     install_prefix = env['PREFIX']
1166
1167 subst_dict['%INSTALL_PREFIX%'] = install_prefix;
1168 subst_dict['%FINAL_PREFIX%'] = final_prefix;
1169 subst_dict['%PREFIX%'] = final_prefix;
1170
1171 if env['PREFIX'] == '/usr':
1172     final_config_prefix = '/etc'
1173 else:
1174     final_config_prefix = env['PREFIX'] + '/etc'
1175
1176 config_prefix = '$DESTDIR' + final_config_prefix
1177
1178 #
1179 # everybody needs this
1180 #
1181
1182 env.Merge ([ libraries['core'] ])
1183
1184
1185 #
1186 # i18n support
1187 #
1188
1189 conf = Configure (env)
1190 if env['NLS']:
1191     nls_error = 'This system is not configured for internationalized applications.  An english-only version will be built:'
1192     print 'Checking for internationalization support ...'
1193     have_gettext = conf.TryAction(Action('xgettext --version'))
1194     if have_gettext[0] != 1:
1195         nls_error += ' No xgettext command.'
1196         env['NLS'] = 0
1197     else:
1198         print "Found xgettext"
1199     
1200     have_msgmerge = conf.TryAction(Action('msgmerge --version'))
1201     if have_msgmerge[0] != 1:
1202         nls_error += ' No msgmerge command.'
1203         env['NLS'] = 0
1204     else:
1205         print "Found msgmerge"
1206     
1207     if not conf.CheckCHeader('libintl.h'):
1208         nls_error += ' No libintl.h.'
1209         env['NLS'] = 0
1210         
1211     if env['NLS'] == 0:
1212         print nls_error
1213     else:
1214         print "International version will be built."
1215 env = conf.Finish()
1216
1217 if env['NLS'] == 1:
1218     env.Append(CCFLAGS="-DENABLE_NLS")
1219
1220 Export('env install_prefix final_prefix config_prefix final_config_prefix libraries i18n ardour_version subst_dict use_flac')
1221
1222 #
1223 # the configuration file may be system dependent
1224 #
1225
1226 conf = env.Configure ()
1227
1228 if conf.CheckCHeader('/System/Library/Frameworks/CoreAudio.framework/Versions/A/Headers/CoreAudio.h'):
1229     subst_dict['%JACK_INPUT%'] = "coreaudio:Built-in Audio:in"
1230     subst_dict['%JACK_OUTPUT%'] = "coreaudio:Built-in Audio:out"
1231 else:
1232     subst_dict['%JACK_INPUT%'] = "alsa_pcm:playback_"
1233     subst_dict['%JACK_OUTPUT%'] = "alsa_pcm:capture_"
1234
1235 # posix_memalign available
1236 if not conf.CheckFunc('posix_memalign'):
1237     print 'Did not find posix_memalign(), using malloc'
1238     env.Append(CCFLAGS='-DNO_POSIX_MEMALIGN')
1239
1240
1241 env = conf.Finish()
1242
1243 # generate the per-user and system rc files from the same source
1244
1245 sysrcbuild = env.SubstInFile ('ardour_system.rc','ardour.rc.in', SUBST_DICT = subst_dict)
1246
1247 # add to the substitution dictionary
1248
1249 subst_dict['%VERSION%'] = ardour_version[0:3]
1250 subst_dict['%EXTRA_VERSION%'] = ardour_version[3:]
1251 subst_dict['%REVISION_STRING%'] = ''
1252 if os.path.exists('.svn'):
1253     subst_dict['%REVISION_STRING%'] = '.' + fetch_svn_revision ('.') + 'svn'
1254
1255 # specbuild = env.SubstInFile ('ardour.spec','ardour.spec.in', SUBST_DICT = subst_dict)
1256
1257 the_revision = env.Command ('frobnicatory_decoy', [], create_stored_revision)
1258 remove_ardour = env.Command ('frobnicatory_decoy2', [],
1259                              [ Delete ('$PREFIX/etc/ardour2'),
1260                                Delete ('$PREFIX/lib/ardour2'),
1261                                Delete ('$PREFIX/bin/ardour2')])
1262
1263 env.Alias('revision', the_revision)
1264 env.Alias('install', env.Install(os.path.join(config_prefix, 'ardour2'), 'ardour_system.rc'))
1265 env.Alias('uninstall', remove_ardour)
1266
1267 Default (sysrcbuild)
1268
1269 # source tarball
1270
1271 Precious (env['DISTTREE'])
1272
1273 env.Distribute (env['DISTTREE'],
1274                [ 'SConstruct', 'svn_revision.h',
1275                   'COPYING', 'PACKAGER_README', 'README',
1276                   'ardour.rc.in',
1277                   'tools/config.guess',
1278                   'icons/icon/ardour_icon_mac_mask.png',
1279                   'icons/icon/ardour_icon_mac.png',
1280                   'icons/icon/ardour_icon_tango_16px_blue.png',
1281                   'icons/icon/ardour_icon_tango_16px_red.png',
1282                   'icons/icon/ardour_icon_tango_22px_blue.png',
1283                   'icons/icon/ardour_icon_tango_22px_red.png',
1284                   'icons/icon/ardour_icon_tango_32px_blue.png',
1285                   'icons/icon/ardour_icon_tango_32px_red.png',
1286                   'icons/icon/ardour_icon_tango_48px_blue.png',
1287                   'icons/icon/ardour_icon_tango_48px_red.png'
1288                   ] +
1289                 glob.glob ('DOCUMENTATION/AUTHORS*') +
1290                 glob.glob ('DOCUMENTATION/CONTRIBUTORS*') +
1291                 glob.glob ('DOCUMENTATION/TRANSLATORS*') +
1292                 glob.glob ('DOCUMENTATION/BUILD*') +
1293                 glob.glob ('DOCUMENTATION/FAQ*') +
1294                 glob.glob ('DOCUMENTATION/README*')
1295                 )
1296
1297 srcdist = env.Tarball(env['TARBALL'], [ env['DISTTREE'], the_revision ])
1298 env.Alias ('srctar', srcdist)
1299
1300 #
1301 # don't leave the distree around
1302 #
1303
1304 env.AddPreAction (env['DISTTREE'], Action ('rm -rf ' + str (File (env['DISTTREE']))))
1305 env.AddPostAction (srcdist, Action ('rm -rf ' + str (File (env['DISTTREE']))))
1306
1307 #
1308 # the subdirs
1309 #
1310
1311 for subdir in coredirs:
1312     SConscript (subdir + '/SConscript')
1313
1314 for sublistdir in [ subdirs, timefx_subdirs, gtk_subdirs, surface_subdirs ]:
1315     for subdir in sublistdir:
1316         SConscript (subdir + '/SConscript')
1317
1318 # cleanup
1319 env.Clean ('scrub', [ 'scache.conf', '.sconf_temp', '.sconsign.dblite', 'config.log'])
1320