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