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