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