16 EnsureSConsVersion(0, 96)
18 version = '2.0beta5.1'
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. Build with VST=false.'
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)
506 if conf.CheckCHeader('jack/midiport.h'):
507 libraries['sysmidi'] = LibraryInfo (LIBS='jack')
508 env['SYSMIDI'] = 'JACK MIDI'
509 subst_dict['%MIDITAG%'] = "control"
510 subst_dict['%MIDITYPE%'] = "jack"
511 print "Using JACK MIDI"
512 elif conf.CheckCHeader('alsa/asoundlib.h'):
513 libraries['sysmidi'] = LibraryInfo (LIBS='asound')
514 env['SYSMIDI'] = 'ALSA Sequencer'
515 subst_dict['%MIDITAG%'] = "seq"
516 subst_dict['%MIDITYPE%'] = "alsa/sequencer"
517 print "Using ALSA MIDI"
518 elif conf.CheckCHeader('/System/Library/Frameworks/CoreMIDI.framework/Headers/CoreMIDI.h'):
519 # this line is needed because scons can't handle -framework in ParseConfig() yet.
520 libraries['sysmidi'] = LibraryInfo (LINKFLAGS= '-framework CoreMIDI -framework CoreFoundation -framework CoreAudio -framework CoreServices -framework AudioUnit -framework AudioToolbox -bind_at_load')
521 env['SYSMIDI'] = 'CoreMIDI'
522 subst_dict['%MIDITAG%'] = "ardour"
523 subst_dict['%MIDITYPE%'] = "coremidi"
524 print "Using CoreMIDI"
526 print "It appears you don't have the required MIDI libraries installed."
533 libraries['sigc2'] = LibraryInfo()
534 libraries['sigc2'].ParseConfig('pkg-config --cflags --libs sigc++-2.0')
535 libraries['glibmm2'] = LibraryInfo()
536 libraries['glibmm2'].ParseConfig('pkg-config --cflags --libs glibmm-2.4')
537 libraries['gdkmm2'] = LibraryInfo()
538 libraries['gdkmm2'].ParseConfig ('pkg-config --cflags --libs gdkmm-2.4')
539 libraries['gtkmm2'] = LibraryInfo()
540 libraries['gtkmm2'].ParseConfig ('pkg-config --cflags --libs gtkmm-2.4')
541 libraries['atkmm'] = LibraryInfo()
542 libraries['atkmm'].ParseConfig ('pkg-config --cflags --libs atkmm-1.6')
543 libraries['pangomm'] = LibraryInfo()
544 libraries['pangomm'].ParseConfig ('pkg-config --cflags --libs pangomm-1.4')
545 libraries['libgnomecanvasmm'] = LibraryInfo()
546 libraries['libgnomecanvasmm'].ParseConfig ('pkg-config --cflags --libs libgnomecanvasmm-2.6')
549 # cannot use system one for the time being
552 libraries['sndfile'] = LibraryInfo(LIBS='libsndfile',
553 LIBPATH='#libs/libsndfile',
554 CPPPATH=['#libs/libsndfile', '#libs/libsndfile/src'])
556 # libraries['libglademm'] = LibraryInfo()
557 # libraries['libglademm'].ParseConfig ('pkg-config --cflags --libs libglademm-2.4')
559 # libraries['flowcanvas'] = LibraryInfo(LIBS='flowcanvas', LIBPATH='#/libs/flowcanvas', CPPPATH='#libs/flowcanvas')
560 libraries['soundtouch'] = LibraryInfo()
561 libraries['soundtouch'].ParseConfig ('pkg-config --cflags --libs libSoundTouch')
563 libraries['appleutility'] = LibraryInfo(LIBS='libappleutility',
564 LIBPATH='#libs/appleutility',
565 CPPPATH='#libs/appleutility')
576 # these are unconditionally included but have
577 # tests internally to avoid compilation etc
581 # this is unconditionally included but has
582 # tests internally to avoid compilation etc
583 # if COREAUDIO is not set
594 libraries['sigc2'] = LibraryInfo(LIBS='sigc++2',
595 LIBPATH='#libs/sigc++2',
596 CPPPATH='#libs/sigc++2')
597 libraries['glibmm2'] = LibraryInfo(LIBS='glibmm2',
598 LIBPATH='#libs/glibmm2',
599 CPPPATH='#libs/glibmm2')
600 libraries['pangomm'] = LibraryInfo(LIBS='pangomm',
601 LIBPATH='#libs/gtkmm2/pango',
602 CPPPATH='#libs/gtkmm2/pango')
603 libraries['atkmm'] = LibraryInfo(LIBS='atkmm',
604 LIBPATH='#libs/gtkmm2/atk',
605 CPPPATH='#libs/gtkmm2/atk')
606 libraries['gdkmm2'] = LibraryInfo(LIBS='gdkmm2',
607 LIBPATH='#libs/gtkmm2/gdk',
608 CPPPATH='#libs/gtkmm2/gdk')
609 libraries['gtkmm2'] = LibraryInfo(LIBS='gtkmm2',
610 LIBPATH="#libs/gtkmm2/gtk",
611 CPPPATH='#libs/gtkmm2/gtk/')
612 libraries['libgnomecanvasmm'] = LibraryInfo(LIBS='libgnomecanvasmm',
613 LIBPATH='#libs/libgnomecanvasmm',
614 CPPPATH='#libs/libgnomecanvasmm')
616 libraries['soundtouch'] = LibraryInfo(LIBS='soundtouch',
617 LIBPATH='#libs/soundtouch',
618 CPPPATH=['#libs', '#libs/soundtouch'])
619 libraries['sndfile'] = LibraryInfo(LIBS='libsndfile',
620 LIBPATH='#libs/libsndfile',
621 CPPPATH=['#libs/libsndfile', '#libs/libsndfile/src'])
622 # libraries['libglademm'] = LibraryInfo(LIBS='libglademm',
623 # LIBPATH='#libs/libglademm',
624 # CPPPATH='#libs/libglademm')
625 libraries['appleutility'] = LibraryInfo(LIBS='libappleutility',
626 LIBPATH='#libs/appleutility',
627 CPPPATH='#libs/appleutility')
640 # these are unconditionally included but have
641 # tests internally to avoid compilation etc
645 # this is unconditionally included but has
646 # tests internally to avoid compilation etc
647 # if COREAUDIO is not set
657 'libs/libgnomecanvasmm',
664 # always build the LGPL control protocol lib, since we link against it ourselves
665 # ditto for generic MIDI
668 surface_subdirs = [ 'libs/surfaces/control_protocol', 'libs/surfaces/generic_midi' ]
672 surface_subdirs += [ 'libs/surfaces/tranzport' ]
673 if os.access ('libs/surfaces/sony9pin', os.F_OK):
674 surface_subdirs += [ 'libs/surfaces/sony9pin' ]
676 opts.Save('scache.conf', env)
677 Help(opts.GenerateHelpText(env))
679 if os.environ.has_key('PATH'):
680 env.Append(PATH = os.environ['PATH'])
682 if os.environ.has_key('PKG_CONFIG_PATH'):
683 env.Append(PKG_CONFIG_PATH = os.environ['PKG_CONFIG_PATH'])
685 if os.environ.has_key('CC'):
686 env['CC'] = os.environ['CC']
688 if os.environ.has_key('CXX'):
689 env['CXX'] = os.environ['CXX']
691 if os.environ.has_key('DISTCC_HOSTS'):
692 env['ENV']['DISTCC_HOSTS'] = os.environ['DISTCC_HOSTS']
693 env['ENV']['HOME'] = os.environ['HOME']
695 final_prefix = '$PREFIX'
698 install_prefix = '$DESTDIR/$PREFIX'
700 install_prefix = env['PREFIX']
702 subst_dict['%INSTALL_PREFIX%'] = install_prefix;
703 subst_dict['%FINAL_PREFIX%'] = final_prefix;
704 subst_dict['%PREFIX%'] = final_prefix;
706 if env['PREFIX'] == '/usr':
707 final_config_prefix = '/etc'
709 final_config_prefix = env['PREFIX'] + '/etc'
711 config_prefix = '$DESTDIR' + final_config_prefix
714 if os.environ.has_key('PATH'):
715 env['PATH'] = os.environ['PATH']
716 if os.environ.has_key('TERM'):
717 env['TERM'] = os.environ['TERM']
718 if os.environ.has_key('HOME'):
719 env['HOME'] = os.environ['HOME']
721 # SCons should really do this for us
723 conf = Configure (env)
725 have_cxx = conf.TryAction (Action (env['CXX'] + ' --version'))
727 print "This system has no functional C++ compiler. You cannot build Ardour from source without one."
730 print "Congratulations, you have a functioning C++ compiler."
735 # Compiler flags and other system-dependent stuff
739 debug_flags = [ '-g' ]
741 # guess at the platform, used to define compiler flags
743 config_guess = os.popen("tools/config.guess").read()[:-1]
749 config = config_guess.split ("-")
751 print "system triple: " + config_guess
754 if env['DIST_TARGET'] == 'auto':
755 if config[config_arch] == 'apple':
756 # The [.] matches to the dot after the major version, "." would match any character
757 if re.search ("darwin[0-7][.]", config[config_kernel]) != None:
758 env['DIST_TARGET'] = 'panther'
760 env['DIST_TARGET'] = 'tiger'
762 if re.search ("x86_64", config[config_cpu]) != None:
763 env['DIST_TARGET'] = 'x86_64'
764 elif re.search("i[0-5]86", config[config_cpu]) != None:
765 env['DIST_TARGET'] = 'i386'
766 elif re.search("powerpc", config[config_cpu]) != None:
767 env['DIST_TARGET'] = 'powerpc'
769 env['DIST_TARGET'] = 'i686'
770 print "\n*******************************"
771 print "detected DIST_TARGET = " + env['DIST_TARGET']
772 print "*******************************\n"
775 if config[config_cpu] == 'powerpc' and env['DIST_TARGET'] != 'none':
777 # Apple/PowerPC optimization options
779 # -mcpu=7450 does not reliably work with gcc 3.*
781 if env['DIST_TARGET'] == 'panther' or env['DIST_TARGET'] == 'tiger':
782 if config[config_arch] == 'apple':
783 opt_flags.extend ([ "-mcpu=7450", "-faltivec"])
785 opt_flags.extend ([ "-mcpu=7400", "-maltivec", "-mabi=altivec"])
787 opt_flags.extend([ "-mcpu=750", "-mmultiple" ])
788 opt_flags.extend (["-mhard-float", "-mpowerpc-gfxopt"])
790 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':
792 build_host_supports_sse = 0
794 debug_flags.append ("-DARCH_X86")
795 opt_flags.append ("-DARCH_X86")
797 if config[config_kernel] == 'linux' :
799 if env['DIST_TARGET'] != 'i386':
801 flag_line = os.popen ("cat /proc/cpuinfo | grep '^flags'").read()[:-1]
802 x86_flags = flag_line.split (": ")[1:][0].split (' ')
804 if "mmx" in x86_flags:
805 opt_flags.append ("-mmmx")
806 if "sse" in x86_flags:
807 build_host_supports_sse = 1
808 if "3dnow" in x86_flags:
809 opt_flags.append ("-m3dnow")
811 if config[config_cpu] == "i586":
812 opt_flags.append ("-march=i586")
813 elif config[config_cpu] == "i686":
814 opt_flags.append ("-march=i686")
816 if ((env['DIST_TARGET'] == 'i686') or (env['DIST_TARGET'] == 'x86_64')) and build_host_supports_sse:
817 opt_flags.extend (["-msse", "-mfpmath=sse"])
818 debug_flags.extend (["-msse", "-mfpmath=sse"])
819 # end of processor-specific section
821 # optimization section
822 if env['FPU_OPTIMIZATION']:
823 if env['DIST_TARGET'] == 'tiger':
824 opt_flags.append ("-DBUILD_VECLIB_OPTIMIZATIONS")
825 debug_flags.append ("-DBUILD_VECLIB_OPTIMIZATIONS")
826 libraries['core'].Append(LINKFLAGS= '-framework Accelerate')
827 elif env['DIST_TARGET'] == 'i686' or env['DIST_TARGET'] == 'x86_64':
828 opt_flags.append ("-DBUILD_SSE_OPTIMIZATIONS")
829 debug_flags.append ("-DBUILD_SSE_OPTIMIZATIONS")
830 if env['DIST_TARGET'] == 'x86_64':
831 opt_flags.append ("-DUSE_X86_64_ASM")
832 debug_flags.append ("-DUSE_X86_64_ASM")
833 if build_host_supports_sse != 1:
834 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)"
835 # end optimization section
838 # save off guessed arch element in an env
840 env.Append(CONFIG_ARCH=config[config_arch])
844 # ARCH="..." overrides all
847 if env['ARCH'] != '':
848 opt_flags = env['ARCH'].split()
851 # prepend boiler plate optimization flags
856 "-fomit-frame-pointer",
861 if env['DEBUG'] == 1:
862 env.Append(CCFLAGS=" ".join (debug_flags))
864 env.Append(CCFLAGS=" ".join (opt_flags))
870 env.Append(CCFLAGS="-Wall")
871 env.Append(CXXFLAGS="-Woverloaded-virtual")
873 if env['EXTRA_WARN']:
874 env.Append(CCFLAGS="-Wextra -pedantic")
875 env.Append(CXXFLAGS="-ansi")
878 env.Append(CCFLAGS="-DHAVE_LIBLO")
881 # everybody needs this
884 env.Merge ([ libraries['core'] ])
887 # fix scons nitpickiness on APPLE
890 if env['DIST_TARGET'] == 'panther' or env['DIST_TARGET'] == 'tiger':
891 env.Append(CCFLAGS="-I/opt/local/include", LINKFLAGS="-L/opt/local/lib")
897 conf = Configure (env)
899 nls_error = 'This system is not configured for internationalized applications. An english-only version will be built:'
900 print 'Checking for internationalization support ...'
901 have_gettext = conf.TryAction(Action('xgettext --version'))
902 if have_gettext[0] != 1:
903 nls_error += ' No xgettext command.'
906 print "Found xgettext"
908 have_msgmerge = conf.TryAction(Action('msgmerge --version'))
909 if have_msgmerge[0] != 1:
910 nls_error += ' No msgmerge command.'
913 print "Found msgmerge"
915 if not conf.CheckCHeader('libintl.h'):
916 nls_error += ' No libintl.h.'
922 print "International version will be built."
926 env.Append(CCFLAGS="-DENABLE_NLS")
928 Export('env install_prefix final_prefix config_prefix final_config_prefix libraries i18n version subst_dict')
931 # the configuration file may be system dependent
934 conf = env.Configure ()
936 if conf.CheckCHeader('/System/Library/Frameworks/CoreAudio.framework/Versions/A/Headers/CoreAudio.h'):
937 subst_dict['%JACK_INPUT%'] = "coreaudio:Built-in Audio:in"
938 subst_dict['%JACK_OUTPUT%'] = "coreaudio:Built-in Audio:out"
940 subst_dict['%JACK_INPUT%'] = "alsa_pcm:playback_"
941 subst_dict['%JACK_OUTPUT%'] = "alsa_pcm:capture_"
943 # posix_memalign available
944 if not conf.CheckFunc('posix_memalign'):
945 print 'Did not find posix_memalign(), using malloc'
946 env.Append(CCFLAGS='-DNO_POSIX_MEMALIGN')
951 rcbuild = env.SubstInFile ('ardour.rc','ardour.rc.in', SUBST_DICT = subst_dict)
953 env.Alias('install', env.Install(os.path.join(config_prefix, 'ardour2'), 'ardour_system.rc'))
954 env.Alias('install', env.Install(os.path.join(config_prefix, 'ardour2'), 'ardour.rc'))
960 Precious (env['DISTTREE'])
963 # note the special "cleanfirst" source name. this triggers removal
964 # of the existing disttree
967 env.Distribute (env['DISTTREE'],
969 'COPYING', 'PACKAGER_README', 'README',
972 'tools/config.guess',
973 'icons/icon/ardour_icon_mac_mask.png',
974 'icons/icon/ardour_icon_mac.png',
975 'icons/icon/ardour_icon_tango_16px_blue.png',
976 'icons/icon/ardour_icon_tango_16px_red.png',
977 'icons/icon/ardour_icon_tango_22px_blue.png',
978 'icons/icon/ardour_icon_tango_22px_red.png',
979 'icons/icon/ardour_icon_tango_32px_blue.png',
980 'icons/icon/ardour_icon_tango_32px_red.png',
981 'icons/icon/ardour_icon_tango_48px_blue.png',
982 'icons/icon/ardour_icon_tango_48px_red.png'
984 glob.glob ('DOCUMENTATION/AUTHORS*') +
985 glob.glob ('DOCUMENTATION/CONTRIBUTORS*') +
986 glob.glob ('DOCUMENTATION/TRANSLATORS*') +
987 glob.glob ('DOCUMENTATION/BUILD*') +
988 glob.glob ('DOCUMENTATION/FAQ*') +
989 glob.glob ('DOCUMENTATION/README*')
992 srcdist = env.Tarball(env['TARBALL'], env['DISTTREE'])
993 env.Alias ('srctar', srcdist)
996 # don't leave the distree around
998 env.AddPreAction (env['DISTTREE'], Action ('rm -rf ' + str (File (env['DISTTREE']))))
999 env.AddPostAction (srcdist, Action ('rm -rf ' + str (File (env['DISTTREE']))))
1005 for subdir in coredirs:
1006 SConscript (subdir + '/SConscript')
1008 for sublistdir in [ subdirs, gtk_subdirs, surface_subdirs ]:
1009 for subdir in sublistdir:
1010 SConscript (subdir + '/SConscript')
1013 env.Clean ('scrub', [ 'scache.conf', '.sconf_temp', '.sconsign.dblite', 'config.log'])