17 EnsureSConsVersion(0, 96)
24 # Command-line options
27 opts = Options('scache.conf')
29 ('ARCH', 'Set architecture-specific compilation flags by hand (all flags as 1 argument)',''),
30 BoolOption('AUDIOUNITS', 'Compile with Apple\'s AudioUnit library. (experimental)', 0),
31 BoolOption('COREAUDIO', 'Compile with Apple\'s CoreAudio library', 0),
32 BoolOption('DEBUG', 'Set to build with debugging information and no optimizations', 0),
33 PathOption('DESTDIR', 'Set the intermediate install "prefix"', '/'),
34 EnumOption('DIST_TARGET', 'Build target for cross compiling packagers', 'auto', allowed_values=('auto', 'i386', 'i686', 'x86_64', 'powerpc', 'tiger', 'panther', 'none' ), ignorecase=2),
35 BoolOption('DMALLOC', 'Compile and link using the dmalloc library', 0),
36 BoolOption('EXTRA_WARN', 'Compile with -Wextra, -ansi, and -pedantic. Might break compilation. For pedants', 0),
37 BoolOption('FFT_ANALYSIS', 'Include FFT analysis window', 0),
38 BoolOption('FPU_OPTIMIZATION', 'Build runtime checked assembler code', 1),
39 BoolOption('LIBLO', 'Compile with support for liblo library', 1),
40 BoolOption('NLS', 'Set to turn on i18n support', 1),
41 PathOption('PREFIX', 'Set the install "prefix"', '/usr/local'),
42 BoolOption('SURFACES', 'Build support for control surfaces', 0),
43 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),
44 BoolOption('VERSIONED', 'Add revision information to ardour/gtk executable name inside the build directory', 0),
45 BoolOption('VST', 'Compile with support for VST', 0),
46 BoolOption('TRANZPORT', 'Compile with support for Frontier Designs (if libusb is available)', 0)
49 #----------------------------------------------------------------------
50 # a handy helper that provides a way to merge compile/link information
51 # from multiple different "environments"
52 #----------------------------------------------------------------------
54 class LibraryInfo(Environment):
55 def __init__(self,*args,**kw):
56 Environment.__init__ (self,*args,**kw)
58 def Merge (self,others):
60 self.Append (LIBS = other.get ('LIBS',[]))
61 self.Append (LIBPATH = other.get ('LIBPATH', []))
62 self.Append (CPPPATH = other.get('CPPPATH', []))
63 self.Append (LINKFLAGS = other.get('LINKFLAGS', []))
64 self.Replace(LIBPATH = list(Set(self.get('LIBPATH', []))))
65 self.Replace(CPPPATH = list(Set(self.get('CPPPATH',[]))))
66 #doing LINKFLAGS breaks -framework
67 #doing LIBS break link order dependency
69 def ENV_update(self, src_ENV):
70 for k in src_ENV.keys():
71 if k in self['ENV'].keys() and k in [ 'PATH', 'LD_LIBRARY_PATH',
73 self['ENV'][k]=SCons.Util.AppendPath(self['ENV'][k], src_ENV[k])
75 self['ENV'][k]=src_ENV[k]
77 env = LibraryInfo (options = opts,
80 TARBALL='ardour-' + version + '.tar.bz2',
82 DISTTREE = '#ardour-' + version,
83 DISTCHECKDIR = '#ardour-' + version + '/check'
86 env.ENV_update(os.environ)
88 #----------------------------------------------------------------------
90 #----------------------------------------------------------------------
92 # Handy subst-in-file builder
95 def do_subst_in_file(targetfile, sourcefile, dict):
96 """Replace all instances of the keys of dict with their values.
97 For example, if dict is {'%VERSION%': '1.2345', '%BASE%': 'MyProg'},
98 then all instances of %VERSION% in the file will be replaced with 1.2345 etc.
101 f = open(sourcefile, 'rb')
105 raise SCons.Errors.UserError, "Can't read source file %s"%sourcefile
106 for (k,v) in dict.items():
107 contents = re.sub(k, v, contents)
109 f = open(targetfile, 'wb')
113 raise SCons.Errors.UserError, "Can't write target file %s"%targetfile
116 def subst_in_file(target, source, env):
117 if not env.has_key('SUBST_DICT'):
118 raise SCons.Errors.UserError, "SubstInFile requires SUBST_DICT to be set."
119 d = dict(env['SUBST_DICT']) # copy it
120 for (k,v) in d.items():
122 d[k] = env.subst(v())
123 elif SCons.Util.is_String(v):
126 raise SCons.Errors.UserError, "SubstInFile: key %s: %s must be a string or callable"%(k, repr(v))
127 for (t,s) in zip(target, source):
128 return do_subst_in_file(str(t), str(s), d)
130 def subst_in_file_string(target, source, env):
131 """This is what gets printed on the console."""
132 return '\n'.join(['Substituting vars from %s into %s'%(str(s), str(t))
133 for (t,s) in zip(target, source)])
135 def subst_emitter(target, source, env):
136 """Add dependency from substituted SUBST_DICT to target.
137 Returns original target, source tuple unchanged.
139 d = env['SUBST_DICT'].copy() # copy it
140 for (k,v) in d.items():
142 d[k] = env.subst(v())
143 elif SCons.Util.is_String(v):
145 Depends(target, SCons.Node.Python.Value(d))
146 # Depends(target, source) # this doesn't help the install-sapphire-linux.sh problem
147 return target, source
149 subst_action = Action (subst_in_file, subst_in_file_string)
150 env['BUILDERS']['SubstInFile'] = Builder(action=subst_action, emitter=subst_emitter)
153 # internationalization
156 # po_builder: builder function to copy po files to the parent directory while updating them
158 # first source: .po file
159 # second source: .pot file
162 def po_builder(target,source,env):
163 os.spawnvp (os.P_WAIT, 'cp', ['cp', str(source[0]), str(target[0])])
169 print 'Updating ' + str(target[0])
170 return os.spawnvp (os.P_WAIT, 'msgmerge', args)
172 po_bld = Builder (action = po_builder)
173 env.Append(BUILDERS = {'PoBuild' : po_bld})
175 # mo_builder: builder function for (binary) message catalogs (.mo)
177 # first source: .po file
180 def mo_builder(target,source,env):
184 target[0].get_path(),
187 return os.spawnvp (os.P_WAIT, 'msgfmt', args)
189 mo_bld = Builder (action = mo_builder)
190 env.Append(BUILDERS = {'MoBuild' : mo_bld})
192 # pot_builder: builder function for message templates (.pot)
194 # source: list of C/C++ etc. files to extract messages from
197 def pot_builder(target,source,env):
202 '-o', target[0].get_path(),
203 "--default-domain=" + env['PACKAGE'],
204 '--copyright-holder="Paul Davis"' ]
205 args += [ src.get_path() for src in source ]
207 return os.spawnvp (os.P_WAIT, 'xgettext', args)
209 pot_bld = Builder (action = pot_builder)
210 env.Append(BUILDERS = {'PotBuild' : pot_bld})
213 # utility function, not a builder
216 def i18n (buildenv, sources, installenv):
217 domain = buildenv['PACKAGE']
218 potfile = buildenv['POTFILE']
220 installenv.Alias ('potupdate', buildenv.PotBuild (potfile, sources))
222 p_oze = [ os.path.basename (po) for po in glob.glob ('po/*.po') ]
223 languages = [ po.replace ('.po', '') for po in p_oze ]
225 for po_file in p_oze:
226 buildenv.PoBuild(po_file, ['po/'+po_file, potfile])
227 mo_file = po_file.replace (".po", ".mo")
228 installenv.Alias ('install', buildenv.MoBuild (mo_file, po_file))
230 for lang in languages:
231 modir = (os.path.join (install_prefix, 'share/locale/' + lang + '/LC_MESSAGES/'))
232 moname = domain + '.mo'
233 installenv.Alias('install', installenv.InstallAs (os.path.join (modir, moname), lang + '.mo'))
236 def fetch_svn_revision (path):
239 cmd += " | awk '/^Revision:/ { print $2}'"
240 return commands.getoutput (cmd)
242 def create_stored_revision (target = None, source = None, env = None):
243 if os.path.exists('.svn'):
244 rev = fetch_svn_revision ('.');
246 text = "#ifndef __ardour_svn_revision_h__\n"
247 text += "#define __ardour_svn_revision_h__\n"
248 text += "static const char* ardour_svn_revision = \"" + rev + "\";\n";
250 print '============> writing svn revision info to svn_revision.h\n'
251 o = file ('svn_revision.h', 'w')
255 print "Could not open svn_revision.h for writing\n"
258 print "You cannot use \"scons revision\" on without using a checked out"
259 print "copy of the Ardour source code repository"
263 # A generic builder for version.cc files
265 # note: requires that DOMAIN, MAJOR, MINOR, MICRO are set in the construction environment
266 # note: assumes one source files, the header that declares the version variables
269 def version_builder (target, source, env):
271 text = "int " + env['DOMAIN'] + "_major_version = " + str (env['MAJOR']) + ";\n"
272 text += "int " + env['DOMAIN'] + "_minor_version = " + str (env['MINOR']) + ";\n"
273 text += "int " + env['DOMAIN'] + "_micro_version = " + str (env['MICRO']) + ";\n"
276 o = file (target[0].get_path(), 'w')
280 print "Could not open", target[0].get_path(), " for writing\n"
283 text = "#ifndef __" + env['DOMAIN'] + "_version_h__\n"
284 text += "#define __" + env['DOMAIN'] + "_version_h__\n"
285 text += "extern const char* " + env['DOMAIN'] + "_revision;\n"
286 text += "extern int " + env['DOMAIN'] + "_major_version;\n"
287 text += "extern int " + env['DOMAIN'] + "_minor_version;\n"
288 text += "extern int " + env['DOMAIN'] + "_micro_version;\n"
289 text += "#endif /* __" + env['DOMAIN'] + "_version_h__ */\n"
292 o = file (target[1].get_path(), 'w')
296 print "Could not open", target[1].get_path(), " for writing\n"
301 version_bld = Builder (action = version_builder)
302 env.Append (BUILDERS = {'VersionBuild' : version_bld})
305 # a builder that makes a hard link from the 'source' executable to a name with
306 # a "build ID" based on the most recent CVS activity that might be reasonably
307 # related to version activity. this relies on the idea that the SConscript
308 # file that builds the executable is updated with new version info and committed
309 # to the source code repository whenever things change.
312 def versioned_builder(target,source,env):
313 w, r = os.popen2( "svn info | awk '/^Revision:/ { print $2}'")
315 last_revision = r.readline().strip()
318 if last_revision == "":
319 print "No SVN info found - versioned executable cannot be built"
322 print "The current build ID is " + last_revision
324 tagged_executable = source[0].get_path() + '-' + last_revision
326 if os.path.exists (tagged_executable):
327 print "Replacing existing executable with the same build tag."
328 os.unlink (tagged_executable)
330 return os.link (source[0].get_path(), tagged_executable)
332 verbuild = Builder (action = versioned_builder)
333 env.Append (BUILDERS = {'VersionedExecutable' : verbuild})
336 # source tar file builder
339 def distcopy (target, source, env):
340 treedir = str (target[0])
344 except OSError, (errnum, strerror):
345 if errnum != errno.EEXIST:
346 print 'mkdir ', treedir, ':', strerror
350 # we don't know what characters might be in the file names
351 # so quote them all before passing them to the shell
353 all_files = ([ str(s) for s in source ])
354 cmd += " ".join ([ "'%s'" % quoted for quoted in all_files])
355 cmd += ' | (cd ' + treedir + ' && tar xf -)'
359 def tarballer (target, source, env):
360 cmd = 'tar -jcf ' + str (target[0]) + ' ' + str(source[0]) + " --exclude '*~'"
361 print 'running ', cmd, ' ... '
365 dist_bld = Builder (action = distcopy,
366 target_factory = SCons.Node.FS.default_fs.Entry,
367 source_factory = SCons.Node.FS.default_fs.Entry,
370 tarball_bld = Builder (action = tarballer,
371 target_factory = SCons.Node.FS.default_fs.Entry,
372 source_factory = SCons.Node.FS.default_fs.Entry)
374 env.Append (BUILDERS = {'Distribute' : dist_bld})
375 env.Append (BUILDERS = {'Tarball' : tarball_bld})
378 # Make sure they know what they are doing
382 sys.stdout.write ("Are you building Ardour for personal use (rather than distribution to others)? [no]: ")
383 answer = sys.stdin.readline ()
384 answer = answer.rstrip().strip()
385 if answer != "yes" and answer != "y":
386 print 'You cannot build Ardour with VST support for distribution to others.\nIt is a violation of several different licenses. Build with VST=false.'
389 print "OK, VST support will be enabled"
392 # ----------------------------------------------------------------------
393 # Construction environment setup
394 # ----------------------------------------------------------------------
398 libraries['core'] = LibraryInfo (CCFLAGS = '-Ilibs')
400 #libraries['sndfile'] = LibraryInfo()
401 #libraries['sndfile'].ParseConfig('pkg-config --cflags --libs sndfile')
403 libraries['lrdf'] = LibraryInfo()
404 libraries['lrdf'].ParseConfig('pkg-config --cflags --libs lrdf')
406 libraries['raptor'] = LibraryInfo()
407 libraries['raptor'].ParseConfig('pkg-config --cflags --libs raptor')
409 libraries['samplerate'] = LibraryInfo()
410 libraries['samplerate'].ParseConfig('pkg-config --cflags --libs samplerate')
412 if env['FFT_ANALYSIS']:
413 libraries['fftw3f'] = LibraryInfo()
414 libraries['fftw3f'].ParseConfig('pkg-config --cflags --libs fftw3f')
416 libraries['jack'] = LibraryInfo()
417 libraries['jack'].ParseConfig('pkg-config --cflags --libs jack')
419 libraries['xml'] = LibraryInfo()
420 libraries['xml'].ParseConfig('pkg-config --cflags --libs libxml-2.0')
422 libraries['xslt'] = LibraryInfo()
423 libraries['xslt'].ParseConfig('pkg-config --cflags --libs libxslt')
425 libraries['glib2'] = LibraryInfo()
426 libraries['glib2'].ParseConfig ('pkg-config --cflags --libs glib-2.0')
427 libraries['glib2'].ParseConfig ('pkg-config --cflags --libs gobject-2.0')
428 libraries['glib2'].ParseConfig ('pkg-config --cflags --libs gmodule-2.0')
429 libraries['glib2'].ParseConfig ('pkg-config --cflags --libs gthread-2.0')
431 libraries['gtk2'] = LibraryInfo()
432 libraries['gtk2'].ParseConfig ('pkg-config --cflags --libs gtk+-2.0')
434 libraries['pango'] = LibraryInfo()
435 libraries['pango'].ParseConfig ('pkg-config --cflags --libs pango')
437 libraries['libgnomecanvas2'] = LibraryInfo()
438 libraries['libgnomecanvas2'].ParseConfig ('pkg-config --cflags --libs libgnomecanvas-2.0')
440 #libraries['flowcanvas'] = LibraryInfo(LIBS='flowcanvas', LIBPATH='#/libs/flowcanvas', CPPPATH='#libs/flowcanvas')
442 # The Ardour Control Protocol Library
444 libraries['ardour_cp'] = LibraryInfo (LIBS='ardour_cp', LIBPATH='#libs/surfaces/control_protocol',
445 CPPPATH='#libs/surfaces/control_protocol')
447 # The Ardour backend/engine
449 libraries['ardour'] = LibraryInfo (LIBS='ardour', LIBPATH='#libs/ardour', CPPPATH='#libs/ardour')
450 libraries['midi++2'] = LibraryInfo (LIBS='midi++', LIBPATH='#libs/midi++2', CPPPATH='#libs/midi++2')
451 libraries['pbd'] = LibraryInfo (LIBS='pbd', LIBPATH='#libs/pbd', CPPPATH='#libs/pbd')
452 libraries['gtkmm2ext'] = LibraryInfo (LIBS='gtkmm2ext', LIBPATH='#libs/gtkmm2ext', CPPPATH='#libs/gtkmm2ext')
457 libraries['usb'] = LibraryInfo ()
459 conf = Configure (libraries['usb'])
460 if conf.CheckLib ('usb', 'usb_interrupt_write'):
465 libraries['usb'] = conf.Finish ()
470 libraries['flac'] = LibraryInfo ()
472 conf = Configure (libraries['flac'])
473 conf.CheckLib ('FLAC', 'FLAC__stream_decoder_new', language='CXX')
474 libraries['flac'] = conf.Finish ()
476 # or if that fails...
477 #libraries['flac'] = LibraryInfo (LIBS='FLAC')
479 # boost (we don't link against boost, just use some header files)
481 libraries['boost'] = LibraryInfo ()
482 conf = Configure (libraries['boost'])
483 if conf.CheckHeader ('boost/shared_ptr.hpp', language='CXX') == False:
484 print "Boost header files do not appear to be installed."
487 libraries['boost'] = conf.Finish ()
493 libraries['lo'] = LibraryInfo ()
495 conf = Configure (libraries['lo'])
496 if conf.CheckLib ('lo', 'lo_server_new') == False:
497 print "liblo does not appear to be installed."
500 libraries['lo'] = conf.Finish ()
505 libraries['dmalloc'] = LibraryInfo ()
508 # look for the threaded version
511 conf = Configure (libraries['dmalloc'])
512 if conf.CheckLib ('dmallocth', 'dmalloc_shutdown'):
513 have_libdmalloc = True
515 have_libdmalloc = False
517 libraries['dmalloc'] = conf.Finish ()
520 # Audio/MIDI library (needed for MIDI, since audio is all handled via JACK)
523 conf = Configure(env)
525 if conf.CheckCHeader('alsa/asoundlib.h'):
526 libraries['sysmidi'] = LibraryInfo (LIBS='asound')
527 env['SYSMIDI'] = 'ALSA Sequencer'
528 subst_dict['%MIDITAG%'] = "seq"
529 subst_dict['%MIDITYPE%'] = "alsa/sequencer"
530 elif conf.CheckCHeader('/System/Library/Frameworks/CoreMIDI.framework/Headers/CoreMIDI.h'):
531 # this line is needed because scons can't handle -framework in ParseConfig() yet.
532 libraries['sysmidi'] = LibraryInfo (LINKFLAGS= '-framework CoreMIDI -framework CoreFoundation -framework CoreAudio -framework CoreServices -framework AudioUnit -framework AudioToolbox -bind_at_load')
533 env['SYSMIDI'] = 'CoreMIDI'
534 subst_dict['%MIDITAG%'] = "ardour"
535 subst_dict['%MIDITYPE%'] = "coremidi"
537 print "It appears you don't have the required MIDI libraries installed. For Linux this means you are missing the development package for ALSA libraries."
544 libraries['sigc2'] = LibraryInfo()
545 libraries['sigc2'].ParseConfig('pkg-config --cflags --libs sigc++-2.0')
546 libraries['glibmm2'] = LibraryInfo()
547 libraries['glibmm2'].ParseConfig('pkg-config --cflags --libs glibmm-2.4')
548 libraries['gdkmm2'] = LibraryInfo()
549 libraries['gdkmm2'].ParseConfig ('pkg-config --cflags --libs gdkmm-2.4')
550 libraries['gtkmm2'] = LibraryInfo()
551 libraries['gtkmm2'].ParseConfig ('pkg-config --cflags --libs gtkmm-2.4')
552 libraries['atkmm'] = LibraryInfo()
553 libraries['atkmm'].ParseConfig ('pkg-config --cflags --libs atkmm-1.6')
554 libraries['pangomm'] = LibraryInfo()
555 libraries['pangomm'].ParseConfig ('pkg-config --cflags --libs pangomm-1.4')
556 libraries['libgnomecanvasmm'] = LibraryInfo()
557 libraries['libgnomecanvasmm'].ParseConfig ('pkg-config --cflags --libs libgnomecanvasmm-2.6')
560 # cannot use system one for the time being
563 libraries['sndfile-ardour'] = LibraryInfo(LIBS='libsndfile-ardour',
564 LIBPATH='#libs/libsndfile',
565 CPPPATH=['#libs/libsndfile', '#libs/libsndfile/src'])
567 # libraries['libglademm'] = LibraryInfo()
568 # libraries['libglademm'].ParseConfig ('pkg-config --cflags --libs libglademm-2.4')
570 # libraries['flowcanvas'] = LibraryInfo(LIBS='flowcanvas', LIBPATH='#/libs/flowcanvas', CPPPATH='#libs/flowcanvas')
571 libraries['soundtouch'] = LibraryInfo()
572 libraries['soundtouch'].ParseConfig ('pkg-config --cflags --libs soundtouch-1.0')
574 libraries['appleutility'] = LibraryInfo(LIBS='libappleutility',
575 LIBPATH='#libs/appleutility',
576 CPPPATH='#libs/appleutility')
587 # these are unconditionally included but have
588 # tests internally to avoid compilation etc
592 # this is unconditionally included but has
593 # tests internally to avoid compilation etc
594 # if COREAUDIO is not set
606 libraries['sigc2'] = LibraryInfo(LIBS='sigc++2',
607 LIBPATH='#libs/sigc++2',
608 CPPPATH='#libs/sigc++2')
609 libraries['glibmm2'] = LibraryInfo(LIBS='glibmm2',
610 LIBPATH='#libs/glibmm2',
611 CPPPATH='#libs/glibmm2')
612 libraries['pangomm'] = LibraryInfo(LIBS='pangomm',
613 LIBPATH='#libs/gtkmm2/pango',
614 CPPPATH='#libs/gtkmm2/pango')
615 libraries['atkmm'] = LibraryInfo(LIBS='atkmm',
616 LIBPATH='#libs/gtkmm2/atk',
617 CPPPATH='#libs/gtkmm2/atk')
618 libraries['gdkmm2'] = LibraryInfo(LIBS='gdkmm2',
619 LIBPATH='#libs/gtkmm2/gdk',
620 CPPPATH='#libs/gtkmm2/gdk')
621 libraries['gtkmm2'] = LibraryInfo(LIBS='gtkmm2',
622 LIBPATH="#libs/gtkmm2/gtk",
623 CPPPATH='#libs/gtkmm2/gtk/')
624 libraries['libgnomecanvasmm'] = LibraryInfo(LIBS='libgnomecanvasmm',
625 LIBPATH='#libs/libgnomecanvasmm',
626 CPPPATH='#libs/libgnomecanvasmm')
628 libraries['soundtouch'] = LibraryInfo(LIBS='soundtouch',
629 LIBPATH='#libs/soundtouch',
630 CPPPATH=['#libs', '#libs/soundtouch'])
631 libraries['sndfile-ardour'] = LibraryInfo(LIBS='libsndfile-ardour',
632 LIBPATH='#libs/libsndfile',
633 CPPPATH=['#libs/libsndfile', '#libs/libsndfile/src'])
634 # libraries['libglademm'] = LibraryInfo(LIBS='libglademm',
635 # LIBPATH='#libs/libglademm',
636 # CPPPATH='#libs/libglademm')
637 libraries['appleutility'] = LibraryInfo(LIBS='libappleutility',
638 LIBPATH='#libs/appleutility',
639 CPPPATH='#libs/appleutility')
652 # these are unconditionally included but have
653 # tests internally to avoid compilation etc
657 # this is unconditionally included but has
658 # tests internally to avoid compilation etc
659 # if COREAUDIO is not set
669 'libs/libgnomecanvasmm',
677 # * always build the LGPL control protocol lib, since we link against it from libardour
678 # * ditto for generic MIDI
679 # * tranzport checks whether it should build internally, but we need here so that
680 # its included in the tarball
683 surface_subdirs = [ 'libs/surfaces/control_protocol', 'libs/surfaces/generic_midi', 'libs/surfaces/tranzport' ]
687 env['TRANZPORT'] = 'yes'
688 if os.access ('libs/surfaces/sony9pin', os.F_OK):
689 surface_subdirs += [ 'libs/surfaces/sony9pin' ]
691 opts.Save('scache.conf', env)
692 Help(opts.GenerateHelpText(env))
694 if os.environ.has_key('PATH'):
695 env.Append(PATH = os.environ['PATH'])
697 if os.environ.has_key('PKG_CONFIG_PATH'):
698 env.Append(PKG_CONFIG_PATH = os.environ['PKG_CONFIG_PATH'])
700 if os.environ.has_key('CC'):
701 env['CC'] = os.environ['CC']
703 if os.environ.has_key('CXX'):
704 env['CXX'] = os.environ['CXX']
706 if os.environ.has_key('DISTCC_HOSTS'):
707 env['ENV']['DISTCC_HOSTS'] = os.environ['DISTCC_HOSTS']
708 env['ENV']['HOME'] = os.environ['HOME']
710 final_prefix = '$PREFIX'
713 install_prefix = '$DESTDIR/$PREFIX'
715 install_prefix = env['PREFIX']
717 subst_dict['%INSTALL_PREFIX%'] = install_prefix;
718 subst_dict['%FINAL_PREFIX%'] = final_prefix;
719 subst_dict['%PREFIX%'] = final_prefix;
721 if env['PREFIX'] == '/usr':
722 final_config_prefix = '/etc'
724 final_config_prefix = env['PREFIX'] + '/etc'
726 config_prefix = '$DESTDIR' + final_config_prefix
728 # SCons should really do this for us
730 conf = Configure (env)
732 have_cxx = conf.TryAction (Action (str(env['CXX']) + ' --version'))
734 print "This system has no functional C++ compiler. You cannot build Ardour from source without one."
737 print "Congratulations, you have a functioning C++ compiler."
742 # Compiler flags and other system-dependent stuff
746 debug_flags = [ '-g' ]
748 # guess at the platform, used to define compiler flags
750 config_guess = os.popen("tools/config.guess").read()[:-1]
756 config = config_guess.split ("-")
758 print "system triple: " + config_guess
761 if env['DIST_TARGET'] == 'auto':
762 if config[config_arch] == 'apple':
763 # The [.] matches to the dot after the major version, "." would match any character
764 if re.search ("darwin[0-7][.]", config[config_kernel]) != None:
765 env['DIST_TARGET'] = 'panther'
767 env['DIST_TARGET'] = 'tiger'
769 if re.search ("x86_64", config[config_cpu]) != None:
770 env['DIST_TARGET'] = 'x86_64'
771 elif re.search("i[0-5]86", config[config_cpu]) != None:
772 env['DIST_TARGET'] = 'i386'
773 elif re.search("powerpc", config[config_cpu]) != None:
774 env['DIST_TARGET'] = 'powerpc'
776 env['DIST_TARGET'] = 'i686'
777 print "\n*******************************"
778 print "detected DIST_TARGET = " + env['DIST_TARGET']
779 print "*******************************\n"
782 if config[config_cpu] == 'powerpc' and env['DIST_TARGET'] != 'none':
784 # Apple/PowerPC optimization options
786 # -mcpu=7450 does not reliably work with gcc 3.*
788 if env['DIST_TARGET'] == 'panther' or env['DIST_TARGET'] == 'tiger':
789 if config[config_arch] == 'apple':
790 opt_flags.extend ([ "-mcpu=7450", "-faltivec"])
792 opt_flags.extend ([ "-mcpu=7400", "-maltivec", "-mabi=altivec"])
794 opt_flags.extend([ "-mcpu=750", "-mmultiple" ])
795 opt_flags.extend (["-mhard-float", "-mpowerpc-gfxopt"])
797 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':
799 build_host_supports_sse = 0
801 debug_flags.append ("-DARCH_X86")
802 opt_flags.append ("-DARCH_X86")
804 if config[config_kernel] == 'linux' :
806 if env['DIST_TARGET'] != 'i386':
808 flag_line = os.popen ("cat /proc/cpuinfo | grep '^flags'").read()[:-1]
809 x86_flags = flag_line.split (": ")[1:][0].split (' ')
811 if "mmx" in x86_flags:
812 opt_flags.append ("-mmmx")
813 if "sse" in x86_flags:
814 build_host_supports_sse = 1
815 if "3dnow" in x86_flags:
816 opt_flags.append ("-m3dnow")
818 if config[config_cpu] == "i586":
819 opt_flags.append ("-march=i586")
820 elif config[config_cpu] == "i686":
821 opt_flags.append ("-march=i686")
823 if ((env['DIST_TARGET'] == 'i686') or (env['DIST_TARGET'] == 'x86_64')) and build_host_supports_sse:
824 opt_flags.extend (["-msse", "-mfpmath=sse"])
825 debug_flags.extend (["-msse", "-mfpmath=sse"])
826 # end of processor-specific section
828 # optimization section
829 if env['FPU_OPTIMIZATION']:
830 if env['DIST_TARGET'] == 'tiger':
831 opt_flags.append ("-DBUILD_VECLIB_OPTIMIZATIONS")
832 debug_flags.append ("-DBUILD_VECLIB_OPTIMIZATIONS")
833 libraries['core'].Append(LINKFLAGS= '-framework Accelerate')
834 elif env['DIST_TARGET'] == 'i686' or env['DIST_TARGET'] == 'x86_64':
835 opt_flags.append ("-DBUILD_SSE_OPTIMIZATIONS")
836 debug_flags.append ("-DBUILD_SSE_OPTIMIZATIONS")
837 if env['DIST_TARGET'] == 'x86_64':
838 opt_flags.append ("-DUSE_X86_64_ASM")
839 debug_flags.append ("-DUSE_X86_64_ASM")
840 if build_host_supports_sse != 1:
841 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)"
842 # end optimization section
845 # save off guessed arch element in an env
847 env.Append(CONFIG_ARCH=config[config_arch])
851 # ARCH="..." overrides all
854 if env['ARCH'] != '':
855 opt_flags = env['ARCH'].split()
858 # prepend boiler plate optimization flags
863 "-fomit-frame-pointer",
868 if env['DEBUG'] == 1:
869 env.Append(CCFLAGS=" ".join (debug_flags))
871 env.Append(CCFLAGS=" ".join (opt_flags))
877 env.Append(CCFLAGS="-Wall")
878 env.Append(CXXFLAGS="-Woverloaded-virtual")
880 if env['EXTRA_WARN']:
881 env.Append(CCFLAGS="-Wextra -pedantic")
882 env.Append(CXXFLAGS="-ansi")
885 env.Append(CCFLAGS="-DHAVE_LIBLO")
888 # everybody needs this
891 env.Merge ([ libraries['core'] ])
894 # fix scons nitpickiness on APPLE
897 if env['DIST_TARGET'] == 'panther' or env['DIST_TARGET'] == 'tiger':
898 env.Append(CCFLAGS="-I/opt/local/include", LINKFLAGS="-L/opt/local/lib")
904 conf = Configure (env)
906 nls_error = 'This system is not configured for internationalized applications. An english-only version will be built:'
907 print 'Checking for internationalization support ...'
908 have_gettext = conf.TryAction(Action('xgettext --version'))
909 if have_gettext[0] != 1:
910 nls_error += ' No xgettext command.'
913 print "Found xgettext"
915 have_msgmerge = conf.TryAction(Action('msgmerge --version'))
916 if have_msgmerge[0] != 1:
917 nls_error += ' No msgmerge command.'
920 print "Found msgmerge"
922 if not conf.CheckCHeader('libintl.h'):
923 nls_error += ' No libintl.h.'
929 print "International version will be built."
933 env.Append(CCFLAGS="-DENABLE_NLS")
935 Export('env install_prefix final_prefix config_prefix final_config_prefix libraries i18n version subst_dict')
938 # the configuration file may be system dependent
941 conf = env.Configure ()
943 if conf.CheckCHeader('/System/Library/Frameworks/CoreAudio.framework/Versions/A/Headers/CoreAudio.h'):
944 subst_dict['%JACK_INPUT%'] = "coreaudio:Built-in Audio:in"
945 subst_dict['%JACK_OUTPUT%'] = "coreaudio:Built-in Audio:out"
947 subst_dict['%JACK_INPUT%'] = "alsa_pcm:playback_"
948 subst_dict['%JACK_OUTPUT%'] = "alsa_pcm:capture_"
950 # posix_memalign available
951 if not conf.CheckFunc('posix_memalign'):
952 print 'Did not find posix_memalign(), using malloc'
953 env.Append(CCFLAGS='-DNO_POSIX_MEMALIGN')
958 rcbuild = env.SubstInFile ('ardour.rc','ardour.rc.in', SUBST_DICT = subst_dict)
960 the_revision = env.Command ('frobnicatory_decoy', [], create_stored_revision)
962 env.Alias('revision', the_revision)
963 env.Alias('install', env.Install(os.path.join(config_prefix, 'ardour2'), 'ardour_system.rc'))
964 env.Alias('install', env.Install(os.path.join(config_prefix, 'ardour2'), 'ardour.rc'))
970 Precious (env['DISTTREE'])
972 env.Distribute (env['DISTTREE'],
973 [ 'SConstruct', 'svn_revision.h',
974 'COPYING', 'PACKAGER_README', 'README',
977 'tools/config.guess',
978 'icons/icon/ardour_icon_mac_mask.png',
979 'icons/icon/ardour_icon_mac.png',
980 'icons/icon/ardour_icon_tango_16px_blue.png',
981 'icons/icon/ardour_icon_tango_16px_red.png',
982 'icons/icon/ardour_icon_tango_22px_blue.png',
983 'icons/icon/ardour_icon_tango_22px_red.png',
984 'icons/icon/ardour_icon_tango_32px_blue.png',
985 'icons/icon/ardour_icon_tango_32px_red.png',
986 'icons/icon/ardour_icon_tango_48px_blue.png',
987 'icons/icon/ardour_icon_tango_48px_red.png'
989 glob.glob ('DOCUMENTATION/AUTHORS*') +
990 glob.glob ('DOCUMENTATION/CONTRIBUTORS*') +
991 glob.glob ('DOCUMENTATION/TRANSLATORS*') +
992 glob.glob ('DOCUMENTATION/BUILD*') +
993 glob.glob ('DOCUMENTATION/FAQ*') +
994 glob.glob ('DOCUMENTATION/README*')
997 srcdist = env.Tarball(env['TARBALL'], [ env['DISTTREE'], the_revision ])
998 env.Alias ('srctar', srcdist)
1001 # don't leave the distree around
1004 env.AddPreAction (env['DISTTREE'], Action ('rm -rf ' + str (File (env['DISTTREE']))))
1005 env.AddPostAction (srcdist, Action ('rm -rf ' + str (File (env['DISTTREE']))))
1011 for subdir in coredirs:
1012 SConscript (subdir + '/SConscript')
1014 for sublistdir in [ subdirs, gtk_subdirs, surface_subdirs ]:
1015 for subdir in sublistdir:
1016 SConscript (subdir + '/SConscript')
1019 env.Clean ('scrub', [ 'scache.conf', '.sconf_temp', '.sconsign.dblite', 'config.log'])