updated author information
[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', 'i386', allowed_values=('none', 'tiger', 'panther', 'i686', 'x86_64', 'i386'), 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 if config[config_arch] == 'apple':
574     if env['FPU_OPTIMIZATION']:
575         opt_flags.append ("-DBUILD_VECLIB_OPTIMIZATIONS")
576         debug_flags.append ("-DBUILD_VECLIB_OPTIMIZATIONS")
577         libraries['core'].Append(LINKFLAGS= '-framework Accelerate')
578
579 if config[config_cpu] == 'powerpc':
580     #
581     # Apple/PowerPC optimization options
582     #
583     # -mcpu=7450 does not reliably work with gcc 3.*
584     #
585     if env['DIST_TARGET'] == 'panther' or env['DIST_TARGET'] == 'tiger':
586         if config[config_arch] == 'apple':
587             opt_flags.extend ([ "-mcpu=7450", "-faltivec"])
588         else:
589             opt_flags.extend ([ "-mcpu=7400", "-maltivec", "-mabi=altivec"]) 
590     else:
591         opt_flags.extend([ "-mcpu=750", "-mmultiple" ])
592     opt_flags.extend (["-mhard-float", "-mpowerpc-gfxopt"])
593
594 elif ((re.search ("i[0-9]86", config[config_cpu]) != None) or (re.search ("x86_64", config[config_cpu]) != None)):
595
596     build_host_supports_sse = 0
597     
598     if env['DIST_TARGET'] != 'none':
599
600         debug_flags.append ("-DARCH_X86")
601         opt_flags.append ("-DARCH_X86")
602
603         if config[config_kernel] == 'linux' :
604
605             flag_line = os.popen ("cat /proc/cpuinfo | grep '^flags'").read()[:-1]
606             x86_flags = flag_line.split (": ")[1:][0].split (' ')
607
608             if "mmx" in x86_flags:
609                 opt_flags.append ("-mmmx")
610             if "sse" in x86_flags:
611                 build_host_supports_sse = 1
612             if "3dnow" in x86_flags:
613                 opt_flags.append ("-m3dnow")
614
615             if config[config_cpu] == "i586":
616                 opt_flags.append ("-march=i586")
617             elif config[config_cpu] == "i686":
618                 opt_flags.append ("-march=i686")
619
620         if (env['DIST_TARGET'] == 'i686') or (env['DIST_TARGET'] == 'x86_64'):
621             opt_flags.extend (["-msse", "-mfpmath=sse"])
622             debug_flags.extend (["-msse", "-mfpmath=sse"])
623             if build_host_supports_sse != 1:
624                 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)"
625
626         if env['FPU_OPTIMIZATION']:
627             opt_flags.append ("-DBUILD_SSE_OPTIMIZATIONS")
628             debug_flags.append ("-DBUILD_SSE_OPTIMIZATIONS")
629             if env['DIST_TARGET'] == 'x86_64':
630                 opt_flags.append ("-DUSE_X86_64_ASM")
631                 debug_flags.append ("-DUSE_X86_64_ASM")                 
632             if build_host_supports_sse != 1:
633                 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)"
634                     
635 # end of processor-specific section
636
637 #
638 # ARCH="..." overrides all 
639 #
640
641 if env['ARCH'] != '':
642     opt_flags = env['ARCH'].split()
643
644 #
645 # prepend boiler plate optimization flags
646 #
647
648 opt_flags[:0] = [
649     "-O3",
650     "-fomit-frame-pointer",
651     "-ffast-math",
652     "-fstrength-reduce"
653     ]
654
655 if env['DEBUG'] == 1:
656     env.Append(CCFLAGS=" ".join (debug_flags))
657 else:
658     env.Append(CCFLAGS=" ".join (opt_flags))
659
660 env.Append(CCFLAGS="-Wall")
661
662 if env['VST']:
663     env.Append(CCFLAGS="-DVST_SUPPORT")
664
665 #
666 # everybody needs this
667 #
668
669 env.Merge ([ libraries['core'] ])
670
671 #
672 # i18n support 
673 #
674
675 conf = Configure (env)
676
677 if env['NLS']:
678     print 'Checking for internationalization support ...'
679     have_gettext = conf.TryAction(Action('xgettext --version'))
680     if have_gettext[0] != 1:
681         print 'This system is not configured for internationalized applications (no xgettext command). An english-only version will be built\n'
682         env['NLS'] = 0
683         
684     if conf.CheckCHeader('libintl.h') == None:
685         print 'This system is not configured for internationalized applications (no libintl.h). An english-only version will be built\n'
686         env['NLS'] = 0
687
688
689 env = conf.Finish()
690
691 if env['NLS'] == 1:
692     env.Append(CCFLAGS="-DENABLE_NLS")
693
694
695 Export('env install_prefix final_prefix config_prefix final_config_prefix libraries i18n version subst_dict')
696
697 #
698 # the configuration file may be system dependent
699 #
700
701 conf = env.Configure ()
702
703 if conf.CheckCHeader('/System/Library/Frameworks/CoreAudio.framework/Versions/A/Headers/CoreAudio.h'):
704     subst_dict['%JACK_INPUT%'] = "coreaudio:Built-in Audio:in"
705     subst_dict['%JACK_OUTPUT%'] = "coreaudio:Built-in Audio:out"
706 else:
707     subst_dict['%JACK_INPUT%'] = "alsa_pcm:playback_"
708     subst_dict['%JACK_OUTPUT%'] = "alsa_pcm:capture_"
709
710 # posix_memalign available
711 if not conf.CheckFunc('posix_memalign'):
712     print 'Did not find posix_memalign(), using malloc'
713     env.Append(CCFLAGS='-DNO_POSIX_MEMALIGN')
714
715
716 env = conf.Finish()
717
718 rcbuild = env.SubstInFile ('ardour.rc','ardour.rc.in', SUBST_DICT = subst_dict)
719
720 env.Alias('install', env.Install(os.path.join(config_prefix, 'ardour'), 'ardour_system.rc'))
721 env.Alias('install', env.Install(os.path.join(config_prefix, 'ardour'), 'ardour.rc'))
722
723 Default (rcbuild)
724
725 # source tarball
726
727 Precious (env['DISTTREE'])
728
729 #
730 # note the special "cleanfirst" source name. this triggers removal
731 # of the existing disttree
732 #
733
734 env.Distribute (env['DISTTREE'],
735                 [ 'SConstruct',
736                   'COPYING', 'PACKAGER_README', 'README',
737                   'ardour.rc.in',
738                   'ardour_system.rc',
739                   'tools/config.guess'
740                   ] +
741                 glob.glob ('DOCUMENTATION/AUTHORS*') +
742                 glob.glob ('DOCUMENTATION/CONTRIBUTORS*') +
743                 glob.glob ('DOCUMENTATION/TRANSLATORS*') +
744                 glob.glob ('DOCUMENTATION/BUILD*') +
745                 glob.glob ('DOCUMENTATION/FAQ*') +
746                 glob.glob ('DOCUMENTATION/README*')
747                 )
748                 
749 srcdist = env.Tarball(env['TARBALL'], env['DISTTREE'])
750 env.Alias ('srctar', srcdist)
751 #
752 # don't leave the distree around 
753 #
754 env.AddPreAction (env['DISTTREE'], Action ('rm -rf ' + str (File (env['DISTTREE']))))
755 env.AddPostAction (srcdist, Action ('rm -rf ' + str (File (env['DISTTREE']))))
756
757 #
758 # the subdirs
759
760
761 for subdir in coredirs:
762     SConscript (subdir + '/SConscript')
763
764 for sublistdir in [subdirs, gtk_subdirs]:
765         for subdir in sublistdir:
766                 SConscript (subdir + '/SConscript')
767
768 # cleanup
769 env.Clean ('scrub', [ 'scache.conf', '.sconf_temp', '.sconsign.dblite', 'config.log'])
770