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 # Dependency Checking #
394 #######################
398 'glib-2.0' : '2.10.1',
399 'gthread-2.0' : '2.10.1',
400 'gtk+-2.0' : '2.8.1',
401 'libxml-2.0' : '2.6.0',
402 'samplerate' : '0.1.0',
406 'libgnomecanvas-2.0' : '2.0'
409 def DependenciesRequiredMessage():
410 print 'You do not have the necessary dependencies required to build ardour'
411 print 'Please consult http://ardour.org/building for more information'
413 def CheckPKGConfig(context, version):
414 context.Message( 'Checking for pkg-config version >= %s... ' %version )
415 ret = context.TryAction('pkg-config --atleast-pkgconfig-version=%s' % version)[0]
416 context.Result( ret )
419 def CheckPKGVersion(context, name, version):
420 context.Message( 'Checking for %s... ' % name )
421 ret = context.TryAction('pkg-config --atleast-version=%s %s' %(version,name) )[0]
422 context.Result( ret )
425 conf = Configure(env, custom_tests = { 'CheckPKGConfig' : CheckPKGConfig,
426 'CheckPKGVersion' : CheckPKGVersion })
428 # I think a more recent version is needed on win32
429 min_pkg_config_version = '0.8.0'
431 if not conf.CheckPKGConfig(min_pkg_config_version):
432 print 'pkg-config >= %s not found.' % min_pkg_config_version
435 for pkg, version in deps.iteritems():
436 if not conf.CheckPKGVersion( pkg, version ):
437 print '%s >= %s not found.' %(pkg, version)
438 DependenciesRequiredMessage()
443 # ----------------------------------------------------------------------
444 # Construction environment setup
445 # ----------------------------------------------------------------------
449 libraries['core'] = LibraryInfo (CCFLAGS = '-Ilibs')
451 #libraries['sndfile'] = LibraryInfo()
452 #libraries['sndfile'].ParseConfig('pkg-config --cflags --libs sndfile')
454 libraries['lrdf'] = LibraryInfo()
455 libraries['lrdf'].ParseConfig('pkg-config --cflags --libs lrdf')
457 libraries['raptor'] = LibraryInfo()
458 libraries['raptor'].ParseConfig('pkg-config --cflags --libs raptor')
460 libraries['samplerate'] = LibraryInfo()
461 libraries['samplerate'].ParseConfig('pkg-config --cflags --libs samplerate')
463 if env['FFT_ANALYSIS']:
464 libraries['fftw3f'] = LibraryInfo()
465 libraries['fftw3f'].ParseConfig('pkg-config --cflags --libs fftw3f')
467 libraries['jack'] = LibraryInfo()
468 libraries['jack'].ParseConfig('pkg-config --cflags --libs jack')
470 libraries['xml'] = LibraryInfo()
471 libraries['xml'].ParseConfig('pkg-config --cflags --libs libxml-2.0')
473 libraries['xslt'] = LibraryInfo()
474 libraries['xslt'].ParseConfig('pkg-config --cflags --libs libxslt')
476 libraries['glib2'] = LibraryInfo()
477 libraries['glib2'].ParseConfig ('pkg-config --cflags --libs glib-2.0')
478 libraries['glib2'].ParseConfig ('pkg-config --cflags --libs gobject-2.0')
479 libraries['glib2'].ParseConfig ('pkg-config --cflags --libs gmodule-2.0')
480 libraries['glib2'].ParseConfig ('pkg-config --cflags --libs gthread-2.0')
482 libraries['gtk2'] = LibraryInfo()
483 libraries['gtk2'].ParseConfig ('pkg-config --cflags --libs gtk+-2.0')
485 libraries['pango'] = LibraryInfo()
486 libraries['pango'].ParseConfig ('pkg-config --cflags --libs pango')
488 libraries['libgnomecanvas2'] = LibraryInfo()
489 libraries['libgnomecanvas2'].ParseConfig ('pkg-config --cflags --libs libgnomecanvas-2.0')
491 #libraries['flowcanvas'] = LibraryInfo(LIBS='flowcanvas', LIBPATH='#/libs/flowcanvas', CPPPATH='#libs/flowcanvas')
493 # The Ardour Control Protocol Library
495 libraries['ardour_cp'] = LibraryInfo (LIBS='ardour_cp', LIBPATH='#libs/surfaces/control_protocol',
496 CPPPATH='#libs/surfaces/control_protocol')
498 # The Ardour backend/engine
500 libraries['ardour'] = LibraryInfo (LIBS='ardour', LIBPATH='#libs/ardour', CPPPATH='#libs/ardour')
501 libraries['midi++2'] = LibraryInfo (LIBS='midi++', LIBPATH='#libs/midi++2', CPPPATH='#libs/midi++2')
502 libraries['pbd'] = LibraryInfo (LIBS='pbd', LIBPATH='#libs/pbd', CPPPATH='#libs/pbd')
503 libraries['gtkmm2ext'] = LibraryInfo (LIBS='gtkmm2ext', LIBPATH='#libs/gtkmm2ext', CPPPATH='#libs/gtkmm2ext')
508 libraries['usb'] = LibraryInfo ()
510 conf = Configure (libraries['usb'])
511 if conf.CheckLib ('usb', 'usb_interrupt_write'):
516 libraries['usb'] = conf.Finish ()
521 libraries['flac'] = LibraryInfo ()
523 conf = Configure (libraries['flac'])
524 conf.CheckLib ('FLAC', 'FLAC__stream_decoder_new', language='CXX')
525 libraries['flac'] = conf.Finish ()
527 # or if that fails...
528 #libraries['flac'] = LibraryInfo (LIBS='FLAC')
530 # boost (we don't link against boost, just use some header files)
532 libraries['boost'] = LibraryInfo ()
533 conf = Configure (libraries['boost'])
534 if conf.CheckHeader ('boost/shared_ptr.hpp', language='CXX') == False:
535 print "Boost header files do not appear to be installed."
538 libraries['boost'] = conf.Finish ()
544 libraries['lo'] = LibraryInfo ()
546 conf = Configure (libraries['lo'])
547 if conf.CheckLib ('lo', 'lo_server_new') == False:
548 print "liblo does not appear to be installed."
551 libraries['lo'] = conf.Finish ()
556 libraries['dmalloc'] = LibraryInfo ()
559 # look for the threaded version
562 conf = Configure (libraries['dmalloc'])
563 if conf.CheckLib ('dmallocth', 'dmalloc_shutdown'):
564 have_libdmalloc = True
566 have_libdmalloc = False
568 libraries['dmalloc'] = conf.Finish ()
571 # Audio/MIDI library (needed for MIDI, since audio is all handled via JACK)
574 conf = Configure(env)
576 if conf.CheckCHeader('alsa/asoundlib.h'):
577 libraries['sysmidi'] = LibraryInfo (LIBS='asound')
578 env['SYSMIDI'] = 'ALSA Sequencer'
579 subst_dict['%MIDITAG%'] = "seq"
580 subst_dict['%MIDITYPE%'] = "alsa/sequencer"
581 elif conf.CheckCHeader('/System/Library/Frameworks/CoreMIDI.framework/Headers/CoreMIDI.h'):
582 # this line is needed because scons can't handle -framework in ParseConfig() yet.
583 libraries['sysmidi'] = LibraryInfo (LINKFLAGS= '-framework CoreMIDI -framework CoreFoundation -framework CoreAudio -framework CoreServices -framework AudioUnit -framework AudioToolbox -bind_at_load')
584 env['SYSMIDI'] = 'CoreMIDI'
585 subst_dict['%MIDITAG%'] = "ardour"
586 subst_dict['%MIDITYPE%'] = "coremidi"
588 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."
597 'sigc++-2.0' : '2.0',
599 'libgnomecanvasmm-2.6' : '2.12.0'
602 conf = Configure(env, custom_tests = { 'CheckPKGConfig' : CheckPKGConfig,
603 'CheckPKGVersion' : CheckPKGVersion })
605 for pkg, version in syslibdeps.iteritems():
606 if not conf.CheckPKGVersion( pkg, version ):
607 print '%s >= %s not found.' %(pkg, version)
608 DependenciesRequiredMessage()
613 libraries['sigc2'] = LibraryInfo()
614 libraries['sigc2'].ParseConfig('pkg-config --cflags --libs sigc++-2.0')
615 libraries['glibmm2'] = LibraryInfo()
616 libraries['glibmm2'].ParseConfig('pkg-config --cflags --libs glibmm-2.4')
617 libraries['gdkmm2'] = LibraryInfo()
618 libraries['gdkmm2'].ParseConfig ('pkg-config --cflags --libs gdkmm-2.4')
619 libraries['gtkmm2'] = LibraryInfo()
620 libraries['gtkmm2'].ParseConfig ('pkg-config --cflags --libs gtkmm-2.4')
621 libraries['atkmm'] = LibraryInfo()
622 libraries['atkmm'].ParseConfig ('pkg-config --cflags --libs atkmm-1.6')
623 libraries['pangomm'] = LibraryInfo()
624 libraries['pangomm'].ParseConfig ('pkg-config --cflags --libs pangomm-1.4')
625 libraries['libgnomecanvasmm'] = LibraryInfo()
626 libraries['libgnomecanvasmm'].ParseConfig ('pkg-config --cflags --libs libgnomecanvasmm-2.6')
629 # cannot use system one for the time being
632 libraries['sndfile-ardour'] = LibraryInfo(LIBS='libsndfile-ardour',
633 LIBPATH='#libs/libsndfile',
634 CPPPATH=['#libs/libsndfile', '#libs/libsndfile/src'])
636 # libraries['libglademm'] = LibraryInfo()
637 # libraries['libglademm'].ParseConfig ('pkg-config --cflags --libs libglademm-2.4')
639 # libraries['flowcanvas'] = LibraryInfo(LIBS='flowcanvas', LIBPATH='#/libs/flowcanvas', CPPPATH='#libs/flowcanvas')
640 libraries['soundtouch'] = LibraryInfo()
641 libraries['soundtouch'].ParseConfig ('pkg-config --cflags --libs soundtouch-1.0')
643 libraries['appleutility'] = LibraryInfo(LIBS='libappleutility',
644 LIBPATH='#libs/appleutility',
645 CPPPATH='#libs/appleutility')
656 # these are unconditionally included but have
657 # tests internally to avoid compilation etc
661 # this is unconditionally included but has
662 # tests internally to avoid compilation etc
663 # if COREAUDIO is not set
675 libraries['sigc2'] = LibraryInfo(LIBS='sigc++2',
676 LIBPATH='#libs/sigc++2',
677 CPPPATH='#libs/sigc++2')
678 libraries['glibmm2'] = LibraryInfo(LIBS='glibmm2',
679 LIBPATH='#libs/glibmm2',
680 CPPPATH='#libs/glibmm2')
681 libraries['pangomm'] = LibraryInfo(LIBS='pangomm',
682 LIBPATH='#libs/gtkmm2/pango',
683 CPPPATH='#libs/gtkmm2/pango')
684 libraries['atkmm'] = LibraryInfo(LIBS='atkmm',
685 LIBPATH='#libs/gtkmm2/atk',
686 CPPPATH='#libs/gtkmm2/atk')
687 libraries['gdkmm2'] = LibraryInfo(LIBS='gdkmm2',
688 LIBPATH='#libs/gtkmm2/gdk',
689 CPPPATH='#libs/gtkmm2/gdk')
690 libraries['gtkmm2'] = LibraryInfo(LIBS='gtkmm2',
691 LIBPATH="#libs/gtkmm2/gtk",
692 CPPPATH='#libs/gtkmm2/gtk/')
693 libraries['libgnomecanvasmm'] = LibraryInfo(LIBS='libgnomecanvasmm',
694 LIBPATH='#libs/libgnomecanvasmm',
695 CPPPATH='#libs/libgnomecanvasmm')
697 libraries['soundtouch'] = LibraryInfo(LIBS='soundtouch',
698 LIBPATH='#libs/soundtouch',
699 CPPPATH=['#libs', '#libs/soundtouch'])
700 libraries['sndfile-ardour'] = LibraryInfo(LIBS='libsndfile-ardour',
701 LIBPATH='#libs/libsndfile',
702 CPPPATH=['#libs/libsndfile', '#libs/libsndfile/src'])
703 # libraries['libglademm'] = LibraryInfo(LIBS='libglademm',
704 # LIBPATH='#libs/libglademm',
705 # CPPPATH='#libs/libglademm')
706 libraries['appleutility'] = LibraryInfo(LIBS='libappleutility',
707 LIBPATH='#libs/appleutility',
708 CPPPATH='#libs/appleutility')
721 # these are unconditionally included but have
722 # tests internally to avoid compilation etc
726 # this is unconditionally included but has
727 # tests internally to avoid compilation etc
728 # if COREAUDIO is not set
738 'libs/libgnomecanvasmm',
746 # * always build the LGPL control protocol lib, since we link against it from libardour
747 # * ditto for generic MIDI
748 # * tranzport checks whether it should build internally, but we need here so that
749 # its included in the tarball
752 surface_subdirs = [ 'libs/surfaces/control_protocol', 'libs/surfaces/generic_midi', 'libs/surfaces/tranzport' ]
756 env['TRANZPORT'] = 'yes'
757 if os.access ('libs/surfaces/sony9pin', os.F_OK):
758 surface_subdirs += [ 'libs/surfaces/sony9pin' ]
760 opts.Save('scache.conf', env)
761 Help(opts.GenerateHelpText(env))
763 if os.environ.has_key('PATH'):
764 env.Append(PATH = os.environ['PATH'])
766 if os.environ.has_key('PKG_CONFIG_PATH'):
767 env.Append(PKG_CONFIG_PATH = os.environ['PKG_CONFIG_PATH'])
769 if os.environ.has_key('CC'):
770 env['CC'] = os.environ['CC']
772 if os.environ.has_key('CXX'):
773 env['CXX'] = os.environ['CXX']
775 if os.environ.has_key('DISTCC_HOSTS'):
776 env['ENV']['DISTCC_HOSTS'] = os.environ['DISTCC_HOSTS']
777 env['ENV']['HOME'] = os.environ['HOME']
779 final_prefix = '$PREFIX'
782 install_prefix = '$DESTDIR/$PREFIX'
784 install_prefix = env['PREFIX']
786 subst_dict['%INSTALL_PREFIX%'] = install_prefix;
787 subst_dict['%FINAL_PREFIX%'] = final_prefix;
788 subst_dict['%PREFIX%'] = final_prefix;
790 if env['PREFIX'] == '/usr':
791 final_config_prefix = '/etc'
793 final_config_prefix = env['PREFIX'] + '/etc'
795 config_prefix = '$DESTDIR' + final_config_prefix
797 # SCons should really do this for us
799 conf = Configure (env)
801 have_cxx = conf.TryAction (Action (str(env['CXX']) + ' --version'))
803 print "This system has no functional C++ compiler. You cannot build Ardour from source without one."
806 print "Congratulations, you have a functioning C++ compiler."
811 # Compiler flags and other system-dependent stuff
815 debug_flags = [ '-g' ]
817 # guess at the platform, used to define compiler flags
819 config_guess = os.popen("tools/config.guess").read()[:-1]
825 config = config_guess.split ("-")
827 print "system triple: " + config_guess
830 if env['DIST_TARGET'] == 'auto':
831 if config[config_arch] == 'apple':
832 # The [.] matches to the dot after the major version, "." would match any character
833 if re.search ("darwin[0-7][.]", config[config_kernel]) != None:
834 env['DIST_TARGET'] = 'panther'
836 env['DIST_TARGET'] = 'tiger'
838 if re.search ("x86_64", config[config_cpu]) != None:
839 env['DIST_TARGET'] = 'x86_64'
840 elif re.search("i[0-5]86", config[config_cpu]) != None:
841 env['DIST_TARGET'] = 'i386'
842 elif re.search("powerpc", config[config_cpu]) != None:
843 env['DIST_TARGET'] = 'powerpc'
845 env['DIST_TARGET'] = 'i686'
846 print "\n*******************************"
847 print "detected DIST_TARGET = " + env['DIST_TARGET']
848 print "*******************************\n"
851 if config[config_cpu] == 'powerpc' and env['DIST_TARGET'] != 'none':
853 # Apple/PowerPC optimization options
855 # -mcpu=7450 does not reliably work with gcc 3.*
857 if env['DIST_TARGET'] == 'panther' or env['DIST_TARGET'] == 'tiger':
858 if config[config_arch] == 'apple':
859 opt_flags.extend ([ "-mcpu=7450", "-faltivec"])
861 opt_flags.extend ([ "-mcpu=7400", "-maltivec", "-mabi=altivec"])
863 opt_flags.extend([ "-mcpu=750", "-mmultiple" ])
864 opt_flags.extend (["-mhard-float", "-mpowerpc-gfxopt"])
866 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':
868 build_host_supports_sse = 0
870 debug_flags.append ("-DARCH_X86")
871 opt_flags.append ("-DARCH_X86")
873 if config[config_kernel] == 'linux' :
875 if env['DIST_TARGET'] != 'i386':
877 flag_line = os.popen ("cat /proc/cpuinfo | grep '^flags'").read()[:-1]
878 x86_flags = flag_line.split (": ")[1:][0].split (' ')
880 if "mmx" in x86_flags:
881 opt_flags.append ("-mmmx")
882 if "sse" in x86_flags:
883 build_host_supports_sse = 1
884 if "3dnow" in x86_flags:
885 opt_flags.append ("-m3dnow")
887 if config[config_cpu] == "i586":
888 opt_flags.append ("-march=i586")
889 elif config[config_cpu] == "i686":
890 opt_flags.append ("-march=i686")
892 if ((env['DIST_TARGET'] == 'i686') or (env['DIST_TARGET'] == 'x86_64')) and build_host_supports_sse:
893 opt_flags.extend (["-msse", "-mfpmath=sse"])
894 debug_flags.extend (["-msse", "-mfpmath=sse"])
895 # end of processor-specific section
897 # optimization section
898 if env['FPU_OPTIMIZATION']:
899 if env['DIST_TARGET'] == 'tiger':
900 opt_flags.append ("-DBUILD_VECLIB_OPTIMIZATIONS")
901 debug_flags.append ("-DBUILD_VECLIB_OPTIMIZATIONS")
902 libraries['core'].Append(LINKFLAGS= '-framework Accelerate')
903 elif env['DIST_TARGET'] == 'i686' or env['DIST_TARGET'] == 'x86_64':
904 opt_flags.append ("-DBUILD_SSE_OPTIMIZATIONS")
905 debug_flags.append ("-DBUILD_SSE_OPTIMIZATIONS")
906 if env['DIST_TARGET'] == 'x86_64':
907 opt_flags.append ("-DUSE_X86_64_ASM")
908 debug_flags.append ("-DUSE_X86_64_ASM")
909 if build_host_supports_sse != 1:
910 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)"
911 # end optimization section
914 # save off guessed arch element in an env
916 env.Append(CONFIG_ARCH=config[config_arch])
920 # ARCH="..." overrides all
923 if env['ARCH'] != '':
924 opt_flags = env['ARCH'].split()
927 # prepend boiler plate optimization flags
932 "-fomit-frame-pointer",
937 if env['DEBUG'] == 1:
938 env.Append(CCFLAGS=" ".join (debug_flags))
940 env.Append(CCFLAGS=" ".join (opt_flags))
946 env.Append(CCFLAGS="-Wall")
947 env.Append(CXXFLAGS="-Woverloaded-virtual")
949 if env['EXTRA_WARN']:
950 env.Append(CCFLAGS="-Wextra -pedantic")
951 env.Append(CXXFLAGS="-ansi")
954 env.Append(CCFLAGS="-DHAVE_LIBLO")
957 # everybody needs this
960 env.Merge ([ libraries['core'] ])
963 # fix scons nitpickiness on APPLE
966 if env['DIST_TARGET'] == 'panther' or env['DIST_TARGET'] == 'tiger':
967 env.Append(CCFLAGS="-I/opt/local/include", LINKFLAGS="-L/opt/local/lib")
973 conf = Configure (env)
975 nls_error = 'This system is not configured for internationalized applications. An english-only version will be built:'
976 print 'Checking for internationalization support ...'
977 have_gettext = conf.TryAction(Action('xgettext --version'))
978 if have_gettext[0] != 1:
979 nls_error += ' No xgettext command.'
982 print "Found xgettext"
984 have_msgmerge = conf.TryAction(Action('msgmerge --version'))
985 if have_msgmerge[0] != 1:
986 nls_error += ' No msgmerge command.'
989 print "Found msgmerge"
991 if not conf.CheckCHeader('libintl.h'):
992 nls_error += ' No libintl.h.'
998 print "International version will be built."
1002 env.Append(CCFLAGS="-DENABLE_NLS")
1004 Export('env install_prefix final_prefix config_prefix final_config_prefix libraries i18n version subst_dict')
1007 # the configuration file may be system dependent
1010 conf = env.Configure ()
1012 if conf.CheckCHeader('/System/Library/Frameworks/CoreAudio.framework/Versions/A/Headers/CoreAudio.h'):
1013 subst_dict['%JACK_INPUT%'] = "coreaudio:Built-in Audio:in"
1014 subst_dict['%JACK_OUTPUT%'] = "coreaudio:Built-in Audio:out"
1016 subst_dict['%JACK_INPUT%'] = "alsa_pcm:playback_"
1017 subst_dict['%JACK_OUTPUT%'] = "alsa_pcm:capture_"
1019 # posix_memalign available
1020 if not conf.CheckFunc('posix_memalign'):
1021 print 'Did not find posix_memalign(), using malloc'
1022 env.Append(CCFLAGS='-DNO_POSIX_MEMALIGN')
1027 rcbuild = env.SubstInFile ('ardour.rc','ardour.rc.in', SUBST_DICT = subst_dict)
1029 the_revision = env.Command ('frobnicatory_decoy', [], create_stored_revision)
1031 env.Alias('revision', the_revision)
1032 env.Alias('install', env.Install(os.path.join(config_prefix, 'ardour2'), 'ardour_system.rc'))
1033 env.Alias('install', env.Install(os.path.join(config_prefix, 'ardour2'), 'ardour.rc'))
1039 Precious (env['DISTTREE'])
1041 env.Distribute (env['DISTTREE'],
1042 [ 'SConstruct', 'svn_revision.h',
1043 'COPYING', 'PACKAGER_README', 'README',
1046 'tools/config.guess',
1047 'icons/icon/ardour_icon_mac_mask.png',
1048 'icons/icon/ardour_icon_mac.png',
1049 'icons/icon/ardour_icon_tango_16px_blue.png',
1050 'icons/icon/ardour_icon_tango_16px_red.png',
1051 'icons/icon/ardour_icon_tango_22px_blue.png',
1052 'icons/icon/ardour_icon_tango_22px_red.png',
1053 'icons/icon/ardour_icon_tango_32px_blue.png',
1054 'icons/icon/ardour_icon_tango_32px_red.png',
1055 'icons/icon/ardour_icon_tango_48px_blue.png',
1056 'icons/icon/ardour_icon_tango_48px_red.png'
1058 glob.glob ('DOCUMENTATION/AUTHORS*') +
1059 glob.glob ('DOCUMENTATION/CONTRIBUTORS*') +
1060 glob.glob ('DOCUMENTATION/TRANSLATORS*') +
1061 glob.glob ('DOCUMENTATION/BUILD*') +
1062 glob.glob ('DOCUMENTATION/FAQ*') +
1063 glob.glob ('DOCUMENTATION/README*')
1066 srcdist = env.Tarball(env['TARBALL'], [ env['DISTTREE'], the_revision ])
1067 env.Alias ('srctar', srcdist)
1070 # don't leave the distree around
1073 env.AddPreAction (env['DISTTREE'], Action ('rm -rf ' + str (File (env['DISTTREE']))))
1074 env.AddPostAction (srcdist, Action ('rm -rf ' + str (File (env['DISTTREE']))))
1080 for subdir in coredirs:
1081 SConscript (subdir + '/SConscript')
1083 for sublistdir in [ subdirs, gtk_subdirs, surface_subdirs ]:
1084 for subdir in sublistdir:
1085 SConscript (subdir + '/SConscript')
1088 env.Clean ('scrub', [ 'scache.conf', '.sconf_temp', '.sconsign.dblite', 'config.log'])