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)
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 w, r = os.popen2( "svn info | awk '/^Revision:/ { print $2}'")
293 last_revision = r.readline().strip()
296 if last_revision == "":
297 print "No SVN info found - versioned executable cannot be built"
300 print "The current build ID is " + last_revision
302 tagged_executable = source[0].get_path() + '-' + last_revision
304 if os.path.exists (tagged_executable):
305 print "Replacing existing executable with the same build tag."
306 os.unlink (tagged_executable)
308 return os.link (source[0].get_path(), tagged_executable)
310 verbuild = Builder (action = versioned_builder)
311 env.Append (BUILDERS = {'VersionedExecutable' : verbuild})
314 # source tar file builder
317 def distcopy (target, source, env):
318 treedir = str (target[0])
322 except OSError, (errnum, strerror):
323 if errnum != errno.EEXIST:
324 print 'mkdir ', treedir, ':', strerror
328 # we don't know what characters might be in the file names
329 # so quote them all before passing them to the shell
331 all_files = ([ str(s) for s in source ])
332 cmd += " ".join ([ "'%s'" % quoted for quoted in all_files])
333 cmd += ' | (cd ' + treedir + ' && tar xf -)'
337 def tarballer (target, source, env):
338 cmd = 'tar -jcf ' + str (target[0]) + ' ' + str(source[0]) + " --exclude '*~'"
339 print 'running ', cmd, ' ... '
343 dist_bld = Builder (action = distcopy,
344 target_factory = SCons.Node.FS.default_fs.Entry,
345 source_factory = SCons.Node.FS.default_fs.Entry,
348 tarball_bld = Builder (action = tarballer,
349 target_factory = SCons.Node.FS.default_fs.Entry,
350 source_factory = SCons.Node.FS.default_fs.Entry)
352 env.Append (BUILDERS = {'Distribute' : dist_bld})
353 env.Append (BUILDERS = {'Tarball' : tarball_bld})
356 # Make sure they know what they are doing
360 sys.stdout.write ("Are you building Ardour for personal use (rather than distributiont to others)? [no]: ")
361 answer = sys.stdin.readline ()
362 answer = answer.rstrip().strip()
363 if answer != "yes" and answer != "y":
364 print 'You cannot build Ardour with VST support for distribution to others.\nIt is a violation of several different licenses. Build with VST=false.'
367 print "OK, VST support will be enabled"
370 # ----------------------------------------------------------------------
371 # Construction environment setup
372 # ----------------------------------------------------------------------
376 libraries['core'] = LibraryInfo (CCFLAGS = '-Ilibs')
378 #libraries['sndfile'] = LibraryInfo()
379 #libraries['sndfile'].ParseConfig('pkg-config --cflags --libs sndfile')
381 libraries['lrdf'] = LibraryInfo()
382 libraries['lrdf'].ParseConfig('pkg-config --cflags --libs lrdf')
384 libraries['raptor'] = LibraryInfo()
385 libraries['raptor'].ParseConfig('pkg-config --cflags --libs raptor')
387 libraries['samplerate'] = LibraryInfo()
388 libraries['samplerate'].ParseConfig('pkg-config --cflags --libs samplerate')
390 if env['FFT_ANALYSIS']:
391 libraries['fftw3f'] = LibraryInfo()
392 libraries['fftw3f'].ParseConfig('pkg-config --cflags --libs fftw3f')
394 libraries['jack'] = LibraryInfo()
395 libraries['jack'].ParseConfig('pkg-config --cflags --libs jack')
397 libraries['xml'] = LibraryInfo()
398 libraries['xml'].ParseConfig('pkg-config --cflags --libs libxml-2.0')
400 libraries['xslt'] = LibraryInfo()
401 libraries['xslt'].ParseConfig('pkg-config --cflags --libs libxslt')
403 libraries['glib2'] = LibraryInfo()
404 libraries['glib2'].ParseConfig ('pkg-config --cflags --libs glib-2.0')
405 libraries['glib2'].ParseConfig ('pkg-config --cflags --libs gobject-2.0')
406 libraries['glib2'].ParseConfig ('pkg-config --cflags --libs gmodule-2.0')
407 libraries['glib2'].ParseConfig ('pkg-config --cflags --libs gthread-2.0')
409 libraries['gtk2'] = LibraryInfo()
410 libraries['gtk2'].ParseConfig ('pkg-config --cflags --libs gtk+-2.0')
412 libraries['pango'] = LibraryInfo()
413 libraries['pango'].ParseConfig ('pkg-config --cflags --libs pango')
415 libraries['libgnomecanvas2'] = LibraryInfo()
416 libraries['libgnomecanvas2'].ParseConfig ('pkg-config --cflags --libs libgnomecanvas-2.0')
418 #libraries['flowcanvas'] = LibraryInfo(LIBS='flowcanvas', LIBPATH='#/libs/flowcanvas', CPPPATH='#libs/flowcanvas')
420 # The Ardour Control Protocol Library
422 libraries['ardour_cp'] = LibraryInfo (LIBS='ardour_cp', LIBPATH='#libs/surfaces/control_protocol',
423 CPPPATH='#libs/surfaces/control_protocol')
425 # The Ardour backend/engine
427 libraries['ardour'] = LibraryInfo (LIBS='ardour', LIBPATH='#libs/ardour', CPPPATH='#libs/ardour')
428 libraries['midi++2'] = LibraryInfo (LIBS='midi++', LIBPATH='#libs/midi++2', CPPPATH='#libs/midi++2')
429 libraries['pbd'] = LibraryInfo (LIBS='pbd', LIBPATH='#libs/pbd', CPPPATH='#libs/pbd')
430 libraries['gtkmm2ext'] = LibraryInfo (LIBS='gtkmm2ext', LIBPATH='#libs/gtkmm2ext', CPPPATH='#libs/gtkmm2ext')
435 libraries['usb'] = LibraryInfo ()
437 conf = Configure (libraries['usb'])
438 if conf.CheckLib ('usb', 'usb_interrupt_write'):
443 libraries['usb'] = conf.Finish ()
448 libraries['flac'] = LibraryInfo ()
450 conf = Configure (libraries['flac'])
451 conf.CheckLib ('FLAC', 'FLAC__stream_decoder_new', language='CXX')
452 libraries['flac'] = conf.Finish ()
454 # or if that fails...
455 #libraries['flac'] = LibraryInfo (LIBS='FLAC')
457 # boost (we don't link against boost, just use some header files)
459 libraries['boost'] = LibraryInfo ()
460 conf = Configure (libraries['boost'])
461 if conf.CheckHeader ('boost/shared_ptr.hpp', language='CXX') == False:
462 print "Boost header files do not appear to be installed."
465 libraries['boost'] = conf.Finish ()
471 libraries['lo'] = LibraryInfo ()
473 conf = Configure (libraries['lo'])
474 if conf.CheckLib ('lo', 'lo_server_new') == False:
475 print "liblo does not appear to be installed."
478 libraries['lo'] = conf.Finish ()
483 libraries['dmalloc'] = LibraryInfo ()
486 # look for the threaded version
489 conf = Configure (libraries['dmalloc'])
490 if conf.CheckLib ('dmallocth', 'dmalloc_shutdown'):
491 have_libdmalloc = True
493 have_libdmalloc = False
495 libraries['dmalloc'] = conf.Finish ()
498 # Audio/MIDI library (needed for MIDI, since audio is all handled via JACK)
501 conf = Configure(env)
503 if conf.CheckCHeader('alsa/asoundlib.h'):
504 libraries['sysmidi'] = LibraryInfo (LIBS='asound')
505 env['SYSMIDI'] = 'ALSA Sequencer'
506 subst_dict['%MIDITAG%'] = "seq"
507 subst_dict['%MIDITYPE%'] = "alsa/sequencer"
508 elif conf.CheckCHeader('/System/Library/Frameworks/CoreMIDI.framework/Headers/CoreMIDI.h'):
509 # this line is needed because scons can't handle -framework in ParseConfig() yet.
510 libraries['sysmidi'] = LibraryInfo (LINKFLAGS= '-framework CoreMIDI -framework CoreFoundation -framework CoreAudio -framework CoreServices -framework AudioUnit -framework AudioToolbox -bind_at_load')
511 env['SYSMIDI'] = 'CoreMIDI'
512 subst_dict['%MIDITAG%'] = "ardour"
513 subst_dict['%MIDITYPE%'] = "coremidi"
515 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."
522 libraries['sigc2'] = LibraryInfo()
523 libraries['sigc2'].ParseConfig('pkg-config --cflags --libs sigc++-2.0')
524 libraries['glibmm2'] = LibraryInfo()
525 libraries['glibmm2'].ParseConfig('pkg-config --cflags --libs glibmm-2.4')
526 libraries['gdkmm2'] = LibraryInfo()
527 libraries['gdkmm2'].ParseConfig ('pkg-config --cflags --libs gdkmm-2.4')
528 libraries['gtkmm2'] = LibraryInfo()
529 libraries['gtkmm2'].ParseConfig ('pkg-config --cflags --libs gtkmm-2.4')
530 libraries['atkmm'] = LibraryInfo()
531 libraries['atkmm'].ParseConfig ('pkg-config --cflags --libs atkmm-1.6')
532 libraries['pangomm'] = LibraryInfo()
533 libraries['pangomm'].ParseConfig ('pkg-config --cflags --libs pangomm-1.4')
534 libraries['libgnomecanvasmm'] = LibraryInfo()
535 libraries['libgnomecanvasmm'].ParseConfig ('pkg-config --cflags --libs libgnomecanvasmm-2.6')
538 # cannot use system one for the time being
541 libraries['sndfile-ardour'] = LibraryInfo(LIBS='libsndfile-ardour',
542 LIBPATH='#libs/libsndfile',
543 CPPPATH=['#libs/libsndfile', '#libs/libsndfile/src'])
545 # libraries['libglademm'] = LibraryInfo()
546 # libraries['libglademm'].ParseConfig ('pkg-config --cflags --libs libglademm-2.4')
548 # libraries['flowcanvas'] = LibraryInfo(LIBS='flowcanvas', LIBPATH='#/libs/flowcanvas', CPPPATH='#libs/flowcanvas')
549 libraries['soundtouch'] = LibraryInfo()
550 libraries['soundtouch'].ParseConfig ('pkg-config --cflags --libs soundtouch-1.0')
552 libraries['appleutility'] = LibraryInfo(LIBS='libappleutility',
553 LIBPATH='#libs/appleutility',
554 CPPPATH='#libs/appleutility')
565 # these are unconditionally included but have
566 # tests internally to avoid compilation etc
570 # this is unconditionally included but has
571 # tests internally to avoid compilation etc
572 # if COREAUDIO is not set
583 libraries['sigc2'] = LibraryInfo(LIBS='sigc++2',
584 LIBPATH='#libs/sigc++2',
585 CPPPATH='#libs/sigc++2')
586 libraries['glibmm2'] = LibraryInfo(LIBS='glibmm2',
587 LIBPATH='#libs/glibmm2',
588 CPPPATH='#libs/glibmm2')
589 libraries['pangomm'] = LibraryInfo(LIBS='pangomm',
590 LIBPATH='#libs/gtkmm2/pango',
591 CPPPATH='#libs/gtkmm2/pango')
592 libraries['atkmm'] = LibraryInfo(LIBS='atkmm',
593 LIBPATH='#libs/gtkmm2/atk',
594 CPPPATH='#libs/gtkmm2/atk')
595 libraries['gdkmm2'] = LibraryInfo(LIBS='gdkmm2',
596 LIBPATH='#libs/gtkmm2/gdk',
597 CPPPATH='#libs/gtkmm2/gdk')
598 libraries['gtkmm2'] = LibraryInfo(LIBS='gtkmm2',
599 LIBPATH="#libs/gtkmm2/gtk",
600 CPPPATH='#libs/gtkmm2/gtk/')
601 libraries['libgnomecanvasmm'] = LibraryInfo(LIBS='libgnomecanvasmm',
602 LIBPATH='#libs/libgnomecanvasmm',
603 CPPPATH='#libs/libgnomecanvasmm')
605 libraries['soundtouch'] = LibraryInfo(LIBS='soundtouch',
606 LIBPATH='#libs/soundtouch',
607 CPPPATH=['#libs', '#libs/soundtouch'])
608 libraries['sndfile-ardour'] = LibraryInfo(LIBS='libsndfile-ardour',
609 LIBPATH='#libs/libsndfile',
610 CPPPATH=['#libs/libsndfile', '#libs/libsndfile/src'])
611 # libraries['libglademm'] = LibraryInfo(LIBS='libglademm',
612 # LIBPATH='#libs/libglademm',
613 # CPPPATH='#libs/libglademm')
614 libraries['appleutility'] = LibraryInfo(LIBS='libappleutility',
615 LIBPATH='#libs/appleutility',
616 CPPPATH='#libs/appleutility')
629 # these are unconditionally included but have
630 # tests internally to avoid compilation etc
634 # this is unconditionally included but has
635 # tests internally to avoid compilation etc
636 # if COREAUDIO is not set
646 'libs/libgnomecanvasmm',
653 # always build the LGPL control protocol lib, since we link against it ourselves
654 # ditto for generic MIDI
657 surface_subdirs = [ 'libs/surfaces/control_protocol', 'libs/surfaces/generic_midi' ]
661 surface_subdirs += [ 'libs/surfaces/tranzport' ]
662 if os.access ('libs/surfaces/sony9pin', os.F_OK):
663 surface_subdirs += [ 'libs/surfaces/sony9pin' ]
665 opts.Save('scache.conf', env)
666 Help(opts.GenerateHelpText(env))
668 if os.environ.has_key('PATH'):
669 env.Append(PATH = os.environ['PATH'])
671 if os.environ.has_key('PKG_CONFIG_PATH'):
672 env.Append(PKG_CONFIG_PATH = os.environ['PKG_CONFIG_PATH'])
674 if os.environ.has_key('CC'):
675 env['CC'] = os.environ['CC']
677 if os.environ.has_key('CXX'):
678 env['CXX'] = os.environ['CXX']
680 if os.environ.has_key('DISTCC_HOSTS'):
681 env['ENV']['DISTCC_HOSTS'] = os.environ['DISTCC_HOSTS']
682 env['ENV']['HOME'] = os.environ['HOME']
684 final_prefix = '$PREFIX'
687 install_prefix = '$DESTDIR/$PREFIX'
689 install_prefix = env['PREFIX']
691 subst_dict['%INSTALL_PREFIX%'] = install_prefix;
692 subst_dict['%FINAL_PREFIX%'] = final_prefix;
693 subst_dict['%PREFIX%'] = final_prefix;
695 if env['PREFIX'] == '/usr':
696 final_config_prefix = '/etc'
698 final_config_prefix = env['PREFIX'] + '/etc'
700 config_prefix = '$DESTDIR' + final_config_prefix
702 # SCons should really do this for us
704 conf = Configure (env)
706 have_cxx = conf.TryAction (Action (env['CXX'] + ' --version'))
708 print "This system has no functional C++ compiler. You cannot build Ardour from source without one."
711 print "Congratulations, you have a functioning C++ compiler."
716 # Compiler flags and other system-dependent stuff
720 debug_flags = [ '-g' ]
722 # guess at the platform, used to define compiler flags
724 config_guess = os.popen("tools/config.guess").read()[:-1]
730 config = config_guess.split ("-")
732 print "system triple: " + config_guess
735 if env['DIST_TARGET'] == 'auto':
736 if config[config_arch] == 'apple':
737 # The [.] matches to the dot after the major version, "." would match any character
738 if re.search ("darwin[0-7][.]", config[config_kernel]) != None:
739 env['DIST_TARGET'] = 'panther'
741 env['DIST_TARGET'] = 'tiger'
743 if re.search ("x86_64", config[config_cpu]) != None:
744 env['DIST_TARGET'] = 'x86_64'
745 elif re.search("i[0-5]86", config[config_cpu]) != None:
746 env['DIST_TARGET'] = 'i386'
747 elif re.search("powerpc", config[config_cpu]) != None:
748 env['DIST_TARGET'] = 'powerpc'
750 env['DIST_TARGET'] = 'i686'
751 print "\n*******************************"
752 print "detected DIST_TARGET = " + env['DIST_TARGET']
753 print "*******************************\n"
756 if config[config_cpu] == 'powerpc' and env['DIST_TARGET'] != 'none':
758 # Apple/PowerPC optimization options
760 # -mcpu=7450 does not reliably work with gcc 3.*
762 if env['DIST_TARGET'] == 'panther' or env['DIST_TARGET'] == 'tiger':
763 if config[config_arch] == 'apple':
764 opt_flags.extend ([ "-mcpu=7450", "-faltivec"])
766 opt_flags.extend ([ "-mcpu=7400", "-maltivec", "-mabi=altivec"])
768 opt_flags.extend([ "-mcpu=750", "-mmultiple" ])
769 opt_flags.extend (["-mhard-float", "-mpowerpc-gfxopt"])
771 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':
773 build_host_supports_sse = 0
775 debug_flags.append ("-DARCH_X86")
776 opt_flags.append ("-DARCH_X86")
778 if config[config_kernel] == 'linux' :
780 if env['DIST_TARGET'] != 'i386':
782 flag_line = os.popen ("cat /proc/cpuinfo | grep '^flags'").read()[:-1]
783 x86_flags = flag_line.split (": ")[1:][0].split (' ')
785 if "mmx" in x86_flags:
786 opt_flags.append ("-mmmx")
787 if "sse" in x86_flags:
788 build_host_supports_sse = 1
789 if "3dnow" in x86_flags:
790 opt_flags.append ("-m3dnow")
792 if config[config_cpu] == "i586":
793 opt_flags.append ("-march=i586")
794 elif config[config_cpu] == "i686":
795 opt_flags.append ("-march=i686")
797 if ((env['DIST_TARGET'] == 'i686') or (env['DIST_TARGET'] == 'x86_64')) and build_host_supports_sse:
798 opt_flags.extend (["-msse", "-mfpmath=sse"])
799 debug_flags.extend (["-msse", "-mfpmath=sse"])
800 # end of processor-specific section
802 # optimization section
803 if env['FPU_OPTIMIZATION']:
804 if env['DIST_TARGET'] == 'tiger':
805 opt_flags.append ("-DBUILD_VECLIB_OPTIMIZATIONS")
806 debug_flags.append ("-DBUILD_VECLIB_OPTIMIZATIONS")
807 libraries['core'].Append(LINKFLAGS= '-framework Accelerate')
808 elif env['DIST_TARGET'] == 'i686' or env['DIST_TARGET'] == 'x86_64':
809 opt_flags.append ("-DBUILD_SSE_OPTIMIZATIONS")
810 debug_flags.append ("-DBUILD_SSE_OPTIMIZATIONS")
811 if env['DIST_TARGET'] == 'x86_64':
812 opt_flags.append ("-DUSE_X86_64_ASM")
813 debug_flags.append ("-DUSE_X86_64_ASM")
814 if build_host_supports_sse != 1:
815 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)"
816 # end optimization section
819 # save off guessed arch element in an env
821 env.Append(CONFIG_ARCH=config[config_arch])
825 # ARCH="..." overrides all
828 if env['ARCH'] != '':
829 opt_flags = env['ARCH'].split()
832 # prepend boiler plate optimization flags
837 "-fomit-frame-pointer",
842 if env['DEBUG'] == 1:
843 env.Append(CCFLAGS=" ".join (debug_flags))
845 env.Append(CCFLAGS=" ".join (opt_flags))
851 env.Append(CCFLAGS="-Wall")
852 env.Append(CXXFLAGS="-Woverloaded-virtual")
854 if env['EXTRA_WARN']:
855 env.Append(CCFLAGS="-Wextra -pedantic")
856 env.Append(CXXFLAGS="-ansi")
859 env.Append(CCFLAGS="-DHAVE_LIBLO")
862 # everybody needs this
865 env.Merge ([ libraries['core'] ])
868 # fix scons nitpickiness on APPLE
871 if env['DIST_TARGET'] == 'panther' or env['DIST_TARGET'] == 'tiger':
872 env.Append(CCFLAGS="-I/opt/local/include", LINKFLAGS="-L/opt/local/lib")
878 conf = Configure (env)
880 nls_error = 'This system is not configured for internationalized applications. An english-only version will be built:'
881 print 'Checking for internationalization support ...'
882 have_gettext = conf.TryAction(Action('xgettext --version'))
883 if have_gettext[0] != 1:
884 nls_error += ' No xgettext command.'
887 print "Found xgettext"
889 have_msgmerge = conf.TryAction(Action('msgmerge --version'))
890 if have_msgmerge[0] != 1:
891 nls_error += ' No msgmerge command.'
894 print "Found msgmerge"
896 if not conf.CheckCHeader('libintl.h'):
897 nls_error += ' No libintl.h.'
903 print "International version will be built."
907 env.Append(CCFLAGS="-DENABLE_NLS")
909 Export('env install_prefix final_prefix config_prefix final_config_prefix libraries i18n version subst_dict')
912 # the configuration file may be system dependent
915 conf = env.Configure ()
917 if conf.CheckCHeader('/System/Library/Frameworks/CoreAudio.framework/Versions/A/Headers/CoreAudio.h'):
918 subst_dict['%JACK_INPUT%'] = "coreaudio:Built-in Audio:in"
919 subst_dict['%JACK_OUTPUT%'] = "coreaudio:Built-in Audio:out"
921 subst_dict['%JACK_INPUT%'] = "alsa_pcm:playback_"
922 subst_dict['%JACK_OUTPUT%'] = "alsa_pcm:capture_"
924 # posix_memalign available
925 if not conf.CheckFunc('posix_memalign'):
926 print 'Did not find posix_memalign(), using malloc'
927 env.Append(CCFLAGS='-DNO_POSIX_MEMALIGN')
932 rcbuild = env.SubstInFile ('ardour.rc','ardour.rc.in', SUBST_DICT = subst_dict)
934 env.Alias('install', env.Install(os.path.join(config_prefix, 'ardour2'), 'ardour_system.rc'))
935 env.Alias('install', env.Install(os.path.join(config_prefix, 'ardour2'), 'ardour.rc'))
941 Precious (env['DISTTREE'])
944 # note the special "cleanfirst" source name. this triggers removal
945 # of the existing disttree
948 env.Distribute (env['DISTTREE'],
950 'COPYING', 'PACKAGER_README', 'README',
953 'tools/config.guess',
954 'icons/icon/ardour_icon_mac_mask.png',
955 'icons/icon/ardour_icon_mac.png',
956 'icons/icon/ardour_icon_tango_16px_blue.png',
957 'icons/icon/ardour_icon_tango_16px_red.png',
958 'icons/icon/ardour_icon_tango_22px_blue.png',
959 'icons/icon/ardour_icon_tango_22px_red.png',
960 'icons/icon/ardour_icon_tango_32px_blue.png',
961 'icons/icon/ardour_icon_tango_32px_red.png',
962 'icons/icon/ardour_icon_tango_48px_blue.png',
963 'icons/icon/ardour_icon_tango_48px_red.png'
965 glob.glob ('DOCUMENTATION/AUTHORS*') +
966 glob.glob ('DOCUMENTATION/CONTRIBUTORS*') +
967 glob.glob ('DOCUMENTATION/TRANSLATORS*') +
968 glob.glob ('DOCUMENTATION/BUILD*') +
969 glob.glob ('DOCUMENTATION/FAQ*') +
970 glob.glob ('DOCUMENTATION/README*')
973 srcdist = env.Tarball(env['TARBALL'], env['DISTTREE'])
974 env.Alias ('srctar', srcdist)
977 # don't leave the distree around
979 env.AddPreAction (env['DISTTREE'], Action ('rm -rf ' + str (File (env['DISTTREE']))))
980 env.AddPostAction (srcdist, Action ('rm -rf ' + str (File (env['DISTTREE']))))
986 for subdir in coredirs:
987 SConscript (subdir + '/SConscript')
989 for sublistdir in [ subdirs, gtk_subdirs, surface_subdirs ]:
990 for subdir in sublistdir:
991 SConscript (subdir + '/SConscript')
994 env.Clean ('scrub', [ 'scache.conf', '.sconf_temp', '.sconsign.dblite', 'config.log'])