time_axis_view now compiles
[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['glade2'] = LibraryInfo()
382 libraries['glade2'].ParseConfig ('pkg-config --cflags --libs libglade-2.0')
383
384 libraries['flowcanvas'] = LibraryInfo(LIBS='flowcanvas', LIBPATH='#/libs/flowcanvas', CPPPATH='#libs/flowcanvas')
385
386 libraries['ardour'] = LibraryInfo (LIBS='ardour', LIBPATH='#libs/ardour', CPPPATH='#libs/ardour')
387 libraries['midi++2'] = LibraryInfo (LIBS='midi++', LIBPATH='#libs/midi++2', CPPPATH='#libs/midi++2')
388 libraries['pbd3']    = LibraryInfo (LIBS='pbd', LIBPATH='#libs/pbd3', CPPPATH='#libs/pbd3')
389 libraries['gtkmm2ext'] = LibraryInfo (LIBS='gtkmm2ext', LIBPATH='#libs/gtkmm2ext', CPPPATH='#libs/gtkmm2ext')
390 #libraries['cassowary'] = LibraryInfo(LIBS='cassowary', LIBPATH='#libs/cassowary', CPPPATH='#libs/cassowary')
391
392 libraries['fst'] = LibraryInfo()
393 if env['VST']:
394     libraries['fst'].ParseConfig('pkg-config --cflags --libs libfst')
395
396 #
397 # Audio/MIDI library (needed for MIDI, since audio is all handled via JACK)
398
399
400 conf = Configure(env)
401
402 if conf.CheckCHeader('alsa/asoundlib.h'):
403     libraries['sysmidi'] = LibraryInfo (LIBS='asound')
404     env['SYSMIDI'] = 'ALSA Sequencer'
405     subst_dict['%MIDITAG%'] = "seq"
406     subst_dict['%MIDITYPE%'] = "alsa/sequencer"
407 elif conf.CheckCHeader('/System/Library/Frameworks/CoreMIDI.framework/Headers/CoreMIDI.h'):
408     # this line is needed because scons can't handle -framework in ParseConfig() yet.
409     libraries['sysmidi'] = LibraryInfo (LINKFLAGS= '-framework CoreMIDI -framework CoreFoundation -framework CoreAudio -framework CoreServices -framework AudioUnit -bind_at_load')
410     env['SYSMIDI'] = 'CoreMIDI'
411     subst_dict['%MIDITAG%'] = "ardour"
412     subst_dict['%MIDITYPE%'] = "coremidi"
413
414 env = conf.Finish()
415
416 if env['SYSLIBS']:
417
418     libraries['sigc2'] = LibraryInfo()
419     libraries['sigc2'].ParseConfig('pkg-config --cflags --libs sigc++-2.0')
420
421     libraries['gtkmm2'] = LibraryInfo()
422     libraries['gtkmm2'].ParseConfig ('pkg-config --cflags --libs gtkmm-2.0')
423     
424     libraries['libglademm'] = LibraryInfo()
425     libraries['libglademm'].ParseConfig ('pkg-config --cflags --libs libglademm-2.4')
426     
427     libraries['soundtouch'] = LibraryInfo(LIBS='SoundTouch')
428
429     coredirs = [
430         'templates'
431     ]
432
433     subdirs = [
434 #       'libs/cassowary',
435         'libs/pbd3',
436         'libs/midi++2',
437         'libs/ardour',
438         'templates'
439         ]
440
441     gtk_subdirs = [
442         'libs/gtkmm2ext',
443         'gtk2_ardour',
444         ]
445
446 else:
447     libraries['sigc2'] = LibraryInfo(LIBS='sigc++2',
448                                     LIBPATH='#libs/sigc++2',
449                                     CPPPATH='#libs/sigc++2')
450     libraries['glibmm2'] = LibraryInfo(LIBS='glibmm2',
451                                     LIBPATH='#libs/glibmm2',
452                                     CPPPATH='#libs/glibmm2')
453     libraries['pangomm'] = LibraryInfo(LIBS='pangomm',
454                                     LIBPATH='#libs/gtkmm2/pango',
455                                     CPPPATH='#libs/gtkmm2/pango')
456     libraries['atkmm'] = LibraryInfo(LIBS='atkmm',
457                                      LIBPATH='#libs/gtkmm2/atk',
458                                      CPPPATH='#libs/gtkmm2/atk')
459     libraries['gdkmm2'] = LibraryInfo(LIBS='gdkmm2',
460                                       LIBPATH='#libs/gtkmm2/gdk',
461                                       CPPPATH='#libs/gtkmm2/gdk')
462     libraries['gtkmm2'] = LibraryInfo(LIBS='gtkmm2',
463                                      LIBPATH="#libs/gtkmm2/gtk",
464                                      CPPPATH='#libs/gtkmm2/gtk/')
465     libraries['libgnomecanvasmm'] = LibraryInfo(LIBS='libgnomecanvasmm',
466                                                 LIBPATH='#libs/libgnomecanvasmm',
467                                                 CPPPATH='#libs/libgnomecanvasmm')
468
469     libraries['soundtouch'] = LibraryInfo(LIBS='soundtouch',
470                                           LIBPATH='#libs/soundtouch',
471                                           CPPPATH=['#libs', '#libs/soundtouch'])
472     libraries['libglademm'] = LibraryInfo(LIBS='libglademm',
473                                           LIBPATH='#libs/libglademm',
474                                           CPPPATH='#libs/libglademm')
475
476     coredirs = [
477         'libs/soundtouch',
478         'templates'
479     ]
480
481     subdirs = [
482 #       'libs/cassowary',
483         'libs/sigc++2',
484         'libs/pbd3',
485         'libs/midi++2',
486         'libs/ardour'
487         ]
488
489     gtk_subdirs = [
490         'libs/glibmm2',
491         'libs/gtkmm2/pango',
492         'libs/gtkmm2/atk',
493         'libs/gtkmm2/gdk',
494         'libs/gtkmm2/gtk',
495         'libs/libglademm',
496         'libs/libgnomecanvasmm',
497         'libs/flowcanvas',
498         'libs/gtkmm2ext',
499         'gtk2_ardour'
500         ]
501
502 opts.Save('scache.conf', env)
503 Help(opts.GenerateHelpText(env))
504
505 if os.environ.has_key('PATH'):
506     env.Append(PATH = os.environ['PATH'])
507
508 if os.environ.has_key('PKG_CONFIG_PATH'):
509     env.Append(PKG_CONFIG_PATH = os.environ['PKG_CONFIG_PATH'])
510
511 if os.environ.has_key('CC'):
512     env['CC'] = os.environ['CC']
513
514 if os.environ.has_key('CXX'):
515     env['CXX'] = os.environ['CXX']
516
517 if os.environ.has_key('DISTCC_HOSTS'):
518     env['ENV']['DISTCC_HOSTS'] = os.environ['DISTCC_HOSTS']
519     env['ENV']['HOME'] = os.environ['HOME']
520     
521 final_prefix = '$PREFIX'
522 install_prefix = '$DESTDIR/$PREFIX'
523
524 if env['PREFIX'] == '/usr':
525     final_config_prefix = '/etc'
526 else:
527     final_config_prefix = env['PREFIX'] + '/etc'
528
529 config_prefix = '$DESTDIR' + final_config_prefix
530
531
532 # SCons should really do this for us
533
534 conf = Configure (env)
535
536 have_cxx = conf.TryAction (Action (env['CXX'] + ' --version'));
537 if have_cxx[0] != 1:
538     print "This system has no functional C++ compiler. You cannot build Ardour from source without one."
539     exit (1);
540 else:
541     print "Congratulations, you have a functioning C++ compiler."
542     
543 env = conf.Finish()
544
545 #
546 # Compiler flags and other system-dependent stuff
547 #
548
549 opt_flags = []
550 debug_flags = [ '-g' ]
551
552 # guess at the platform, used to define compiler flags
553
554 config_guess = os.popen("tools/config.guess").read()[:-1]
555
556 config_cpu = 0;
557 config_arch = 1;
558 config_kernel = 2;
559 config_os = 3;
560 config = config_guess.split ("-")
561
562 #
563 # on OS X darwinports puts things in /opt/local by default
564 #
565 if config[config_arch] == 'apple':
566     if os.path.isdir('/opt/local/lib'):
567         libraries['core'].Append (LIBPATH = [ '/opt/local/lib' ])
568     if os.path.isdir('/opt/local/include'):
569         libraries['core'].Append (CPPPATH = [ '/opt/local/include' ])
570 if config[config_cpu] == 'powerpc':
571     #
572     # Apple/PowerPC optimization options
573     #
574     # -mcpu=7450 does not reliably work with gcc 3.*
575     #
576     if env['NOARCH'] == 0:
577         if env['ALTIVEC'] == 1:
578             if config[config_arch] == 'apple':
579                 opt_flags.extend ([ "-mcpu=7450", "-faltivec"])
580             else:
581                 opt_flags.extend ([ "-mcpu=7400", "-maltivec", "-mabi=altivec"]) 
582         else:
583             opt_flags.extend([ "-mcpu=750", "-mmultiple" ])
584         opt_flags.extend (["-mhard-float", "-mpowerpc-gfxopt"])
585
586 elif ((re.search ("i[0-9]86", config[config_cpu]) != None) or (re.search ("x86_64", config[config_cpu]) != None)):
587
588     build_host_supports_sse = 0
589     
590     if env['NOARCH'] == 0:
591
592         debug_flags.append ("-DARCH_X86")
593         opt_flags.append ("-DARCH_X86")
594
595         if config[config_kernel] == 'linux' :
596
597             flag_line = os.popen ("cat /proc/cpuinfo | grep '^flags'").read()[:-1]
598             x86_flags = flag_line.split (": ")[1:][0].split (' ')
599
600             if "mmx" in x86_flags:
601                 opt_flags.append ("-mmmx")
602             if "sse" in x86_flags:
603                 build_host_supports_sse = 1
604             if "3dnow" in x86_flags:
605                 opt_flags.append ("-m3dnow")
606
607             if config[config_cpu] == "i586":
608                 opt_flags.append ("-march=i586")
609             elif config[config_cpu] == "i686":
610                 opt_flags.append ("-march=i686")
611
612         if env['USE_SSE_EVERYWHERE'] == 1:
613                 opt_flags.extend (["-msse", "-mfpmath=sse"])
614                 debug_flags.extend (["-msse", "-mfpmath=sse"])
615                 if build_host_supports_sse != 1:
616                     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)"
617
618         if env['BUILD_SSE_OPTIMIZATIONS'] == 1:
619                 opt_flags.append ("-DBUILD_SSE_OPTIMIZATIONS")
620                 debug_flags.append ("-DBUILD_SSE_OPTIMIZATIONS")
621                 if build_host_supports_sse != 1:
622                     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)"
623                     
624 # end of processor-specific section
625
626 #
627 # ARCH="..." overrides all 
628 #
629
630 if env['ARCH'] != '':
631     opt_flags = env['ARCH'].split()
632
633 #
634 # prepend boiler plate optimization flags
635 #
636
637 opt_flags[:0] = [
638     "-O3",
639     "-fomit-frame-pointer",
640     "-ffast-math",
641     "-fstrength-reduce"
642     ]
643
644 if env['DEBUG'] == 1:
645     env.Append(CCFLAGS=" ".join (debug_flags))
646 else:
647     env.Append(CCFLAGS=" ".join (opt_flags))
648
649 env.Append(CCFLAGS="-Wall")
650
651 if env['VST']:
652     env.Append(CCFLAGS="-DVST_SUPPORT")
653
654
655 #
656 # everybody needs this
657 #
658
659 env.Merge ([ libraries['core'] ])
660
661 #
662 # i18n support 
663 #
664
665 conf = Configure (env)
666
667 if env['NLS']:
668     print 'Checking for internationalization support ...'
669     have_gettext = conf.TryAction(Action('xgettext --version'))
670     if have_gettext[0] != 1:
671         print 'This system is not configured for internationalized applications (no xgettext command). An english-only version will be built\n'
672         env['NLS'] = 0
673         
674     if conf.CheckCHeader('libintl.h') == None:
675         print 'This system is not configured for internationalized applications (no libintl.h). An english-only version will be built\n'
676         env['NLS'] = 0
677
678
679 env = conf.Finish()
680
681 if env['NLS'] == 1:
682     env.Append(CCFLAGS="-DENABLE_NLS")
683
684
685 Export('env install_prefix final_prefix config_prefix final_config_prefix libraries i18n version subst_dict')
686
687 #
688 # the configuration file may be system dependent
689 #
690
691 conf = env.Configure ()
692
693 if conf.CheckCHeader('/System/Library/Frameworks/CoreAudio.framework/Versions/A/Headers/CoreAudio.h'):
694     subst_dict['%JACK_BACKEND%'] = "coreaudio:Built-in Audio:in"
695 else:
696     subst_dict['%JACK_BACKEND%'] = "alsa_pcm:playback_"
697
698 # posix_memalign available
699 if not conf.CheckFunc('posix_memalign'):
700     print 'Did not find posix_memalign(), using malloc'
701     env.Append(CCFLAGS='-DNO_POSIX_MEMALIGN')
702
703
704 env = conf.Finish()
705
706 rcbuild = env.SubstInFile ('ardour.rc','ardour.rc.in', SUBST_DICT = subst_dict)
707
708 env.Alias('install', env.Install(os.path.join(config_prefix, 'ardour'), 'ardour_system.rc'))
709 env.Alias('install', env.Install(os.path.join(config_prefix, 'ardour'), 'ardour.rc'))
710
711 Default (rcbuild)
712
713 # source tarball
714
715 Precious (env['DISTTREE'])
716
717 #
718 # note the special "cleanfirst" source name. this triggers removal
719 # of the existing disttree
720 #
721
722 env.Distribute (env['DISTTREE'],
723                 [ 'SConstruct',
724                   'COPYING', 'PACKAGER_README', 'README',
725                   'ardour.rc.in',
726                   'ardour_system.rc',
727                   'tools/config.guess'
728                   ] +
729                 glob.glob ('DOCUMENTATION/AUTHORS*') +
730                 glob.glob ('DOCUMENTATION/CONTRIBUTORS*') +
731                 glob.glob ('DOCUMENTATION/TRANSLATORS*') +
732                 glob.glob ('DOCUMENTATION/BUILD*') +
733                 glob.glob ('DOCUMENTATION/FAQ*') +
734                 glob.glob ('DOCUMENTATION/README*')
735                 )
736                 
737 srcdist = env.Tarball(env['TARBALL'], env['DISTTREE'])
738 env.Alias ('srctar', srcdist)
739 #
740 # don't leave the distree around 
741 #
742 env.AddPreAction (env['DISTTREE'], Action ('rm -rf ' + str (File (env['DISTTREE']))))
743 env.AddPostAction (srcdist, Action ('rm -rf ' + str (File (env['DISTTREE']))))
744
745 #
746 # the subdirs
747
748
749 for subdir in coredirs:
750     SConscript (subdir + '/SConscript')
751
752 for sublistdir in [subdirs, gtk_subdirs]:
753         for subdir in sublistdir:
754                 SConscript (subdir + '/SConscript')
755
756 # cleanup
757 env.Clean ('scrub', [ 'scache.conf', '.sconf_temp', '.sconsign.dblite', 'config.log'])
758