5a1440c619652406d3d34d356b358274c0051fbc
[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 SCons.Node.FS
11
12 SConsignFile()
13 EnsureSConsVersion(0, 96)
14
15 version = '1.9beta1'
16
17 subst_dict = { }
18
19 #
20 # Command-line options
21 #
22
23 opts = Options('scache.conf')
24 opts.AddOptions(
25     BoolOption('ALTIVEC', 'Compile using Altivec instructions', 0),
26   ('ARCH', 'Set architecture-specific compilation flags by hand (all flags as 1 argument)',''),
27     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),
28     BoolOption('DEBUG', 'Set to build with debugging information and no optimizations', 0),
29     PathOption('DESTDIR', 'Set the intermediate install "prefix"', '/'),
30     BoolOption('DEVBUILD', 'Use shared libardour (developers only)', 0),
31     BoolOption('SIGCCVSBUILD', 'Use if building sigc++ with a new configure.ac (developers only)', 0),
32     BoolOption('NLS', 'Set to turn on i18n support', 1),
33     BoolOption('NOARCH', 'Do not use architecture-specific compilation flags', 0),
34     PathOption('PREFIX', 'Set the install "prefix"', '/usr/local'),
35     BoolOption('VST', 'Compile with support for VST', 0),
36     BoolOption('VERSIONED', 'Add version information to ardour/gtk executable name inside the build directory', 0),
37     BoolOption('USE_SSE_EVERYWHERE', 'Ask the compiler to use x86/SSE instructions and also our hand-written x86/SSE optimizations when possible (off by default)', 0),
38     BoolOption('BUILD_SSE_OPTIMIZATIONS', 'Use our hand-written x86/SSE optimizations when possible (off by default)', 0)
39   )
40
41
42 #----------------------------------------------------------------------
43 # a handy helper that provides a way to merge compile/link information
44 # from multiple different "environments"
45 #----------------------------------------------------------------------
46 #
47 class LibraryInfo(Environment):
48     def __init__(self,*args,**kw):
49         Environment.__init__ (self,*args,**kw)
50         
51     def Merge (self,others):
52         for other in others:
53             self.Append (LIBS = other.get ('LIBS',[]))
54             self.Append (LIBPATH = other.get ('LIBPATH', []))   
55             self.Append (CPPPATH = other.get('CPPPATH', []))
56             self.Append (LINKFLAGS = other.get('LINKFLAGS', []))
57
58
59 env = LibraryInfo (options = opts,
60                    CPPPATH = [ '.' ],
61                    VERSION = version,
62                    TARBALL='ardour-' + version + '.tar.bz2',
63                    DISTFILES = [ ],
64                    DISTTREE  = '#ardour-' + version,
65                    DISTCHECKDIR = '#ardour-' + version + '/check'
66                    )
67
68
69 #----------------------------------------------------------------------
70 # Builders
71 #----------------------------------------------------------------------
72
73 # Handy subst-in-file builder
74
75
76 def do_subst_in_file(targetfile, sourcefile, dict):
77         """Replace all instances of the keys of dict with their values.
78         For example, if dict is {'%VERSION%': '1.2345', '%BASE%': 'MyProg'},
79         then all instances of %VERSION% in the file will be replaced with 1.2345 etc.
80         """
81         try:
82             f = open(sourcefile, 'rb')
83             contents = f.read()
84             f.close()
85         except:
86             raise SCons.Errors.UserError, "Can't read source file %s"%sourcefile
87         for (k,v) in dict.items():
88             contents = re.sub(k, v, contents)
89         try:
90             f = open(targetfile, 'wb')
91             f.write(contents)
92             f.close()
93         except:
94             raise SCons.Errors.UserError, "Can't write target file %s"%targetfile
95         return 0 # success
96  
97 def subst_in_file(target, source, env):
98         if not env.has_key('SUBST_DICT'):
99             raise SCons.Errors.UserError, "SubstInFile requires SUBST_DICT to be set."
100         d = dict(env['SUBST_DICT']) # copy it
101         for (k,v) in d.items():
102             if callable(v):
103                 d[k] = env.subst(v())
104             elif SCons.Util.is_String(v):
105                 d[k]=env.subst(v)
106             else:
107                 raise SCons.Errors.UserError, "SubstInFile: key %s: %s must be a string or callable"%(k, repr(v))
108         for (t,s) in zip(target, source):
109             return do_subst_in_file(str(t), str(s), d)
110  
111 def subst_in_file_string(target, source, env):
112         """This is what gets printed on the console."""
113         return '\n'.join(['Substituting vars from %s into %s'%(str(s), str(t))
114                           for (t,s) in zip(target, source)])
115  
116 def subst_emitter(target, source, env):
117         """Add dependency from substituted SUBST_DICT to target.
118         Returns original target, source tuple unchanged.
119         """
120         d = env['SUBST_DICT'].copy() # copy it
121         for (k,v) in d.items():
122             if callable(v):
123                 d[k] = env.subst(v())
124             elif SCons.Util.is_String(v):
125                 d[k]=env.subst(v)
126         Depends(target, SCons.Node.Python.Value(d))
127         # Depends(target, source) # this doesn't help the install-sapphire-linux.sh problem
128         return target, source
129  
130 subst_action = Action (subst_in_file, subst_in_file_string)
131 env['BUILDERS']['SubstInFile'] = Builder(action=subst_action, emitter=subst_emitter)
132
133 #
134 # internationalization
135 #
136
137 # po_helper
138 #
139 # this is not a builder. we can't list the .po files as a target,
140 # because then scons -c will remove them (even Precious doesn't alter
141 # this). this function is called whenever a .mo file is being
142 # built, and will conditionally update the .po file if necessary.
143 #
144
145 def po_helper(po,pot):
146     args = [ 'msgmerge',
147              '--update',
148              po,
149              pot,
150              ]
151     print 'Updating ' + po
152     return os.spawnvp (os.P_WAIT, 'msgmerge', args)
153
154 # mo_builder: builder function for (binary) message catalogs (.mo)
155 #
156 # first source:  .po file
157 # second source: .pot file
158 #
159
160 def mo_builder(target,source,env):
161     po_helper (source[0].get_path(), source[1].get_path())
162     args = [ 'msgfmt',
163              '-c',
164              '-o',
165              target[0].get_path(),
166              source[0].get_path()
167              ]
168     return os.spawnvp (os.P_WAIT, 'msgfmt', args)
169
170 mo_bld = Builder (action = mo_builder)
171 env.Append(BUILDERS = {'MoBuild' : mo_bld})
172
173 # pot_builder: builder function for message templates (.pot)
174 #
175 # source: list of C/C++ etc. files to extract messages from
176 #
177
178 def pot_builder(target,source,env):
179     args = [ 'xgettext', 
180              '--keyword=_',
181              '--keyword=N_',
182              '--from-code=UTF-8',
183              '-o', target[0].get_path(), 
184              "--default-domain=" + env['PACKAGE'],
185              '--copyright-holder="Paul Davis"' ]
186     args += [ src.get_path() for src in source ]
187
188     return os.spawnvp (os.P_WAIT, 'xgettext', args)
189
190 pot_bld = Builder (action = pot_builder)
191 env.Append(BUILDERS = {'PotBuild' : pot_bld})
192
193 #
194 # utility function, not a builder
195 #
196
197 def i18n (buildenv, sources, installenv):
198     domain = buildenv['PACKAGE']
199     potfile = buildenv['POTFILE']
200
201     installenv.Alias ('potupdate', buildenv.PotBuild (potfile, sources))
202
203     p_oze = [ os.path.basename (po) for po in glob.glob ('po/*.po') ]
204     languages = [ po.replace ('.po', '') for po in p_oze ]
205     m_oze = [ po.replace (".po", ".mo") for po in p_oze ]
206     
207     for mo in m_oze[:]:
208         po = 'po/' + mo.replace (".mo", ".po")
209         installenv.Alias ('install', buildenv.MoBuild (mo, [ po, potfile ]))
210         
211     for lang in languages[:]:
212         modir = (os.path.join (install_prefix, 'share/locale/' + lang + '/LC_MESSAGES/'))
213         moname = domain + '.mo'
214         installenv.Alias('install', installenv.InstallAs (os.path.join (modir, moname), lang + '.mo'))
215
216 #
217 # A generic builder for version.cc files
218
219 # note: requires that DOMAIN, MAJOR, MINOR, MICRO are set in the construction environment
220 # note: assumes one source files, the header that declares the version variables
221
222 def version_builder (target, source, env):
223    text  = "int " + env['DOMAIN'] + "_major_version = " + str (env['MAJOR']) + ";\n"
224    text += "int " + env['DOMAIN'] + "_minor_version = " + str (env['MINOR']) + ";\n"
225    text += "int " + env['DOMAIN'] + "_micro_version = " + str (env['MICRO']) + ";\n"
226
227    try:
228       o = file (target[0].get_path(), 'w')
229       o.write (text)
230       o.close ();
231    except IOError:
232       print "Could not open", target[0].get_path(), " for writing\n"
233       sys.exit (-1)
234
235    text  = "#ifndef __" + env['DOMAIN'] + "_version_h__\n";
236    text += "#define __" + env['DOMAIN'] + "_version_h__\n";
237    text += "extern int " + env['DOMAIN'] + "_major_version;\n"
238    text += "extern int " + env['DOMAIN'] + "_minor_version;\n"
239    text += "extern int " + env['DOMAIN'] + "_micro_version;\n"
240    text += "#endif /* __" + env['DOMAIN'] + "_version_h__ */\n";
241
242    try:
243       o = file (target[1].get_path(), 'w')
244       o.write (text)
245       o.close ();
246    except IOError:
247       print "Could not open", target[1].get_path(), " for writing\n"
248       sys.exit (-1)
249   
250    return None
251
252 version_bld = Builder (action = version_builder)
253 env.Append (BUILDERS = {'VersionBuild' : version_bld})
254
255 #
256 # a builder that makes a hard link from the 'source' executable to a name with
257 # a "build ID" based on the most recent CVS activity that might be reasonably
258 # related to version activity. this relies on the idea that the SConscript
259 # file that builds the executable is updated with new version info and committed
260 # to the source code repository whenever things change.
261 #
262
263 def versioned_builder(target,source,env):
264     # build ID is composed of a representation of the date of the last CVS transaction
265     # for this (SConscript) file
266     
267     try:
268         o = file (source[0].get_dir().get_path() +  '/CVS/Entries', "r")
269     except IOError:
270         print "Could not CVS/Entries for reading"
271         return -1
272
273     last_date = ""        
274     lines = o.readlines()
275     for line in lines:
276         if line[0:12] == '/SConscript/':
277             parts = line.split ("/")
278             last_date = parts[3]
279             break
280     o.close ()
281
282     if last_date == "":
283         print "No SConscript CVS update info found - versioned executable cannot be built"
284         return -1
285
286     tag = time.strftime ('%Y%M%d%H%m', time.strptime (last_date));
287     print "The current build ID is " + tag
288
289     tagged_executable = source[0].get_path() + '-' + tag
290
291     if os.path.exists (tagged_executable):
292         print "Replacing existing executable with the same build tag."
293         os.unlink (tagged_executable)
294
295     return os.link (source[0].get_path(), tagged_executable)
296
297 verbuild = Builder (action = versioned_builder)
298 env.Append (BUILDERS = {'VersionedExecutable' : verbuild})
299
300 #
301 # source tar file builder
302 #
303
304 def distcopy (target, source, env):
305     treedir = str (target[0])
306
307     try:
308         os.mkdir (treedir)
309     except OSError, (errnum, strerror):
310         if errnum != errno.EEXIST:
311             print 'mkdir ', treedir, ':', strerror
312
313     cmd = 'tar cf - '
314     #
315     # we don't know what characters might be in the file names
316     # so quote them all before passing them to the shell
317     #
318     all_files = ([ str(s) for s in source ])
319     cmd += " ".join ([ "'%s'" % quoted for quoted in all_files])
320     cmd += ' | (cd ' + treedir + ' && tar xf -)'
321     p = os.popen (cmd)
322     return p.close ();
323
324 def tarballer (target, source, env):            
325     cmd = 'tar -jcf ' + str (target[0]) +  ' ' + str(source[0]) + "  --exclude '*~'"
326     print 'running ', cmd, ' ... '
327     p = os.popen (cmd)
328     return p.close ()
329
330 dist_bld = Builder (action = distcopy,
331                     target_factory = SCons.Node.FS.default_fs.Entry,
332                     source_factory = SCons.Node.FS.default_fs.Entry,
333                     multi = 1)
334
335 tarball_bld = Builder (action = tarballer,
336                        target_factory = SCons.Node.FS.default_fs.Entry,
337                        source_factory = SCons.Node.FS.default_fs.Entry)
338
339 env.Append (BUILDERS = {'Distribute' : dist_bld})
340 env.Append (BUILDERS = {'Tarball' : tarball_bld})
341
342 # ----------------------------------------------------------------------
343 # Construction environment setup
344 # ----------------------------------------------------------------------
345
346 libraries = { }
347
348 libraries['core'] = LibraryInfo (CPPPATH = [ '#libs'])
349
350 libraries['sndfile'] = LibraryInfo()
351 libraries['sndfile'].ParseConfig('pkg-config --cflags --libs sndfile')
352
353 libraries['lrdf'] = LibraryInfo()
354 libraries['lrdf'].ParseConfig('pkg-config --cflags --libs lrdf')
355
356 libraries['raptor'] = LibraryInfo()
357 libraries['raptor'].ParseConfig('pkg-config --cflags --libs raptor')
358
359 libraries['samplerate'] = LibraryInfo()
360 libraries['samplerate'].ParseConfig('pkg-config --cflags --libs samplerate')
361
362 libraries['jack'] = LibraryInfo()
363 libraries['jack'].ParseConfig('pkg-config --cflags --libs jack')
364
365 libraries['xml'] = LibraryInfo()
366 libraries['xml'].ParseConfig('pkg-config --cflags --libs libxml-2.0')
367
368 libraries['glib2'] = LibraryInfo()
369 libraries['glib2'].ParseConfig ('pkg-config --cflags --libs glib-2.0')
370 libraries['glib2'].ParseConfig ('pkg-config --cflags --libs gobject-2.0')
371 libraries['glib2'].ParseConfig ('pkg-config --cflags --libs gmodule-2.0')
372
373 libraries['gtk2'] = LibraryInfo()
374 libraries['gtk2'].ParseConfig ('pkg-config --cflags --libs gtk+-2.0')
375
376 libraries['pango'] = LibraryInfo()
377 libraries['pango'].ParseConfig ('pkg-config --cflags --libs pango')
378
379 libraries['libgnomecanvas2'] = LibraryInfo()
380 libraries['libgnomecanvas2'].ParseConfig ('pkg-config --cflags --libs libgnomecanvas-2.0')
381
382 libraries['ardour'] = LibraryInfo (LIBS='ardour', LIBPATH='#libs/ardour', CPPPATH='#libs/ardour')
383 libraries['midi++2'] = LibraryInfo (LIBS='midi++', LIBPATH='#libs/midi++2', CPPPATH='#libs/midi++2')
384 libraries['pbd3']    = LibraryInfo (LIBS='pbd', LIBPATH='#libs/pbd3', CPPPATH='#libs/pbd3')
385 libraries['gtkmm2ext'] = LibraryInfo (LIBS='gtkmm2ext', LIBPATH='#libs/gtkmm2ext', CPPPATH='#libs/gtkmm2ext')
386 #libraries['cassowary'] = LibraryInfo(LIBS='cassowary', LIBPATH='#libs/cassowary', CPPPATH='#libs/cassowary')
387
388 libraries['fst'] = LibraryInfo()
389 if env['VST']:
390     libraries['fst'].ParseConfig('pkg-config --cflags --libs libfst')
391
392 #
393 # Audio/MIDI library (needed for MIDI, since audio is all handled via JACK)
394
395
396 conf = Configure(env)
397
398 if conf.CheckCHeader('alsa/asoundlib.h'):
399     libraries['sysmidi'] = LibraryInfo (LIBS='asound')
400     env['SYSMIDI'] = 'ALSA Sequencer'
401     subst_dict['%MIDITAG%'] = "seq"
402     subst_dict['%MIDITYPE%'] = "alsa/sequencer"
403 elif conf.CheckCHeader('/System/Library/Frameworks/CoreMIDI.framework/Headers/CoreMIDI.h'):
404     # this line is needed because scons can't handle -framework in ParseConfig() yet.
405     libraries['sysmidi'] = LibraryInfo (LINKFLAGS= '-framework CoreMIDI -framework CoreFoundation -framework CoreAudio -framework CoreServices -framework AudioUnit -bind_at_load')
406     env['SYSMIDI'] = 'CoreMIDI'
407     subst_dict['%MIDITAG%'] = "ardour"
408     subst_dict['%MIDITYPE%'] = "coremidi"
409
410 env = conf.Finish()
411
412 if env['SYSLIBS']:
413
414     libraries['sigc2'] = LibraryInfo()
415     libraries['sigc2'].ParseConfig('pkg-config --cflags --libs sigc++-2.0')
416
417     libraries['gtkmm2'] = LibraryInfo()
418     libraries['gtkmm2'].ParseConfig ('pkg-config --cflags --libs gtkmm-2.0')
419
420     libraries['soundtouch'] = LibraryInfo(LIBS='SoundTouch')
421
422     coredirs = [
423         'templates'
424     ]
425
426     subdirs = [
427 #       'libs/cassowary',
428         'libs/pbd3',
429         'libs/midi++2',
430         'libs/ardour',
431         'templates'
432         ]
433
434     gtk_subdirs = [
435         'libs/gtkmm2ext',
436         'gtk2_ardour',
437         ]
438
439 else:
440     libraries['sigc2'] = LibraryInfo(LIBS='sigc++2',
441                                     LIBPATH='#libs/sigc++2',
442                                     CPPPATH='#libs/sigc++2')
443     libraries['glibmm2'] = LibraryInfo(LIBS='glibmm2',
444                                     LIBPATH='#libs/glibmm2',
445                                     CPPPATH='#libs/glibmm2')
446     libraries['pangomm'] = LibraryInfo(LIBS='pangomm',
447                                     LIBPATH='#libs/gtkmm2/pango',
448                                     CPPPATH='#libs/gtkmm2/pango')
449     libraries['atkmm'] = LibraryInfo(LIBS='atkmm',
450                                      LIBPATH='#libs/gtkmm2/atk',
451                                      CPPPATH='#libs/gtkmm2/atk')
452     libraries['gdkmm2'] = LibraryInfo(LIBS='gdkmm2',
453                                       LIBPATH='#libs/gtkmm2/gdk',
454                                       CPPPATH='#libs/gtkmm2/gdk')
455     libraries['gtkmm2'] = LibraryInfo(LIBS='gtkmm2',
456                                      LIBPATH="#libs/gtkmm2/gtk",
457                                      CPPPATH='#libs/gtkmm2/gtk/')
458     libraries['libgnomecanvasmm'] = LibraryInfo(LIBS='libgnomecanvasmm',
459                                                 LIBPATH='#libs/libgnomecanvasmm',
460                                                 CPPPATH='#libs/libgnomecanvasmm')
461
462     libraries['soundtouch'] = LibraryInfo(LIBS='soundtouch',
463                                           LIBPATH='#libs/soundtouch',
464                                           CPPPATH=['#libs', '#libs/soundtouch'])
465
466     coredirs = [
467         'libs/soundtouch',
468         'templates'
469     ]
470
471     subdirs = [
472 #       'libs/cassowary',
473         'libs/sigc++2',
474         'libs/pbd3',
475         'libs/midi++2',
476         'libs/ardour'
477         ]
478
479     gtk_subdirs = [
480         'libs/glibmm2',
481         'libs/gtkmm2/pango',
482         'libs/gtkmm2/atk',
483         'libs/gtkmm2/gdk',
484         'libs/gtkmm2/gtk',
485         'libs/libgnomecanvasmm',
486         'libs/gtkmm2ext',
487         'gtk2_ardour',
488         ]
489
490 opts.Save('scache.conf', env)
491 Help(opts.GenerateHelpText(env))
492
493 if os.environ.has_key('PATH'):
494     env.Append(PATH = os.environ['PATH'])
495
496 if os.environ.has_key('PKG_CONFIG_PATH'):
497     env.Append(PKG_CONFIG_PATH = os.environ['PKG_CONFIG_PATH'])
498
499 if os.environ.has_key('CC'):
500     env['CC'] = os.environ['CC']
501
502 if os.environ.has_key('CXX'):
503     env['CXX'] = os.environ['CXX']
504
505 if os.environ.has_key('DISTCC_HOSTS'):
506     env['ENV']['DISTCC_HOSTS'] = os.environ['DISTCC_HOSTS']
507     env['ENV']['HOME'] = os.environ['HOME']
508     
509 final_prefix = '$PREFIX'
510 install_prefix = '$DESTDIR/$PREFIX'
511
512 if env['PREFIX'] == '/usr':
513     final_config_prefix = '/etc'
514 else:
515     final_config_prefix = env['PREFIX'] + '/etc'
516
517 config_prefix = '$DESTDIR' + final_config_prefix
518
519 #
520 # Compiler flags and other system-dependent stuff
521 #
522
523 opt_flags = []
524 debug_flags = [ '-g' ]
525
526 # guess at the platform, used to define compiler flags
527
528 config_guess = os.popen("tools/config.guess").read()[:-1]
529
530 config_cpu = 0;
531 config_arch = 1;
532 config_kernel = 2;
533 config_os = 3;
534 config = config_guess.split ("-")
535
536 #
537 # on OS X darwinports puts things in /opt/local by default
538 #
539 if config[config_arch] == 'apple':
540     if os.path.isdir('/opt/local/lib'):
541         libraries['core'].Append (LIBPATH = [ '/opt/local/lib' ])
542     if os.path.isdir('/opt/local/include'):
543         libraries['core'].Append (CPPPATH = [ '/opt/local/include' ])
544 if config[config_cpu] == 'powerpc':
545     #
546     # Apple/PowerPC optimization options
547     #
548     # -mcpu=7450 does not reliably work with gcc 3.*
549     #
550     if env['NOARCH'] == 0:
551         if env['ALTIVEC'] == 1:
552             if config[config_arch] == 'apple':
553                 opt_flags.extend ([ "-mcpu=7450", "-faltivec"])
554             else:
555                 opt_flags.extend ([ "-mcpu=7400", "-maltivec", "-mabi=altivec"]) 
556         else:
557             opt_flags.extend([ "-mcpu=750", "-mmultiple" ])
558         opt_flags.extend (["-mhard-float", "-mpowerpc-gfxopt"])
559
560 elif ((re.search ("i[0-9]86", config[config_cpu]) != None) or (re.search ("x86_64", config[config_cpu]) != None)):
561
562     build_host_supports_sse = 0
563     
564     if env['NOARCH'] == 0:
565
566         debug_flags.append ("-DARCH_X86")
567         opt_flags.append ("-DARCH_X86")
568
569         if config[config_kernel] == 'linux' :
570
571             flag_line = os.popen ("cat /proc/cpuinfo | grep '^flags'").read()[:-1]
572             x86_flags = flag_line.split (": ")[1:][0].split (' ')
573
574             if "mmx" in x86_flags:
575                 opt_flags.append ("-mmmx")
576             if "sse" in x86_flags:
577                 build_host_supports_sse = 1
578             if "3dnow" in x86_flags:
579                 opt_flags.append ("-m3dnow")
580
581             if config[config_cpu] == "i586":
582                 opt_flags.append ("-march=i586")
583             elif config[config_cpu] == "i686":
584                 opt_flags.append ("-march=i686")
585
586         if env['USE_SSE_EVERYWHERE'] == 1:
587                 opt_flags.extend (["-msse", "-mfpmath=sse"])
588                 debug_flags.extend (["-msse", "-mfpmath=sse"])
589                 if build_host_supports_sse != 1:
590                     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)"
591
592         if env['BUILD_SSE_OPTIMIZATIONS'] == 1:
593                 opt_flags.append ("-DBUILD_SSE_OPTIMIZATIONS")
594                 debug_flags.append ("-DBUILD_SSE_OPTIMIZATIONS")
595                 if build_host_supports_sse != 1:
596                     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)"
597                     
598 # end of processor-specific section
599
600 #
601 # ARCH="..." overrides all 
602 #
603
604 if env['ARCH'] != '':
605     opt_flags = env['ARCH'].split()
606
607 #
608 # prepend boiler plate optimization flags
609 #
610
611 opt_flags[:0] = [
612     "-O3",
613     "-fomit-frame-pointer",
614     "-ffast-math",
615     "-fstrength-reduce"
616     ]
617
618 if env['DEBUG'] == 1:
619     env.Append(CCFLAGS=" ".join (debug_flags))
620 else:
621     env.Append(CCFLAGS=" ".join (opt_flags))
622
623 env.Append(CCFLAGS="-Wall")
624
625 if env['VST']:
626     env.Append(CCFLAGS="-DVST_SUPPORT")
627
628
629 #
630 # everybody needs this
631 #
632
633 env.Merge ([ libraries['core'] ])
634
635 #
636 # i18n support 
637 #
638
639 conf = Configure (env)
640
641 if env['NLS']:
642     print 'Checking for internationalization support ...'
643     have_gettext = conf.TryAction(Action('xgettext --version'))
644     if have_gettext[0] != 1:
645         print 'This system is not configured for internationalized applications (no xgettext command). An english-only version will be built\n'
646         env['NLS'] = 0
647         
648     if conf.CheckCHeader('libintl.h') == None:
649         print 'This system is not configured for internationalized applications (no libintl.h). An english-only version will be built\n'
650         env['NLS'] = 0
651
652
653 env = conf.Finish()
654
655 if env['NLS'] == 1:
656     env.Append(CCFLAGS="-DENABLE_NLS")
657
658
659 Export('env install_prefix final_prefix config_prefix final_config_prefix libraries i18n version')
660
661 #
662 # the configuration file may be system dependent
663 #
664
665 conf = env.Configure ()
666
667 if conf.CheckCHeader('/System/Library/Frameworks/CoreAudio.framework/Versions/A/Headers/CoreAudio.h'):
668     subst_dict['%JACK_BACKEND%'] = "coreaudio:Built-in Audio:in"
669 else:
670     subst_dict['%JACK_BACKEND%'] = "alsa_pcm:playback_"
671
672 # posix_memalign available
673 if not conf.CheckFunc('posix_memalign'):
674     print 'Did not find posix_memalign(), using malloc'
675     env.Append(CCFLAGS='-DNO_POSIX_MEMALIGN')
676
677
678 env = conf.Finish()
679
680 rcbuild = env.SubstInFile ('ardour.rc','ardour.rc.in', SUBST_DICT = subst_dict)
681
682 env.Alias('install', env.Install(os.path.join(config_prefix, 'ardour'), 'ardour_system.rc'))
683 env.Alias('install', env.Install(os.path.join(config_prefix, 'ardour'), 'ardour.rc'))
684
685 Default (rcbuild)
686
687 # source tarball
688
689 Precious (env['DISTTREE'])
690
691 #
692 # note the special "cleanfirst" source name. this triggers removal
693 # of the existing disttree
694 #
695
696 env.Distribute (env['DISTTREE'],
697                 [ 'SConstruct',
698                   'COPYING', 'PACKAGER_README', 'README',
699                   'ardour.rc.in',
700                   'ardour_system.rc',
701                   'tools/config.guess'
702                   ] +
703                 glob.glob ('DOCUMENTATION/AUTHORS*') +
704                 glob.glob ('DOCUMENTATION/CONTRIBUTORS*') +
705                 glob.glob ('DOCUMENTATION/TRANSLATORS*') +
706                 glob.glob ('DOCUMENTATION/BUILD*') +
707                 glob.glob ('DOCUMENTATION/FAQ*') +
708                 glob.glob ('DOCUMENTATION/README*')
709                 )
710                 
711 srcdist = env.Tarball(env['TARBALL'], env['DISTTREE'])
712 env.Alias ('srctar', srcdist)
713 #
714 # don't leave the distree around 
715 #
716 env.AddPreAction (env['DISTTREE'], Action ('rm -rf ' + str (File (env['DISTTREE']))))
717 env.AddPostAction (srcdist, Action ('rm -rf ' + str (File (env['DISTTREE']))))
718
719 #
720 # the subdirs
721
722
723 for subdir in coredirs:
724     SConscript (subdir + '/SConscript')
725
726 for sublistdir in [subdirs, gtk_subdirs]:
727         for subdir in sublistdir:
728                 SConscript (subdir + '/SConscript')
729
730 # cleanup
731 env.Clean ('scrub', [ 'scache.conf', '.sconf_temp', '.sconsign.dblite', 'config.log'])
732