16 EnsureSConsVersion(0, 96)
23 # Command-line options
26 opts = Options('scache.conf')
28 ('ARCH', 'Set architecture-specific compilation flags by hand (all flags as 1 argument)',''),
29 BoolOption('AUDIOUNITS', 'Compile with Apple\'s AudioUnit library. (experimental)', 0),
30 BoolOption('COREAUDIO', 'Compile with Apple\'s CoreAudio library', 0),
31 BoolOption('DEBUG', 'Set to build with debugging information and no optimizations', 0),
32 PathOption('DESTDIR', 'Set the intermediate install "prefix"', '/'),
33 EnumOption('DIST_TARGET', 'Build target for cross compiling packagers', 'auto', allowed_values=('auto', 'i386', 'i686', 'x86_64', 'powerpc', 'tiger', 'panther', 'none' ), ignorecase=2),
34 BoolOption('DMALLOC', 'Compile and link using the dmalloc library', 0),
35 BoolOption('EXTRA_WARN', 'Compile with -Wextra, -ansi, and -pedantic. Might break compilation. For pedants', 0),
36 BoolOption('FFT_ANALYSIS', 'Include FFT analysis window', 0),
37 BoolOption('FPU_OPTIMIZATION', 'Build runtime checked assembler code', 1),
38 BoolOption('LIBLO', 'Compile with support for liblo library', 1),
39 BoolOption('NLS', 'Set to turn on i18n support', 1),
40 PathOption('PREFIX', 'Set the install "prefix"', '/usr/local'),
41 BoolOption('SURFACES', 'Build support for control surfaces', 0),
42 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),
43 BoolOption('VERSIONED', 'Add version information to ardour/gtk executable name inside the build directory', 0),
44 BoolOption('VST', 'Compile with support for VST', 0)
47 #----------------------------------------------------------------------
48 # a handy helper that provides a way to merge compile/link information
49 # from multiple different "environments"
50 #----------------------------------------------------------------------
52 class LibraryInfo(Environment):
53 def __init__(self,*args,**kw):
54 Environment.__init__ (self,*args,**kw)
56 def Merge (self,others):
58 self.Append (LIBS = other.get ('LIBS',[]))
59 self.Append (LIBPATH = other.get ('LIBPATH', []))
60 self.Append (CPPPATH = other.get('CPPPATH', []))
61 self.Append (LINKFLAGS = other.get('LINKFLAGS', []))
62 self.Replace(LIBPATH = list(Set(self.get('LIBPATH', []))))
63 self.Replace(CPPPATH = list(Set(self.get('CPPPATH',[]))))
64 #doing LINKFLAGS breaks -framework
65 #doing LIBS break link order dependency
67 def ENV_update(self, src_ENV):
68 for k in src_ENV.keys():
69 if k in self['ENV'].keys() and k in [ 'PATH', 'LD_LIBRARY_PATH',
71 self['ENV'][k]=SCons.Util.AppendPath(self['ENV'][k], src_ENV[k])
73 self['ENV'][k]=src_ENV[k]
75 env = LibraryInfo (options = opts,
78 TARBALL='ardour-' + version + '.tar.bz2',
80 DISTTREE = '#ardour-' + version,
81 DISTCHECKDIR = '#ardour-' + version + '/check'
84 env.ENV_update(os.environ)
86 #----------------------------------------------------------------------
88 #----------------------------------------------------------------------
90 # Handy subst-in-file builder
93 def do_subst_in_file(targetfile, sourcefile, dict):
94 """Replace all instances of the keys of dict with their values.
95 For example, if dict is {'%VERSION%': '1.2345', '%BASE%': 'MyProg'},
96 then all instances of %VERSION% in the file will be replaced with 1.2345 etc.
99 f = open(sourcefile, 'rb')
103 raise SCons.Errors.UserError, "Can't read source file %s"%sourcefile
104 for (k,v) in dict.items():
105 contents = re.sub(k, v, contents)
107 f = open(targetfile, 'wb')
111 raise SCons.Errors.UserError, "Can't write target file %s"%targetfile
114 def subst_in_file(target, source, env):
115 if not env.has_key('SUBST_DICT'):
116 raise SCons.Errors.UserError, "SubstInFile requires SUBST_DICT to be set."
117 d = dict(env['SUBST_DICT']) # copy it
118 for (k,v) in d.items():
120 d[k] = env.subst(v())
121 elif SCons.Util.is_String(v):
124 raise SCons.Errors.UserError, "SubstInFile: key %s: %s must be a string or callable"%(k, repr(v))
125 for (t,s) in zip(target, source):
126 return do_subst_in_file(str(t), str(s), d)
128 def subst_in_file_string(target, source, env):
129 """This is what gets printed on the console."""
130 return '\n'.join(['Substituting vars from %s into %s'%(str(s), str(t))
131 for (t,s) in zip(target, source)])
133 def subst_emitter(target, source, env):
134 """Add dependency from substituted SUBST_DICT to target.
135 Returns original target, source tuple unchanged.
137 d = env['SUBST_DICT'].copy() # copy it
138 for (k,v) in d.items():
140 d[k] = env.subst(v())
141 elif SCons.Util.is_String(v):
143 Depends(target, SCons.Node.Python.Value(d))
144 # Depends(target, source) # this doesn't help the install-sapphire-linux.sh problem
145 return target, source
147 subst_action = Action (subst_in_file, subst_in_file_string)
148 env['BUILDERS']['SubstInFile'] = Builder(action=subst_action, emitter=subst_emitter)
151 # internationalization
154 # po_builder: builder function to copy po files to the parent directory while updating them
156 # first source: .po file
157 # second source: .pot file
160 def po_builder(target,source,env):
161 os.spawnvp (os.P_WAIT, 'cp', ['cp', str(source[0]), str(target[0])])
167 print 'Updating ' + str(target[0])
168 return os.spawnvp (os.P_WAIT, 'msgmerge', args)
170 po_bld = Builder (action = po_builder)
171 env.Append(BUILDERS = {'PoBuild' : po_bld})
173 # mo_builder: builder function for (binary) message catalogs (.mo)
175 # first source: .po file
178 def mo_builder(target,source,env):
182 target[0].get_path(),
185 return os.spawnvp (os.P_WAIT, 'msgfmt', args)
187 mo_bld = Builder (action = mo_builder)
188 env.Append(BUILDERS = {'MoBuild' : mo_bld})
190 # pot_builder: builder function for message templates (.pot)
192 # source: list of C/C++ etc. files to extract messages from
195 def pot_builder(target,source,env):
200 '-o', target[0].get_path(),
201 "--default-domain=" + env['PACKAGE'],
202 '--copyright-holder="Paul Davis"' ]
203 args += [ src.get_path() for src in source ]
205 return os.spawnvp (os.P_WAIT, 'xgettext', args)
207 pot_bld = Builder (action = pot_builder)
208 env.Append(BUILDERS = {'PotBuild' : pot_bld})
211 # utility function, not a builder
214 def i18n (buildenv, sources, installenv):
215 domain = buildenv['PACKAGE']
216 potfile = buildenv['POTFILE']
218 installenv.Alias ('potupdate', buildenv.PotBuild (potfile, sources))
220 p_oze = [ os.path.basename (po) for po in glob.glob ('po/*.po') ]
221 languages = [ po.replace ('.po', '') for po in p_oze ]
223 for po_file in p_oze:
224 buildenv.PoBuild(po_file, ['po/'+po_file, potfile])
225 mo_file = po_file.replace (".po", ".mo")
226 installenv.Alias ('install', buildenv.MoBuild (mo_file, po_file))
228 for lang in languages:
229 modir = (os.path.join (install_prefix, 'share/locale/' + lang + '/LC_MESSAGES/'))
230 moname = domain + '.mo'
231 installenv.Alias('install', installenv.InstallAs (os.path.join (modir, moname), lang + '.mo'))
234 # A generic builder for version.cc files
236 # note: requires that DOMAIN, MAJOR, MINOR, MICRO are set in the construction environment
237 # note: assumes one source files, the header that declares the version variables
239 def version_builder (target, source, env):
240 text = "int " + env['DOMAIN'] + "_major_version = " + str (env['MAJOR']) + ";\n"
241 text += "int " + env['DOMAIN'] + "_minor_version = " + str (env['MINOR']) + ";\n"
242 text += "int " + env['DOMAIN'] + "_micro_version = " + str (env['MICRO']) + ";\n"
245 o = file (target[0].get_path(), 'w')
249 print "Could not open", target[0].get_path(), " for writing\n"
252 text = "#ifndef __" + env['DOMAIN'] + "_version_h__\n"
253 text += "#define __" + env['DOMAIN'] + "_version_h__\n"
254 text += "extern int " + env['DOMAIN'] + "_major_version;\n"
255 text += "extern int " + env['DOMAIN'] + "_minor_version;\n"
256 text += "extern int " + env['DOMAIN'] + "_micro_version;\n"
257 text += "#endif /* __" + env['DOMAIN'] + "_version_h__ */\n"
260 o = file (target[1].get_path(), 'w')
264 print "Could not open", target[1].get_path(), " for writing\n"
269 version_bld = Builder (action = version_builder)
270 env.Append (BUILDERS = {'VersionBuild' : version_bld})
273 # a builder that makes a hard link from the 'source' executable to a name with
274 # a "build ID" based on the most recent CVS activity that might be reasonably
275 # related to version activity. this relies on the idea that the SConscript
276 # file that builds the executable is updated with new version info and committed
277 # to the source code repository whenever things change.
280 def versioned_builder(target,source,env):
281 # build ID is composed of a representation of the date of the last CVS transaction
282 # for this (SConscript) file
285 o = file (source[0].get_dir().get_path() + '/CVS/Entries', "r")
287 print "Could not CVS/Entries for reading"
291 lines = o.readlines()
293 if line[0:12] == '/SConscript/':
294 parts = line.split ("/")
300 print "No SConscript CVS update info found - versioned executable cannot be built"
303 tag = time.strftime ('%Y%M%d%H%m', time.strptime (last_date))
304 print "The current build ID is " + tag
306 tagged_executable = source[0].get_path() + '-' + tag
308 if os.path.exists (tagged_executable):
309 print "Replacing existing executable with the same build tag."
310 os.unlink (tagged_executable)
312 return os.link (source[0].get_path(), tagged_executable)
314 verbuild = Builder (action = versioned_builder)
315 env.Append (BUILDERS = {'VersionedExecutable' : verbuild})
318 # source tar file builder
321 def distcopy (target, source, env):
322 treedir = str (target[0])
326 except OSError, (errnum, strerror):
327 if errnum != errno.EEXIST:
328 print 'mkdir ', treedir, ':', strerror
332 # we don't know what characters might be in the file names
333 # so quote them all before passing them to the shell
335 all_files = ([ str(s) for s in source ])
336 cmd += " ".join ([ "'%s'" % quoted for quoted in all_files])
337 cmd += ' | (cd ' + treedir + ' && tar xf -)'
341 def tarballer (target, source, env):
342 cmd = 'tar -jcf ' + str (target[0]) + ' ' + str(source[0]) + " --exclude '*~'"
343 print 'running ', cmd, ' ... '
347 dist_bld = Builder (action = distcopy,
348 target_factory = SCons.Node.FS.default_fs.Entry,
349 source_factory = SCons.Node.FS.default_fs.Entry,
352 tarball_bld = Builder (action = tarballer,
353 target_factory = SCons.Node.FS.default_fs.Entry,
354 source_factory = SCons.Node.FS.default_fs.Entry)
356 env.Append (BUILDERS = {'Distribute' : dist_bld})
357 env.Append (BUILDERS = {'Tarball' : tarball_bld})
360 # Make sure they know what they are doing
364 sys.stdout.write ("Are you building Ardour for personal use (rather than distributiont to others)? [no]: ")
365 answer = sys.stdin.readline ()
366 answer = answer.rstrip().strip()
367 if answer != "yes" and answer != "y":
368 print 'You cannot build Ardour with VST support for distribution to others.\nIt is a violation of several different licenses. VST support disabled.'
371 print "OK, VST support will be enabled"
374 # ----------------------------------------------------------------------
375 # Construction environment setup
376 # ----------------------------------------------------------------------
380 libraries['core'] = LibraryInfo (CCFLAGS = '-Ilibs')
382 #libraries['sndfile'] = LibraryInfo()
383 #libraries['sndfile'].ParseConfig('pkg-config --cflags --libs sndfile')
385 libraries['lrdf'] = LibraryInfo()
386 libraries['lrdf'].ParseConfig('pkg-config --cflags --libs lrdf')
388 libraries['raptor'] = LibraryInfo()
389 libraries['raptor'].ParseConfig('pkg-config --cflags --libs raptor')
391 libraries['samplerate'] = LibraryInfo()
392 libraries['samplerate'].ParseConfig('pkg-config --cflags --libs samplerate')
394 if env['FFT_ANALYSIS']:
395 libraries['fftw3f'] = LibraryInfo()
396 libraries['fftw3f'].ParseConfig('pkg-config --cflags --libs fftw3f')
398 libraries['jack'] = LibraryInfo()
399 libraries['jack'].ParseConfig('pkg-config --cflags --libs jack')
401 libraries['xml'] = LibraryInfo()
402 libraries['xml'].ParseConfig('pkg-config --cflags --libs libxml-2.0')
404 libraries['xslt'] = LibraryInfo()
405 libraries['xslt'].ParseConfig('pkg-config --cflags --libs libxslt')
407 libraries['glib2'] = LibraryInfo()
408 libraries['glib2'].ParseConfig ('pkg-config --cflags --libs glib-2.0')
409 libraries['glib2'].ParseConfig ('pkg-config --cflags --libs gobject-2.0')
410 libraries['glib2'].ParseConfig ('pkg-config --cflags --libs gmodule-2.0')
411 libraries['glib2'].ParseConfig ('pkg-config --cflags --libs gthread-2.0')
413 libraries['gtk2'] = LibraryInfo()
414 libraries['gtk2'].ParseConfig ('pkg-config --cflags --libs gtk+-2.0')
416 libraries['pango'] = LibraryInfo()
417 libraries['pango'].ParseConfig ('pkg-config --cflags --libs pango')
419 libraries['libgnomecanvas2'] = LibraryInfo()
420 libraries['libgnomecanvas2'].ParseConfig ('pkg-config --cflags --libs libgnomecanvas-2.0')
422 #libraries['flowcanvas'] = LibraryInfo(LIBS='flowcanvas', LIBPATH='#/libs/flowcanvas', CPPPATH='#libs/flowcanvas')
424 # The Ardour Control Protocol Library
426 libraries['ardour_cp'] = LibraryInfo (LIBS='ardour_cp', LIBPATH='#libs/surfaces/control_protocol',
427 CPPPATH='#libs/surfaces/control_protocol')
429 # The Ardour backend/engine
431 libraries['ardour'] = LibraryInfo (LIBS='ardour', LIBPATH='#libs/ardour', CPPPATH='#libs/ardour')
432 libraries['midi++2'] = LibraryInfo (LIBS='midi++', LIBPATH='#libs/midi++2', CPPPATH='#libs/midi++2')
433 libraries['pbd'] = LibraryInfo (LIBS='pbd', LIBPATH='#libs/pbd', CPPPATH='#libs/pbd')
434 libraries['gtkmm2ext'] = LibraryInfo (LIBS='gtkmm2ext', LIBPATH='#libs/gtkmm2ext', CPPPATH='#libs/gtkmm2ext')
439 libraries['usb'] = LibraryInfo ()
441 conf = Configure (libraries['usb'])
442 if conf.CheckLib ('usb', 'usb_interrupt_write'):
447 libraries['usb'] = conf.Finish ()
452 libraries['flac'] = LibraryInfo ()
454 conf = Configure (libraries['flac'])
455 conf.CheckLib ('FLAC', 'FLAC__stream_decoder_new', language='CXX')
456 libraries['flac'] = conf.Finish ()
458 # or if that fails...
459 #libraries['flac'] = LibraryInfo (LIBS='FLAC')
461 # boost (we don't link against boost, just use some header files)
463 libraries['boost'] = LibraryInfo ()
464 conf = Configure (libraries['boost'])
465 if conf.CheckHeader ('boost/shared_ptr.hpp', language='CXX') == 0:
466 print "Boost header files do not appear to be installed."
469 libraries['boost'] = conf.Finish ()
475 libraries['lo'] = LibraryInfo ()
477 conf = Configure (libraries['lo'])
478 if conf.CheckLib ('lo', 'lo_server_new') == False:
479 print "liblo does not appear to be installed."
482 libraries['lo'] = conf.Finish ()
487 libraries['dmalloc'] = LibraryInfo ()
490 # look for the threaded version
493 conf = Configure (libraries['dmalloc'])
494 if conf.CheckLib ('dmallocth', 'dmalloc_shutdown'):
495 have_libdmalloc = True
497 have_libdmalloc = False
499 libraries['dmalloc'] = conf.Finish ()
502 # Audio/MIDI library (needed for MIDI, since audio is all handled via JACK)
505 conf = Configure(env)
507 if conf.CheckCHeader('alsa/asoundlib.h'):
508 libraries['sysmidi'] = LibraryInfo (LIBS='asound')
509 env['SYSMIDI'] = 'ALSA Sequencer'
510 subst_dict['%MIDITAG%'] = "seq"
511 subst_dict['%MIDITYPE%'] = "alsa/sequencer"
512 elif conf.CheckCHeader('/System/Library/Frameworks/CoreMIDI.framework/Headers/CoreMIDI.h'):
513 # this line is needed because scons can't handle -framework in ParseConfig() yet.
514 libraries['sysmidi'] = LibraryInfo (LINKFLAGS= '-framework CoreMIDI -framework CoreFoundation -framework CoreAudio -framework CoreServices -framework AudioUnit -framework AudioToolbox -bind_at_load')
515 env['SYSMIDI'] = 'CoreMIDI'
516 subst_dict['%MIDITAG%'] = "ardour"
517 subst_dict['%MIDITYPE%'] = "coremidi"
519 print "It appears you don't have the required MIDI libraries installed."
526 libraries['sigc2'] = LibraryInfo()
527 libraries['sigc2'].ParseConfig('pkg-config --cflags --libs sigc++-2.0')
528 libraries['glibmm2'] = LibraryInfo()
529 libraries['glibmm2'].ParseConfig('pkg-config --cflags --libs glibmm-2.4')
530 libraries['gdkmm2'] = LibraryInfo()
531 libraries['gdkmm2'].ParseConfig ('pkg-config --cflags --libs gdkmm-2.4')
532 libraries['gtkmm2'] = LibraryInfo()
533 libraries['gtkmm2'].ParseConfig ('pkg-config --cflags --libs gtkmm-2.4')
534 libraries['atkmm'] = LibraryInfo()
535 libraries['atkmm'].ParseConfig ('pkg-config --cflags --libs atkmm-1.6')
536 libraries['pangomm'] = LibraryInfo()
537 libraries['pangomm'].ParseConfig ('pkg-config --cflags --libs pangomm-1.4')
538 libraries['libgnomecanvasmm'] = LibraryInfo()
539 libraries['libgnomecanvasmm'].ParseConfig ('pkg-config --cflags --libs libgnomecanvasmm-2.6')
542 # cannot use system one for the time being
545 libraries['sndfile'] = LibraryInfo(LIBS='libsndfile',
546 LIBPATH='#libs/libsndfile',
547 CPPPATH=['#libs/libsndfile', '#libs/libsndfile/src'])
549 # libraries['libglademm'] = LibraryInfo()
550 # libraries['libglademm'].ParseConfig ('pkg-config --cflags --libs libglademm-2.4')
552 # libraries['flowcanvas'] = LibraryInfo(LIBS='flowcanvas', LIBPATH='#/libs/flowcanvas', CPPPATH='#libs/flowcanvas')
553 libraries['soundtouch'] = LibraryInfo()
554 libraries['soundtouch'].ParseConfig ('pkg-config --cflags --libs soundtouch-1.0')
556 libraries['appleutility'] = LibraryInfo(LIBS='libappleutility',
557 LIBPATH='#libs/appleutility',
558 CPPPATH='#libs/appleutility')
572 subdirs = ['libs/fst'] + subdirs + ['vst']
575 subdirs = subdirs + ['libs/appleutility']
584 libraries['sigc2'] = LibraryInfo(LIBS='sigc++2',
585 LIBPATH='#libs/sigc++2',
586 CPPPATH='#libs/sigc++2')
587 libraries['glibmm2'] = LibraryInfo(LIBS='glibmm2',
588 LIBPATH='#libs/glibmm2',
589 CPPPATH='#libs/glibmm2')
590 libraries['pangomm'] = LibraryInfo(LIBS='pangomm',
591 LIBPATH='#libs/gtkmm2/pango',
592 CPPPATH='#libs/gtkmm2/pango')
593 libraries['atkmm'] = LibraryInfo(LIBS='atkmm',
594 LIBPATH='#libs/gtkmm2/atk',
595 CPPPATH='#libs/gtkmm2/atk')
596 libraries['gdkmm2'] = LibraryInfo(LIBS='gdkmm2',
597 LIBPATH='#libs/gtkmm2/gdk',
598 CPPPATH='#libs/gtkmm2/gdk')
599 libraries['gtkmm2'] = LibraryInfo(LIBS='gtkmm2',
600 LIBPATH="#libs/gtkmm2/gtk",
601 CPPPATH='#libs/gtkmm2/gtk/')
602 libraries['libgnomecanvasmm'] = LibraryInfo(LIBS='libgnomecanvasmm',
603 LIBPATH='#libs/libgnomecanvasmm',
604 CPPPATH='#libs/libgnomecanvasmm')
606 libraries['soundtouch'] = LibraryInfo(LIBS='soundtouch',
607 LIBPATH='#libs/soundtouch',
608 CPPPATH=['#libs', '#libs/soundtouch'])
609 libraries['sndfile'] = LibraryInfo(LIBS='libsndfile',
610 LIBPATH='#libs/libsndfile',
611 CPPPATH=['#libs/libsndfile', '#libs/libsndfile/src'])
612 # libraries['libglademm'] = LibraryInfo(LIBS='libglademm',
613 # LIBPATH='#libs/libglademm',
614 # CPPPATH='#libs/libglademm')
615 libraries['appleutility'] = LibraryInfo(LIBS='libappleutility',
616 LIBPATH='#libs/appleutility',
617 CPPPATH='#libs/appleutility')
633 subdirs = ['libs/fst'] + subdirs + ['vst']
636 subdirs = subdirs + ['libs/appleutility']
644 'libs/libgnomecanvasmm',
651 # always build the LGPL control protocol lib, since we link against it ourselves
652 # ditto for generic MIDI
655 surface_subdirs = [ 'libs/surfaces/control_protocol', 'libs/surfaces/generic_midi' ]
659 surface_subdirs += [ 'libs/surfaces/tranzport' ]
660 if os.access ('libs/surfaces/sony9pin', os.F_OK):
661 surface_subdirs += [ 'libs/surfaces/sony9pin' ]
663 opts.Save('scache.conf', env)
664 Help(opts.GenerateHelpText(env))
666 if os.environ.has_key('PATH'):
667 env.Append(PATH = os.environ['PATH'])
669 if os.environ.has_key('PKG_CONFIG_PATH'):
670 env.Append(PKG_CONFIG_PATH = os.environ['PKG_CONFIG_PATH'])
672 if os.environ.has_key('CC'):
673 env['CC'] = os.environ['CC']
675 if os.environ.has_key('CXX'):
676 env['CXX'] = os.environ['CXX']
678 if os.environ.has_key('DISTCC_HOSTS'):
679 env['ENV']['DISTCC_HOSTS'] = os.environ['DISTCC_HOSTS']
680 env['ENV']['HOME'] = os.environ['HOME']
682 final_prefix = '$PREFIX'
683 install_prefix = '$DESTDIR/$PREFIX'
685 subst_dict['INSTALL_PREFIX'] = install_prefix;
687 if env['PREFIX'] == '/usr':
688 final_config_prefix = '/etc'
690 final_config_prefix = env['PREFIX'] + '/etc'
692 config_prefix = '$DESTDIR' + final_config_prefix
695 # SCons should really do this for us
697 conf = Configure (env)
699 have_cxx = conf.TryAction (Action (env['CXX'] + ' --version'))
701 print "This system has no functional C++ compiler. You cannot build Ardour from source without one."
704 print "Congratulations, you have a functioning C++ compiler."
709 # Compiler flags and other system-dependent stuff
713 debug_flags = [ '-g' ]
715 # guess at the platform, used to define compiler flags
717 config_guess = os.popen("tools/config.guess").read()[:-1]
723 config = config_guess.split ("-")
725 print "system triple: " + config_guess
728 if env['DIST_TARGET'] == 'auto':
729 if config[config_arch] == 'apple':
730 # The [.] matches to the dot after the major version, "." would match any character
731 if re.search ("darwin[0-7][.]", config[config_kernel]) != None:
732 env['DIST_TARGET'] = 'panther'
734 env['DIST_TARGET'] = 'tiger'
736 if re.search ("x86_64", config[config_cpu]) != None:
737 env['DIST_TARGET'] = 'x86_64'
738 elif re.search("i[0-5]86", config[config_cpu]) != None:
739 env['DIST_TARGET'] = 'i386'
740 elif re.search("powerpc", config[config_cpu]) != None:
741 env['DIST_TARGET'] = 'powerpc'
743 env['DIST_TARGET'] = 'i686'
744 print "\n*******************************"
745 print "detected DIST_TARGET = " + env['DIST_TARGET']
746 print "*******************************\n"
749 if config[config_cpu] == 'powerpc' and env['DIST_TARGET'] != 'none':
751 # Apple/PowerPC optimization options
753 # -mcpu=7450 does not reliably work with gcc 3.*
755 if env['DIST_TARGET'] == 'panther' or env['DIST_TARGET'] == 'tiger':
756 if config[config_arch] == 'apple':
757 opt_flags.extend ([ "-mcpu=7450", "-faltivec"])
759 opt_flags.extend ([ "-mcpu=7400", "-maltivec", "-mabi=altivec"])
761 opt_flags.extend([ "-mcpu=750", "-mmultiple" ])
762 opt_flags.extend (["-mhard-float", "-mpowerpc-gfxopt"])
764 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':
766 build_host_supports_sse = 0
768 debug_flags.append ("-DARCH_X86")
769 opt_flags.append ("-DARCH_X86")
771 if config[config_kernel] == 'linux' :
773 if env['DIST_TARGET'] != 'i386':
775 flag_line = os.popen ("cat /proc/cpuinfo | grep '^flags'").read()[:-1]
776 x86_flags = flag_line.split (": ")[1:][0].split (' ')
778 if "mmx" in x86_flags:
779 opt_flags.append ("-mmmx")
780 if "sse" in x86_flags:
781 build_host_supports_sse = 1
782 if "3dnow" in x86_flags:
783 opt_flags.append ("-m3dnow")
785 if config[config_cpu] == "i586":
786 opt_flags.append ("-march=i586")
787 elif config[config_cpu] == "i686":
788 opt_flags.append ("-march=i686")
790 if ((env['DIST_TARGET'] == 'i686') or (env['DIST_TARGET'] == 'x86_64')) and build_host_supports_sse:
791 opt_flags.extend (["-msse", "-mfpmath=sse"])
792 debug_flags.extend (["-msse", "-mfpmath=sse"])
793 # end of processor-specific section
795 # optimization section
796 if env['FPU_OPTIMIZATION']:
797 if env['DIST_TARGET'] == 'tiger':
798 opt_flags.append ("-DBUILD_VECLIB_OPTIMIZATIONS")
799 debug_flags.append ("-DBUILD_VECLIB_OPTIMIZATIONS")
800 libraries['core'].Append(LINKFLAGS= '-framework Accelerate')
801 elif env['DIST_TARGET'] == 'i686' or env['DIST_TARGET'] == 'x86_64':
802 opt_flags.append ("-DBUILD_SSE_OPTIMIZATIONS")
803 debug_flags.append ("-DBUILD_SSE_OPTIMIZATIONS")
804 if env['DIST_TARGET'] == 'x86_64':
805 opt_flags.append ("-DUSE_X86_64_ASM")
806 debug_flags.append ("-DUSE_X86_64_ASM")
807 if build_host_supports_sse != 1:
808 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)"
809 # end optimization section
812 # save off guessed arch element in an env
814 env.Append(CONFIG_ARCH=config[config_arch])
818 # ARCH="..." overrides all
821 if env['ARCH'] != '':
822 opt_flags = env['ARCH'].split()
825 # prepend boiler plate optimization flags
830 "-fomit-frame-pointer",
835 if env['DEBUG'] == 1:
836 env.Append(CCFLAGS=" ".join (debug_flags))
838 env.Append(CCFLAGS=" ".join (opt_flags))
844 env.Append(CCFLAGS="-Wall")
845 env.Append(CXXFLAGS="-Woverloaded-virtual")
847 if env['EXTRA_WARN']:
848 env.Append(CCFLAGS="-Wextra -pedantic")
849 env.Append(CXXFLAGS="-ansi")
852 env.Append(CCFLAGS="-DHAVE_LIBLO")
855 # everybody needs this
858 env.Merge ([ libraries['core'] ])
861 # fix scons nitpickiness on APPLE
864 if env['DIST_TARGET'] == 'panther' or env['DIST_TARGET'] == 'tiger':
865 env.Append(CCFLAGS="-I/opt/local/include", LINKFLAGS="-L/opt/local/lib")
871 conf = Configure (env)
873 nls_error = 'This system is not configured for internationalized applications. An english-only version will be built:'
874 print 'Checking for internationalization support ...'
875 have_gettext = conf.TryAction(Action('xgettext --version'))
876 if have_gettext[0] != 1:
877 nls_error += ' No xgettext command.'
880 print "Found xgettext"
882 have_msgmerge = conf.TryAction(Action('msgmerge --version'))
883 if have_msgmerge[0] != 1:
884 nls_error += ' No msgmerge command.'
887 print "Found msgmerge"
889 if not conf.CheckCHeader('libintl.h'):
890 nls_error += ' No libintl.h.'
896 print "International version will be built."
900 env.Append(CCFLAGS="-DENABLE_NLS")
902 Export('env install_prefix final_prefix config_prefix final_config_prefix libraries i18n version subst_dict')
905 # the configuration file may be system dependent
908 conf = env.Configure ()
910 if conf.CheckCHeader('/System/Library/Frameworks/CoreAudio.framework/Versions/A/Headers/CoreAudio.h'):
911 subst_dict['%JACK_INPUT%'] = "coreaudio:Built-in Audio:in"
912 subst_dict['%JACK_OUTPUT%'] = "coreaudio:Built-in Audio:out"
914 subst_dict['%JACK_INPUT%'] = "alsa_pcm:playback_"
915 subst_dict['%JACK_OUTPUT%'] = "alsa_pcm:capture_"
917 # posix_memalign available
918 if not conf.CheckFunc('posix_memalign'):
919 print 'Did not find posix_memalign(), using malloc'
920 env.Append(CCFLAGS='-DNO_POSIX_MEMALIGN')
925 rcbuild = env.SubstInFile ('ardour.rc','ardour.rc.in', SUBST_DICT = subst_dict)
927 env.Alias('install', env.Install(os.path.join(config_prefix, 'ardour2'), 'ardour_system.rc'))
928 env.Alias('install', env.Install(os.path.join(config_prefix, 'ardour2'), 'ardour.rc'))
934 Precious (env['DISTTREE'])
937 # note the special "cleanfirst" source name. this triggers removal
938 # of the existing disttree
941 env.Distribute (env['DISTTREE'],
943 'COPYING', 'PACKAGER_README', 'README',
948 glob.glob ('DOCUMENTATION/AUTHORS*') +
949 glob.glob ('DOCUMENTATION/CONTRIBUTORS*') +
950 glob.glob ('DOCUMENTATION/TRANSLATORS*') +
951 glob.glob ('DOCUMENTATION/BUILD*') +
952 glob.glob ('DOCUMENTATION/FAQ*') +
953 glob.glob ('DOCUMENTATION/README*')
956 srcdist = env.Tarball(env['TARBALL'], env['DISTTREE'])
957 env.Alias ('srctar', srcdist)
959 # don't leave the distree around
961 env.AddPreAction (env['DISTTREE'], Action ('rm -rf ' + str (File (env['DISTTREE']))))
962 env.AddPostAction (srcdist, Action ('rm -rf ' + str (File (env['DISTTREE']))))
968 for subdir in coredirs:
969 SConscript (subdir + '/SConscript')
971 for sublistdir in [ subdirs, gtk_subdirs, surface_subdirs ]:
972 for subdir in sublistdir:
973 SConscript (subdir + '/SConscript')
976 env.Clean ('scrub', [ 'scache.conf', '.sconf_temp', '.sconsign.dblite', 'config.log'])