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