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