17 EnsureSConsVersion(0, 96)
19 version = '2.0beta6.1'
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 version information to ardour/gtk executable name inside the build directory', 0),
45 BoolOption('VST', 'Compile with support for VST', 0)
48 #----------------------------------------------------------------------
49 # a handy helper that provides a way to merge compile/link information
50 # from multiple different "environments"
51 #----------------------------------------------------------------------
53 class LibraryInfo(Environment):
54 def __init__(self,*args,**kw):
55 Environment.__init__ (self,*args,**kw)
57 def Merge (self,others):
59 self.Append (LIBS = other.get ('LIBS',[]))
60 self.Append (LIBPATH = other.get ('LIBPATH', []))
61 self.Append (CPPPATH = other.get('CPPPATH', []))
62 self.Append (LINKFLAGS = other.get('LINKFLAGS', []))
63 self.Replace(LIBPATH = list(Set(self.get('LIBPATH', []))))
64 self.Replace(CPPPATH = list(Set(self.get('CPPPATH',[]))))
65 #doing LINKFLAGS breaks -framework
66 #doing LIBS break link order dependency
68 def ENV_update(self, src_ENV):
69 for k in src_ENV.keys():
70 if k in self['ENV'].keys() and k in [ 'PATH', 'LD_LIBRARY_PATH',
72 self['ENV'][k]=SCons.Util.AppendPath(self['ENV'][k], src_ENV[k])
74 self['ENV'][k]=src_ENV[k]
76 env = LibraryInfo (options = opts,
79 TARBALL='ardour-' + version + '.tar.bz2',
81 DISTTREE = '#ardour-' + version,
82 DISTCHECKDIR = '#ardour-' + version + '/check'
85 env.ENV_update(os.environ)
87 #----------------------------------------------------------------------
89 #----------------------------------------------------------------------
91 # Handy subst-in-file builder
94 def do_subst_in_file(targetfile, sourcefile, dict):
95 """Replace all instances of the keys of dict with their values.
96 For example, if dict is {'%VERSION%': '1.2345', '%BASE%': 'MyProg'},
97 then all instances of %VERSION% in the file will be replaced with 1.2345 etc.
100 f = open(sourcefile, 'rb')
104 raise SCons.Errors.UserError, "Can't read source file %s"%sourcefile
105 for (k,v) in dict.items():
106 contents = re.sub(k, v, contents)
108 f = open(targetfile, 'wb')
112 raise SCons.Errors.UserError, "Can't write target file %s"%targetfile
115 def subst_in_file(target, source, env):
116 if not env.has_key('SUBST_DICT'):
117 raise SCons.Errors.UserError, "SubstInFile requires SUBST_DICT to be set."
118 d = dict(env['SUBST_DICT']) # copy it
119 for (k,v) in d.items():
121 d[k] = env.subst(v())
122 elif SCons.Util.is_String(v):
125 raise SCons.Errors.UserError, "SubstInFile: key %s: %s must be a string or callable"%(k, repr(v))
126 for (t,s) in zip(target, source):
127 return do_subst_in_file(str(t), str(s), d)
129 def subst_in_file_string(target, source, env):
130 """This is what gets printed on the console."""
131 return '\n'.join(['Substituting vars from %s into %s'%(str(s), str(t))
132 for (t,s) in zip(target, source)])
134 def subst_emitter(target, source, env):
135 """Add dependency from substituted SUBST_DICT to target.
136 Returns original target, source tuple unchanged.
138 d = env['SUBST_DICT'].copy() # copy it
139 for (k,v) in d.items():
141 d[k] = env.subst(v())
142 elif SCons.Util.is_String(v):
144 Depends(target, SCons.Node.Python.Value(d))
145 # Depends(target, source) # this doesn't help the install-sapphire-linux.sh problem
146 return target, source
148 subst_action = Action (subst_in_file, subst_in_file_string)
149 env['BUILDERS']['SubstInFile'] = Builder(action=subst_action, emitter=subst_emitter)
152 # internationalization
155 # po_builder: builder function to copy po files to the parent directory while updating them
157 # first source: .po file
158 # second source: .pot file
161 def po_builder(target,source,env):
162 os.spawnvp (os.P_WAIT, 'cp', ['cp', str(source[0]), str(target[0])])
168 print 'Updating ' + str(target[0])
169 return os.spawnvp (os.P_WAIT, 'msgmerge', args)
171 po_bld = Builder (action = po_builder)
172 env.Append(BUILDERS = {'PoBuild' : po_bld})
174 # mo_builder: builder function for (binary) message catalogs (.mo)
176 # first source: .po file
179 def mo_builder(target,source,env):
183 target[0].get_path(),
186 return os.spawnvp (os.P_WAIT, 'msgfmt', args)
188 mo_bld = Builder (action = mo_builder)
189 env.Append(BUILDERS = {'MoBuild' : mo_bld})
191 # pot_builder: builder function for message templates (.pot)
193 # source: list of C/C++ etc. files to extract messages from
196 def pot_builder(target,source,env):
201 '-o', target[0].get_path(),
202 "--default-domain=" + env['PACKAGE'],
203 '--copyright-holder="Paul Davis"' ]
204 args += [ src.get_path() for src in source ]
206 return os.spawnvp (os.P_WAIT, 'xgettext', args)
208 pot_bld = Builder (action = pot_builder)
209 env.Append(BUILDERS = {'PotBuild' : pot_bld})
212 # utility function, not a builder
215 def i18n (buildenv, sources, installenv):
216 domain = buildenv['PACKAGE']
217 potfile = buildenv['POTFILE']
219 installenv.Alias ('potupdate', buildenv.PotBuild (potfile, sources))
221 p_oze = [ os.path.basename (po) for po in glob.glob ('po/*.po') ]
222 languages = [ po.replace ('.po', '') for po in p_oze ]
224 for po_file in p_oze:
225 buildenv.PoBuild(po_file, ['po/'+po_file, potfile])
226 mo_file = po_file.replace (".po", ".mo")
227 installenv.Alias ('install', buildenv.MoBuild (mo_file, po_file))
229 for lang in languages:
230 modir = (os.path.join (install_prefix, 'share/locale/' + lang + '/LC_MESSAGES/'))
231 moname = domain + '.mo'
232 installenv.Alias('install', installenv.InstallAs (os.path.join (modir, moname), lang + '.mo'))
235 # A generic builder for version.cc files
237 # note: requires that DOMAIN, MAJOR, MINOR, MICRO are set in the construction environment
238 # note: assumes one source files, the header that declares the version variables
241 def version_builder (target, source, env):
243 cmd += source[0].get_path()
244 cmd += " | awk '/^Revision:/ { print $2}'"
246 rev = commands.getoutput (cmd)
248 text = "const char* " + env['DOMAIN'] + "_revision = \"" + rev + "\";\n"
249 text += "int " + env['DOMAIN'] + "_major_version = " + str (env['MAJOR']) + ";\n"
250 text += "int " + env['DOMAIN'] + "_minor_version = " + str (env['MINOR']) + ";\n"
251 text += "int " + env['DOMAIN'] + "_micro_version = " + str (env['MICRO']) + ";\n"
254 o = file (target[0].get_path(), 'w')
258 print "Could not open", target[0].get_path(), " for writing\n"
261 text = "#ifndef __" + env['DOMAIN'] + "_version_h__\n"
262 text += "#define __" + env['DOMAIN'] + "_version_h__\n"
263 text += "extern const char* " + env['DOMAIN'] + "_revision;\n"
264 text += "extern int " + env['DOMAIN'] + "_major_version;\n"
265 text += "extern int " + env['DOMAIN'] + "_minor_version;\n"
266 text += "extern int " + env['DOMAIN'] + "_micro_version;\n"
267 text += "#endif /* __" + env['DOMAIN'] + "_version_h__ */\n"
270 o = file (target[1].get_path(), 'w')
274 print "Could not open", target[1].get_path(), " for writing\n"
279 version_bld = Builder (action = version_builder)
280 env.Append (BUILDERS = {'VersionBuild' : version_bld})
283 # a builder that makes a hard link from the 'source' executable to a name with
284 # a "build ID" based on the most recent CVS activity that might be reasonably
285 # related to version activity. this relies on the idea that the SConscript
286 # file that builds the executable is updated with new version info and committed
287 # to the source code repository whenever things change.
290 def versioned_builder(target,source,env):
291 # build ID is composed of a representation of the date of the last CVS transaction
292 # for this (SConscript) file
295 o = file (source[0].get_dir().get_path() + '/CVS/Entries', "r")
297 print "Could not CVS/Entries for reading"
301 lines = o.readlines()
303 if line[0:12] == '/SConscript/':
304 parts = line.split ("/")
310 print "No SConscript CVS update info found - versioned executable cannot be built"
313 tag = time.strftime ('%Y%M%d%H%m', time.strptime (last_date))
314 print "The current build ID is " + tag
316 tagged_executable = source[0].get_path() + '-' + tag
318 if os.path.exists (tagged_executable):
319 print "Replacing existing executable with the same build tag."
320 os.unlink (tagged_executable)
322 return os.link (source[0].get_path(), tagged_executable)
324 verbuild = Builder (action = versioned_builder)
325 env.Append (BUILDERS = {'VersionedExecutable' : verbuild})
328 # source tar file builder
331 def distcopy (target, source, env):
332 treedir = str (target[0])
336 except OSError, (errnum, strerror):
337 if errnum != errno.EEXIST:
338 print 'mkdir ', treedir, ':', strerror
342 # we don't know what characters might be in the file names
343 # so quote them all before passing them to the shell
345 all_files = ([ str(s) for s in source ])
346 cmd += " ".join ([ "'%s'" % quoted for quoted in all_files])
347 cmd += ' | (cd ' + treedir + ' && tar xf -)'
351 def tarballer (target, source, env):
352 cmd = 'tar -jcf ' + str (target[0]) + ' ' + str(source[0]) + " --exclude '*~'"
353 print 'running ', cmd, ' ... '
357 dist_bld = Builder (action = distcopy,
358 target_factory = SCons.Node.FS.default_fs.Entry,
359 source_factory = SCons.Node.FS.default_fs.Entry,
362 tarball_bld = Builder (action = tarballer,
363 target_factory = SCons.Node.FS.default_fs.Entry,
364 source_factory = SCons.Node.FS.default_fs.Entry)
366 env.Append (BUILDERS = {'Distribute' : dist_bld})
367 env.Append (BUILDERS = {'Tarball' : tarball_bld})
370 # Make sure they know what they are doing
374 sys.stdout.write ("Are you building Ardour for personal use (rather than distributiont to others)? [no]: ")
375 answer = sys.stdin.readline ()
376 answer = answer.rstrip().strip()
377 if answer != "yes" and answer != "y":
378 print 'You cannot build Ardour with VST support for distribution to others.\nIt is a violation of several different licenses. Build with VST=false.'
381 print "OK, VST support will be enabled"
384 # ----------------------------------------------------------------------
385 # Construction environment setup
386 # ----------------------------------------------------------------------
390 libraries['core'] = LibraryInfo (CCFLAGS = '-Ilibs')
392 #libraries['sndfile'] = LibraryInfo()
393 #libraries['sndfile'].ParseConfig('pkg-config --cflags --libs sndfile')
395 libraries['lrdf'] = LibraryInfo()
396 libraries['lrdf'].ParseConfig('pkg-config --cflags --libs lrdf')
398 libraries['raptor'] = LibraryInfo()
399 libraries['raptor'].ParseConfig('pkg-config --cflags --libs raptor')
401 libraries['samplerate'] = LibraryInfo()
402 libraries['samplerate'].ParseConfig('pkg-config --cflags --libs samplerate')
404 if env['FFT_ANALYSIS']:
405 libraries['fftw3f'] = LibraryInfo()
406 libraries['fftw3f'].ParseConfig('pkg-config --cflags --libs fftw3f')
408 libraries['jack'] = LibraryInfo()
409 libraries['jack'].ParseConfig('pkg-config --cflags --libs jack')
411 libraries['xml'] = LibraryInfo()
412 libraries['xml'].ParseConfig('pkg-config --cflags --libs libxml-2.0')
414 libraries['xslt'] = LibraryInfo()
415 libraries['xslt'].ParseConfig('pkg-config --cflags --libs libxslt')
417 libraries['glib2'] = LibraryInfo()
418 libraries['glib2'].ParseConfig ('pkg-config --cflags --libs glib-2.0')
419 libraries['glib2'].ParseConfig ('pkg-config --cflags --libs gobject-2.0')
420 libraries['glib2'].ParseConfig ('pkg-config --cflags --libs gmodule-2.0')
421 libraries['glib2'].ParseConfig ('pkg-config --cflags --libs gthread-2.0')
423 libraries['gtk2'] = LibraryInfo()
424 libraries['gtk2'].ParseConfig ('pkg-config --cflags --libs gtk+-2.0')
426 libraries['pango'] = LibraryInfo()
427 libraries['pango'].ParseConfig ('pkg-config --cflags --libs pango')
429 libraries['libgnomecanvas2'] = LibraryInfo()
430 libraries['libgnomecanvas2'].ParseConfig ('pkg-config --cflags --libs libgnomecanvas-2.0')
432 #libraries['flowcanvas'] = LibraryInfo(LIBS='flowcanvas', LIBPATH='#/libs/flowcanvas', CPPPATH='#libs/flowcanvas')
434 # The Ardour Control Protocol Library
436 libraries['ardour_cp'] = LibraryInfo (LIBS='ardour_cp', LIBPATH='#libs/surfaces/control_protocol',
437 CPPPATH='#libs/surfaces/control_protocol')
439 # The Ardour backend/engine
441 libraries['ardour'] = LibraryInfo (LIBS='ardour', LIBPATH='#libs/ardour', CPPPATH='#libs/ardour')
442 libraries['midi++2'] = LibraryInfo (LIBS='midi++', LIBPATH='#libs/midi++2', CPPPATH='#libs/midi++2')
443 libraries['pbd'] = LibraryInfo (LIBS='pbd', LIBPATH='#libs/pbd', CPPPATH='#libs/pbd')
444 libraries['gtkmm2ext'] = LibraryInfo (LIBS='gtkmm2ext', LIBPATH='#libs/gtkmm2ext', CPPPATH='#libs/gtkmm2ext')
449 libraries['usb'] = LibraryInfo ()
451 conf = Configure (libraries['usb'])
452 if conf.CheckLib ('usb', 'usb_interrupt_write'):
457 libraries['usb'] = conf.Finish ()
462 libraries['flac'] = LibraryInfo ()
464 conf = Configure (libraries['flac'])
465 conf.CheckLib ('FLAC', 'FLAC__stream_decoder_new', language='CXX')
466 libraries['flac'] = conf.Finish ()
468 # or if that fails...
469 #libraries['flac'] = LibraryInfo (LIBS='FLAC')
471 # boost (we don't link against boost, just use some header files)
473 libraries['boost'] = LibraryInfo ()
474 conf = Configure (libraries['boost'])
475 if conf.CheckHeader ('boost/shared_ptr.hpp', language='CXX') == 0:
476 print "Boost header files do not appear to be installed."
479 libraries['boost'] = conf.Finish ()
485 libraries['lo'] = LibraryInfo ()
487 conf = Configure (libraries['lo'])
488 if conf.CheckLib ('lo', 'lo_server_new') == False:
489 print "liblo does not appear to be installed."
492 libraries['lo'] = conf.Finish ()
497 libraries['dmalloc'] = LibraryInfo ()
500 # look for the threaded version
503 conf = Configure (libraries['dmalloc'])
504 if conf.CheckLib ('dmallocth', 'dmalloc_shutdown'):
505 have_libdmalloc = True
507 have_libdmalloc = False
509 libraries['dmalloc'] = conf.Finish ()
512 # Audio/MIDI library (needed for MIDI, since audio is all handled via JACK)
515 conf = Configure(env)
517 if conf.CheckCHeader('alsa/asoundlib.h'):
518 libraries['sysmidi'] = LibraryInfo (LIBS='asound')
519 env['SYSMIDI'] = 'ALSA Sequencer'
520 subst_dict['%MIDITAG%'] = "seq"
521 subst_dict['%MIDITYPE%'] = "alsa/sequencer"
522 elif conf.CheckCHeader('/System/Library/Frameworks/CoreMIDI.framework/Headers/CoreMIDI.h'):
523 # this line is needed because scons can't handle -framework in ParseConfig() yet.
524 libraries['sysmidi'] = LibraryInfo (LINKFLAGS= '-framework CoreMIDI -framework CoreFoundation -framework CoreAudio -framework CoreServices -framework AudioUnit -framework AudioToolbox -bind_at_load')
525 env['SYSMIDI'] = 'CoreMIDI'
526 subst_dict['%MIDITAG%'] = "ardour"
527 subst_dict['%MIDITYPE%'] = "coremidi"
529 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."
536 libraries['sigc2'] = LibraryInfo()
537 libraries['sigc2'].ParseConfig('pkg-config --cflags --libs sigc++-2.0')
538 libraries['glibmm2'] = LibraryInfo()
539 libraries['glibmm2'].ParseConfig('pkg-config --cflags --libs glibmm-2.4')
540 libraries['gdkmm2'] = LibraryInfo()
541 libraries['gdkmm2'].ParseConfig ('pkg-config --cflags --libs gdkmm-2.4')
542 libraries['gtkmm2'] = LibraryInfo()
543 libraries['gtkmm2'].ParseConfig ('pkg-config --cflags --libs gtkmm-2.4')
544 libraries['atkmm'] = LibraryInfo()
545 libraries['atkmm'].ParseConfig ('pkg-config --cflags --libs atkmm-1.6')
546 libraries['pangomm'] = LibraryInfo()
547 libraries['pangomm'].ParseConfig ('pkg-config --cflags --libs pangomm-1.4')
548 libraries['libgnomecanvasmm'] = LibraryInfo()
549 libraries['libgnomecanvasmm'].ParseConfig ('pkg-config --cflags --libs libgnomecanvasmm-2.6')
552 # cannot use system one for the time being
555 libraries['sndfile'] = LibraryInfo(LIBS='libsndfile',
556 LIBPATH='#libs/libsndfile',
557 CPPPATH=['#libs/libsndfile', '#libs/libsndfile/src'])
559 # libraries['libglademm'] = LibraryInfo()
560 # libraries['libglademm'].ParseConfig ('pkg-config --cflags --libs libglademm-2.4')
562 # libraries['flowcanvas'] = LibraryInfo(LIBS='flowcanvas', LIBPATH='#/libs/flowcanvas', CPPPATH='#libs/flowcanvas')
563 libraries['soundtouch'] = LibraryInfo()
564 libraries['soundtouch'].ParseConfig ('pkg-config --cflags --libs soundtouch-1.0')
566 libraries['appleutility'] = LibraryInfo(LIBS='libappleutility',
567 LIBPATH='#libs/appleutility',
568 CPPPATH='#libs/appleutility')
579 # these are unconditionally included but have
580 # tests internally to avoid compilation etc
584 # this is unconditionally included but has
585 # tests internally to avoid compilation etc
586 # if COREAUDIO is not set
597 libraries['sigc2'] = LibraryInfo(LIBS='sigc++2',
598 LIBPATH='#libs/sigc++2',
599 CPPPATH='#libs/sigc++2')
600 libraries['glibmm2'] = LibraryInfo(LIBS='glibmm2',
601 LIBPATH='#libs/glibmm2',
602 CPPPATH='#libs/glibmm2')
603 libraries['pangomm'] = LibraryInfo(LIBS='pangomm',
604 LIBPATH='#libs/gtkmm2/pango',
605 CPPPATH='#libs/gtkmm2/pango')
606 libraries['atkmm'] = LibraryInfo(LIBS='atkmm',
607 LIBPATH='#libs/gtkmm2/atk',
608 CPPPATH='#libs/gtkmm2/atk')
609 libraries['gdkmm2'] = LibraryInfo(LIBS='gdkmm2',
610 LIBPATH='#libs/gtkmm2/gdk',
611 CPPPATH='#libs/gtkmm2/gdk')
612 libraries['gtkmm2'] = LibraryInfo(LIBS='gtkmm2',
613 LIBPATH="#libs/gtkmm2/gtk",
614 CPPPATH='#libs/gtkmm2/gtk/')
615 libraries['libgnomecanvasmm'] = LibraryInfo(LIBS='libgnomecanvasmm',
616 LIBPATH='#libs/libgnomecanvasmm',
617 CPPPATH='#libs/libgnomecanvasmm')
619 libraries['soundtouch'] = LibraryInfo(LIBS='soundtouch',
620 LIBPATH='#libs/soundtouch',
621 CPPPATH=['#libs', '#libs/soundtouch'])
622 libraries['sndfile'] = LibraryInfo(LIBS='libsndfile',
623 LIBPATH='#libs/libsndfile',
624 CPPPATH=['#libs/libsndfile', '#libs/libsndfile/src'])
625 # libraries['libglademm'] = LibraryInfo(LIBS='libglademm',
626 # LIBPATH='#libs/libglademm',
627 # CPPPATH='#libs/libglademm')
628 libraries['appleutility'] = LibraryInfo(LIBS='libappleutility',
629 LIBPATH='#libs/appleutility',
630 CPPPATH='#libs/appleutility')
643 # these are unconditionally included but have
644 # tests internally to avoid compilation etc
648 # this is unconditionally included but has
649 # tests internally to avoid compilation etc
650 # if COREAUDIO is not set
660 'libs/libgnomecanvasmm',
667 # always build the LGPL control protocol lib, since we link against it ourselves
668 # ditto for generic MIDI
671 surface_subdirs = [ 'libs/surfaces/control_protocol', 'libs/surfaces/generic_midi' ]
675 surface_subdirs += [ 'libs/surfaces/tranzport' ]
676 if os.access ('libs/surfaces/sony9pin', os.F_OK):
677 surface_subdirs += [ 'libs/surfaces/sony9pin' ]
679 opts.Save('scache.conf', env)
680 Help(opts.GenerateHelpText(env))
682 if os.environ.has_key('PATH'):
683 env.Append(PATH = os.environ['PATH'])
685 if os.environ.has_key('PKG_CONFIG_PATH'):
686 env.Append(PKG_CONFIG_PATH = os.environ['PKG_CONFIG_PATH'])
688 if os.environ.has_key('CC'):
689 env['CC'] = os.environ['CC']
691 if os.environ.has_key('CXX'):
692 env['CXX'] = os.environ['CXX']
694 if os.environ.has_key('DISTCC_HOSTS'):
695 env['ENV']['DISTCC_HOSTS'] = os.environ['DISTCC_HOSTS']
696 env['ENV']['HOME'] = os.environ['HOME']
698 final_prefix = '$PREFIX'
701 install_prefix = '$DESTDIR/$PREFIX'
703 install_prefix = env['PREFIX']
705 subst_dict['%INSTALL_PREFIX%'] = install_prefix;
706 subst_dict['%FINAL_PREFIX%'] = final_prefix;
707 subst_dict['%PREFIX%'] = final_prefix;
709 if env['PREFIX'] == '/usr':
710 final_config_prefix = '/etc'
712 final_config_prefix = env['PREFIX'] + '/etc'
714 config_prefix = '$DESTDIR' + final_config_prefix
716 # SCons should really do this for us
718 conf = Configure (env)
720 have_cxx = conf.TryAction (Action (env['CXX'] + ' --version'))
722 print "This system has no functional C++ compiler. You cannot build Ardour from source without one."
725 print "Congratulations, you have a functioning C++ compiler."
730 # Compiler flags and other system-dependent stuff
734 debug_flags = [ '-g' ]
736 # guess at the platform, used to define compiler flags
738 config_guess = os.popen("tools/config.guess").read()[:-1]
744 config = config_guess.split ("-")
746 print "system triple: " + config_guess
749 if env['DIST_TARGET'] == 'auto':
750 if config[config_arch] == 'apple':
751 # The [.] matches to the dot after the major version, "." would match any character
752 if re.search ("darwin[0-7][.]", config[config_kernel]) != None:
753 env['DIST_TARGET'] = 'panther'
755 env['DIST_TARGET'] = 'tiger'
757 if re.search ("x86_64", config[config_cpu]) != None:
758 env['DIST_TARGET'] = 'x86_64'
759 elif re.search("i[0-5]86", config[config_cpu]) != None:
760 env['DIST_TARGET'] = 'i386'
761 elif re.search("powerpc", config[config_cpu]) != None:
762 env['DIST_TARGET'] = 'powerpc'
764 env['DIST_TARGET'] = 'i686'
765 print "\n*******************************"
766 print "detected DIST_TARGET = " + env['DIST_TARGET']
767 print "*******************************\n"
770 if config[config_cpu] == 'powerpc' and env['DIST_TARGET'] != 'none':
772 # Apple/PowerPC optimization options
774 # -mcpu=7450 does not reliably work with gcc 3.*
776 if env['DIST_TARGET'] == 'panther' or env['DIST_TARGET'] == 'tiger':
777 if config[config_arch] == 'apple':
778 opt_flags.extend ([ "-mcpu=7450", "-faltivec"])
780 opt_flags.extend ([ "-mcpu=7400", "-maltivec", "-mabi=altivec"])
782 opt_flags.extend([ "-mcpu=750", "-mmultiple" ])
783 opt_flags.extend (["-mhard-float", "-mpowerpc-gfxopt"])
785 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':
787 build_host_supports_sse = 0
789 debug_flags.append ("-DARCH_X86")
790 opt_flags.append ("-DARCH_X86")
792 if config[config_kernel] == 'linux' :
794 if env['DIST_TARGET'] != 'i386':
796 flag_line = os.popen ("cat /proc/cpuinfo | grep '^flags'").read()[:-1]
797 x86_flags = flag_line.split (": ")[1:][0].split (' ')
799 if "mmx" in x86_flags:
800 opt_flags.append ("-mmmx")
801 if "sse" in x86_flags:
802 build_host_supports_sse = 1
803 if "3dnow" in x86_flags:
804 opt_flags.append ("-m3dnow")
806 if config[config_cpu] == "i586":
807 opt_flags.append ("-march=i586")
808 elif config[config_cpu] == "i686":
809 opt_flags.append ("-march=i686")
811 if ((env['DIST_TARGET'] == 'i686') or (env['DIST_TARGET'] == 'x86_64')) and build_host_supports_sse:
812 opt_flags.extend (["-msse", "-mfpmath=sse"])
813 debug_flags.extend (["-msse", "-mfpmath=sse"])
814 # end of processor-specific section
816 # optimization section
817 if env['FPU_OPTIMIZATION']:
818 if env['DIST_TARGET'] == 'tiger':
819 opt_flags.append ("-DBUILD_VECLIB_OPTIMIZATIONS")
820 debug_flags.append ("-DBUILD_VECLIB_OPTIMIZATIONS")
821 libraries['core'].Append(LINKFLAGS= '-framework Accelerate')
822 elif env['DIST_TARGET'] == 'i686' or env['DIST_TARGET'] == 'x86_64':
823 opt_flags.append ("-DBUILD_SSE_OPTIMIZATIONS")
824 debug_flags.append ("-DBUILD_SSE_OPTIMIZATIONS")
825 if env['DIST_TARGET'] == 'x86_64':
826 opt_flags.append ("-DUSE_X86_64_ASM")
827 debug_flags.append ("-DUSE_X86_64_ASM")
828 if build_host_supports_sse != 1:
829 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)"
830 # end optimization section
833 # save off guessed arch element in an env
835 env.Append(CONFIG_ARCH=config[config_arch])
839 # ARCH="..." overrides all
842 if env['ARCH'] != '':
843 opt_flags = env['ARCH'].split()
846 # prepend boiler plate optimization flags
851 "-fomit-frame-pointer",
856 if env['DEBUG'] == 1:
857 env.Append(CCFLAGS=" ".join (debug_flags))
859 env.Append(CCFLAGS=" ".join (opt_flags))
865 env.Append(CCFLAGS="-Wall")
866 env.Append(CXXFLAGS="-Woverloaded-virtual")
868 if env['EXTRA_WARN']:
869 env.Append(CCFLAGS="-Wextra -pedantic")
870 env.Append(CXXFLAGS="-ansi")
873 env.Append(CCFLAGS="-DHAVE_LIBLO")
876 # everybody needs this
879 env.Merge ([ libraries['core'] ])
882 # fix scons nitpickiness on APPLE
885 if env['DIST_TARGET'] == 'panther' or env['DIST_TARGET'] == 'tiger':
886 env.Append(CCFLAGS="-I/opt/local/include", LINKFLAGS="-L/opt/local/lib")
892 conf = Configure (env)
894 nls_error = 'This system is not configured for internationalized applications. An english-only version will be built:'
895 print 'Checking for internationalization support ...'
896 have_gettext = conf.TryAction(Action('xgettext --version'))
897 if have_gettext[0] != 1:
898 nls_error += ' No xgettext command.'
901 print "Found xgettext"
903 have_msgmerge = conf.TryAction(Action('msgmerge --version'))
904 if have_msgmerge[0] != 1:
905 nls_error += ' No msgmerge command.'
908 print "Found msgmerge"
910 if not conf.CheckCHeader('libintl.h'):
911 nls_error += ' No libintl.h.'
917 print "International version will be built."
921 env.Append(CCFLAGS="-DENABLE_NLS")
923 Export('env install_prefix final_prefix config_prefix final_config_prefix libraries i18n version subst_dict')
926 # the configuration file may be system dependent
929 conf = env.Configure ()
931 if conf.CheckCHeader('/System/Library/Frameworks/CoreAudio.framework/Versions/A/Headers/CoreAudio.h'):
932 subst_dict['%JACK_INPUT%'] = "coreaudio:Built-in Audio:in"
933 subst_dict['%JACK_OUTPUT%'] = "coreaudio:Built-in Audio:out"
935 subst_dict['%JACK_INPUT%'] = "alsa_pcm:playback_"
936 subst_dict['%JACK_OUTPUT%'] = "alsa_pcm:capture_"
938 # posix_memalign available
939 if not conf.CheckFunc('posix_memalign'):
940 print 'Did not find posix_memalign(), using malloc'
941 env.Append(CCFLAGS='-DNO_POSIX_MEMALIGN')
946 rcbuild = env.SubstInFile ('ardour.rc','ardour.rc.in', SUBST_DICT = subst_dict)
948 env.Alias('install', env.Install(os.path.join(config_prefix, 'ardour2'), 'ardour_system.rc'))
949 env.Alias('install', env.Install(os.path.join(config_prefix, 'ardour2'), 'ardour.rc'))
955 Precious (env['DISTTREE'])
958 # note the special "cleanfirst" source name. this triggers removal
959 # of the existing disttree
962 env.Distribute (env['DISTTREE'],
964 'COPYING', 'PACKAGER_README', 'README',
967 'tools/config.guess',
968 'icons/icon/ardour_icon_mac_mask.png',
969 'icons/icon/ardour_icon_mac.png',
970 'icons/icon/ardour_icon_tango_16px_blue.png',
971 'icons/icon/ardour_icon_tango_16px_red.png',
972 'icons/icon/ardour_icon_tango_22px_blue.png',
973 'icons/icon/ardour_icon_tango_22px_red.png',
974 'icons/icon/ardour_icon_tango_32px_blue.png',
975 'icons/icon/ardour_icon_tango_32px_red.png',
976 'icons/icon/ardour_icon_tango_48px_blue.png',
977 'icons/icon/ardour_icon_tango_48px_red.png'
979 glob.glob ('DOCUMENTATION/AUTHORS*') +
980 glob.glob ('DOCUMENTATION/CONTRIBUTORS*') +
981 glob.glob ('DOCUMENTATION/TRANSLATORS*') +
982 glob.glob ('DOCUMENTATION/BUILD*') +
983 glob.glob ('DOCUMENTATION/FAQ*') +
984 glob.glob ('DOCUMENTATION/README*')
987 srcdist = env.Tarball(env['TARBALL'], env['DISTTREE'])
988 env.Alias ('srctar', srcdist)
991 # don't leave the distree around
993 env.AddPreAction (env['DISTTREE'], Action ('rm -rf ' + str (File (env['DISTTREE']))))
994 env.AddPostAction (srcdist, Action ('rm -rf ' + str (File (env['DISTTREE']))))
1000 for subdir in coredirs:
1001 SConscript (subdir + '/SConscript')
1003 for sublistdir in [ subdirs, gtk_subdirs, surface_subdirs ]:
1004 for subdir in sublistdir:
1005 SConscript (subdir + '/SConscript')
1008 env.Clean ('scrub', [ 'scache.conf', '.sconf_temp', '.sconsign.dblite', 'config.log'])