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