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