17 EnsureSConsVersion(0, 96)
19 ardour_version = '2.3'
24 # Command-line options
27 opts = Options('scache.conf')
29 ('ARCH', 'Set architecture-specific compilation flags by hand (all flags as 1 argument)',''),
30 ('WINDOWS_KEY', 'Set X Modifier (Mod1,Mod2,Mod3,Mod4,Mod5) for "Windows" key', 'Mod4'),
31 BoolOption('AUDIOUNITS', 'Compile with Apple\'s AudioUnit library. (experimental)', 0),
32 BoolOption('COREAUDIO', 'Compile with Apple\'s CoreAudio library', 0),
33 BoolOption('GTKOSX', 'Compile for use with GTK-OSX, not GTK-X11', 0),
34 BoolOption('NATIVE_OSX_KEYS', 'Build key bindings file that matches OS X conventions', 0),
35 BoolOption('OLDFONTS', 'Old school font sizes', 0),
36 BoolOption('DEBUG', 'Set to build with debugging information and no optimizations', 0),
37 PathOption('DESTDIR', 'Set the intermediate install "prefix"', '/'),
38 EnumOption('DIST_TARGET', 'Build target for cross compiling packagers', 'auto', allowed_values=('auto', 'i386', 'i686', 'x86_64', 'powerpc', 'tiger', 'panther', 'leopard', 'none' ), ignorecase=2),
39 BoolOption('DMALLOC', 'Compile and link using the dmalloc library', 0),
40 BoolOption('EXTRA_WARN', 'Compile with -Wextra, -ansi, and -pedantic. Might break compilation. For pedants', 0),
41 BoolOption('FFT_ANALYSIS', 'Include FFT analysis window', 0),
42 BoolOption('FPU_OPTIMIZATION', 'Build runtime checked assembler code', 1),
43 BoolOption('LIBLO', 'Compile with support for liblo library', 1),
44 BoolOption('NLS', 'Set to turn on i18n support', 1),
45 PathOption('PREFIX', 'Set the install "prefix"', '/usr/local'),
46 BoolOption('SURFACES', 'Build support for control surfaces', 1),
47 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),
48 BoolOption('UNIVERSAL', 'Compile as universal binary. Requires that external libraries are already universal.', 0),
49 BoolOption('VERSIONED', 'Add revision information to ardour/gtk executable name inside the build directory', 0),
50 BoolOption('VST', 'Compile with support for VST', 0),
51 BoolOption('LV2', 'Compile with support for LV2 (if slv2 is available)', 1),
52 BoolOption('GPROFILE', 'Compile with support for gprofile (Developers only)', 0),
53 BoolOption('TRANZPORT', 'Compile with support for Frontier Designs (if libusb is available)', 1)
56 #----------------------------------------------------------------------
57 # a handy helper that provides a way to merge compile/link information
58 # from multiple different "environments"
59 #----------------------------------------------------------------------
61 class LibraryInfo(Environment):
62 def __init__(self,*args,**kw):
63 Environment.__init__ (self,*args,**kw)
65 def Merge (self,others):
67 self.Append (LIBS = other.get ('LIBS',[]))
68 self.Append (LIBPATH = other.get ('LIBPATH', []))
69 self.Append (CPPPATH = other.get('CPPPATH', []))
70 self.Append (LINKFLAGS = other.get('LINKFLAGS', []))
71 self.Append (CCFLAGS = other.get('CCFLAGS', []))
72 self.Replace(LIBPATH = list(Set(self.get('LIBPATH', []))))
73 self.Replace(CPPPATH = list(Set(self.get('CPPPATH',[]))))
74 #doing LINKFLAGS breaks -framework
75 #doing LIBS break link order dependency
77 def ENV_update(self, src_ENV):
78 for k in src_ENV.keys():
79 if k in self['ENV'].keys() and k in [ 'PATH', 'LD_LIBRARY_PATH',
81 self['ENV'][k]=SCons.Util.AppendPath(self['ENV'][k], src_ENV[k])
83 self['ENV'][k]=src_ENV[k]
85 env = LibraryInfo (options = opts,
87 VERSION = ardour_version,
88 TARBALL='ardour-' + ardour_version + '.tar.bz2',
90 DISTTREE = '#ardour-' + ardour_version,
91 DISTCHECKDIR = '#ardour-' + ardour_version + '/check'
94 env.ENV_update(os.environ)
96 #----------------------------------------------------------------------
98 #----------------------------------------------------------------------
100 # Handy subst-in-file builder
103 def do_subst_in_file(targetfile, sourcefile, dict):
104 """Replace all instances of the keys of dict with their values.
105 For example, if dict is {'%VERSION%': '1.2345', '%BASE%': 'MyProg'},
106 then all instances of %VERSION% in the file will be replaced with 1.2345 etc.
109 f = open(sourcefile, 'rb')
113 raise SCons.Errors.UserError, "Can't read source file %s"%sourcefile
114 for (k,v) in dict.items():
115 contents = re.sub(k, v, contents)
117 f = open(targetfile, 'wb')
121 raise SCons.Errors.UserError, "Can't write target file %s"%targetfile
124 def subst_in_file(target, source, env):
125 if not env.has_key('SUBST_DICT'):
126 raise SCons.Errors.UserError, "SubstInFile requires SUBST_DICT to be set."
127 d = dict(env['SUBST_DICT']) # copy it
128 for (k,v) in d.items():
130 d[k] = env.subst(v())
131 elif SCons.Util.is_String(v):
134 raise SCons.Errors.UserError, "SubstInFile: key %s: %s must be a string or callable"%(k, repr(v))
135 for (t,s) in zip(target, source):
136 return do_subst_in_file(str(t), str(s), d)
138 def subst_in_file_string(target, source, env):
139 """This is what gets printed on the console."""
140 return '\n'.join(['Substituting vars from %s into %s'%(str(s), str(t))
141 for (t,s) in zip(target, source)])
143 def subst_emitter(target, source, env):
144 """Add dependency from substituted SUBST_DICT to target.
145 Returns original target, source tuple unchanged.
147 d = env['SUBST_DICT'].copy() # copy it
148 for (k,v) in d.items():
150 d[k] = env.subst(v())
151 elif SCons.Util.is_String(v):
153 Depends(target, SCons.Node.Python.Value(d))
154 # Depends(target, source) # this doesn't help the install-sapphire-linux.sh problem
155 return target, source
157 subst_action = Action (subst_in_file, subst_in_file_string)
158 env['BUILDERS']['SubstInFile'] = Builder(action=subst_action, emitter=subst_emitter)
161 # internationalization
164 # po_builder: builder function to copy po files to the parent directory while updating them
166 # first source: .po file
167 # second source: .pot file
170 def po_builder(target,source,env):
171 os.spawnvp (os.P_WAIT, 'cp', ['cp', str(source[0]), str(target[0])])
177 print 'Updating ' + str(target[0])
178 return os.spawnvp (os.P_WAIT, 'msgmerge', args)
180 po_bld = Builder (action = po_builder)
181 env.Append(BUILDERS = {'PoBuild' : po_bld})
183 # mo_builder: builder function for (binary) message catalogs (.mo)
185 # first source: .po file
188 def mo_builder(target,source,env):
192 target[0].get_path(),
195 return os.spawnvp (os.P_WAIT, 'msgfmt', args)
197 mo_bld = Builder (action = mo_builder)
198 env.Append(BUILDERS = {'MoBuild' : mo_bld})
200 # pot_builder: builder function for message templates (.pot)
202 # source: list of C/C++ etc. files to extract messages from
205 def pot_builder(target,source,env):
210 '-o', target[0].get_path(),
211 "--default-domain=" + env['PACKAGE'],
212 '--copyright-holder="Paul Davis"' ]
213 args += [ src.get_path() for src in source ]
215 return os.spawnvp (os.P_WAIT, 'xgettext', args)
217 pot_bld = Builder (action = pot_builder)
218 env.Append(BUILDERS = {'PotBuild' : pot_bld})
221 # utility function, not a builder
224 def i18n (buildenv, sources, installenv):
225 domain = buildenv['PACKAGE']
226 potfile = buildenv['POTFILE']
228 installenv.Alias ('potupdate', buildenv.PotBuild (potfile, sources))
230 p_oze = [ os.path.basename (po) for po in glob.glob ('po/*.po') ]
231 languages = [ po.replace ('.po', '') for po in p_oze ]
233 for po_file in p_oze:
234 buildenv.PoBuild(po_file, ['po/'+po_file, potfile])
235 mo_file = po_file.replace (".po", ".mo")
236 installenv.Alias ('install', buildenv.MoBuild (mo_file, po_file))
237 installenv.Alias ('msgupdate', buildenv.MoBuild (mo_file, po_file))
239 for lang in languages:
240 modir = (os.path.join (install_prefix, 'share/locale/' + lang + '/LC_MESSAGES/'))
241 moname = domain + '.mo'
242 installenv.Alias('install', installenv.InstallAs (os.path.join (modir, moname), lang + '.mo'))
245 def fetch_svn_revision (path):
249 cmd += " | awk '/^Revision:/ { print $2}'"
250 return commands.getoutput (cmd)
252 def create_stored_revision (target = None, source = None, env = None):
253 if os.path.exists('.svn'):
254 rev = fetch_svn_revision ('.');
256 text = "#ifndef __ardour_svn_revision_h__\n"
257 text += "#define __ardour_svn_revision_h__\n"
258 text += "static const char* ardour_svn_revision = \"" + rev + "\";\n";
260 print '============> writing svn revision info to svn_revision.h\n'
261 o = file ('svn_revision.h', 'w')
265 print "Could not open svn_revision.h for writing\n"
268 print "You cannot use \"scons revision\" on without using a checked out"
269 print "copy of the Ardour source code repository"
273 # A generic builder for version.cc files
275 # note: requires that DOMAIN, MAJOR, MINOR, MICRO are set in the construction environment
276 # note: assumes one source files, the header that declares the version variables
279 def version_builder (target, source, env):
281 text = "int " + env['DOMAIN'] + "_major_version = " + str (env['MAJOR']) + ";\n"
282 text += "int " + env['DOMAIN'] + "_minor_version = " + str (env['MINOR']) + ";\n"
283 text += "int " + env['DOMAIN'] + "_micro_version = " + str (env['MICRO']) + ";\n"
286 o = file (target[0].get_path(), 'w')
290 print "Could not open", target[0].get_path(), " for writing\n"
293 text = "#ifndef __" + env['DOMAIN'] + "_version_h__\n"
294 text += "#define __" + env['DOMAIN'] + "_version_h__\n"
295 text += "extern const char* " + env['DOMAIN'] + "_revision;\n"
296 text += "extern int " + env['DOMAIN'] + "_major_version;\n"
297 text += "extern int " + env['DOMAIN'] + "_minor_version;\n"
298 text += "extern int " + env['DOMAIN'] + "_micro_version;\n"
299 text += "#endif /* __" + env['DOMAIN'] + "_version_h__ */\n"
302 o = file (target[1].get_path(), 'w')
306 print "Could not open", target[1].get_path(), " for writing\n"
311 version_bld = Builder (action = version_builder)
312 env.Append (BUILDERS = {'VersionBuild' : version_bld})
315 # a builder that makes a hard link from the 'source' executable to a name with
316 # a "build ID" based on the most recent CVS activity that might be reasonably
317 # related to version activity. this relies on the idea that the SConscript
318 # file that builds the executable is updated with new version info and committed
319 # to the source code repository whenever things change.
322 def versioned_builder(target,source,env):
323 w, r = os.popen2( "LANG= svn info | awk '/^Revision:/ { print $2}'")
325 last_revision = r.readline().strip()
328 if last_revision == "":
329 print "No SVN info found - versioned executable cannot be built"
332 print "The current build ID is " + last_revision
334 tagged_executable = source[0].get_path() + '-' + last_revision
336 if os.path.exists (tagged_executable):
337 print "Replacing existing executable with the same build tag."
338 os.unlink (tagged_executable)
340 return os.link (source[0].get_path(), tagged_executable)
342 verbuild = Builder (action = versioned_builder)
343 env.Append (BUILDERS = {'VersionedExecutable' : verbuild})
346 # source tar file builder
349 def distcopy (target, source, env):
350 treedir = str (target[0])
354 except OSError, (errnum, strerror):
355 if errnum != errno.EEXIST:
356 print 'mkdir ', treedir, ':', strerror
360 # we don't know what characters might be in the file names
361 # so quote them all before passing them to the shell
363 all_files = ([ str(s) for s in source ])
364 cmd += " ".join ([ "'%s'" % quoted for quoted in all_files])
365 cmd += ' | (cd ' + treedir + ' && tar xf -)'
369 def tarballer (target, source, env):
370 cmd = 'tar -jcf ' + str (target[0]) + ' ' + str(source[0]) + " --exclude '*~'" + " --exclude .svn --exclude '.svn/*'"
371 print 'running ', cmd, ' ... '
375 dist_bld = Builder (action = distcopy,
376 target_factory = SCons.Node.FS.default_fs.Entry,
377 source_factory = SCons.Node.FS.default_fs.Entry,
380 tarball_bld = Builder (action = tarballer,
381 target_factory = SCons.Node.FS.default_fs.Entry,
382 source_factory = SCons.Node.FS.default_fs.Entry)
384 env.Append (BUILDERS = {'Distribute' : dist_bld})
385 env.Append (BUILDERS = {'Tarball' : tarball_bld})
388 # Make sure they know what they are doing
392 if os.path.isfile('.personal_use_only'):
393 print "Enabling VST support. Note that distributing a VST-enabled ardour\nis a violation of several different licences.\nBuild with VST=false if you intend to distribute ardour to others."
395 sys.stdout.write ("Are you building Ardour for personal use (rather than distribution to others)? [no]: ")
396 answer = sys.stdin.readline ()
397 answer = answer.rstrip().strip()
398 if answer == "yes" or answer == "y":
399 fh = open('.personal_use_only', 'w')
401 print "OK, VST support will be enabled"
403 print 'You cannot build Ardour with VST support for distribution to others.\nIt is a violation of several different licenses. Build with VST=false.'
406 if os.path.isfile('.personal_use_only'):
407 os.remove('.personal_use_only')
413 def pushEnvironment(context):
414 if os.environ.has_key('PATH'):
415 context.Append(PATH = os.environ['PATH'])
417 if os.environ.has_key('PKG_CONFIG_PATH'):
418 context.Append(PKG_CONFIG_PATH = os.environ['PKG_CONFIG_PATH'])
420 if os.environ.has_key('CC'):
421 context['CC'] = os.environ['CC']
423 if os.environ.has_key('CXX'):
424 context['CXX'] = os.environ['CXX']
426 if os.environ.has_key('DISTCC_HOSTS'):
427 context['ENV']['DISTCC_HOSTS'] = os.environ['DISTCC_HOSTS']
428 context['ENV']['HOME'] = os.environ['HOME']
430 pushEnvironment (env)
432 #######################
433 # Dependency Checking #
434 #######################
438 'glib-2.0' : '2.10.1',
439 'gthread-2.0' : '2.10.1',
440 'gtk+-2.0' : '2.8.1',
441 'libxml-2.0' : '2.6.0',
442 'samplerate' : '0.1.0',
446 'libgnomecanvas-2.0' : '2.0'
449 def DependenciesRequiredMessage():
450 print 'You do not have the necessary dependencies required to build ardour'
451 print 'Please consult http://ardour.org/building for more information'
453 def CheckPKGConfig(context, version):
454 context.Message( 'Checking for pkg-config version >= %s... ' %version )
455 ret = context.TryAction('pkg-config --atleast-pkgconfig-version=%s' % version)[0]
456 context.Result( ret )
459 def CheckPKGVersion(context, name, version):
460 context.Message( 'Checking for %s... ' % name )
461 ret = context.TryAction('pkg-config --atleast-version=%s %s' %(version,name) )[0]
462 context.Result( ret )
465 def CheckPKGExists(context, name):
466 context.Message ('Checking for %s...' % name)
467 ret = context.TryAction('pkg-config --exists %s' % name)[0]
471 conf = Configure(env, custom_tests = { 'CheckPKGConfig' : CheckPKGConfig,
472 'CheckPKGVersion' : CheckPKGVersion })
474 # I think a more recent version is needed on win32
475 min_pkg_config_version = '0.8.0'
477 if not conf.CheckPKGConfig(min_pkg_config_version):
478 print 'pkg-config >= %s not found.' % min_pkg_config_version
481 for pkg, version in deps.iteritems():
482 if not conf.CheckPKGVersion( pkg, version ):
483 print '%s >= %s not found.' %(pkg, version)
484 DependenciesRequiredMessage()
489 # ----------------------------------------------------------------------
490 # Construction environment setup
491 # ----------------------------------------------------------------------
495 libraries['core'] = LibraryInfo (CCFLAGS = '-Ilibs')
497 #libraries['sndfile'] = LibraryInfo()
498 #libraries['sndfile'].ParseConfig('pkg-config --cflags --libs sndfile')
500 libraries['lrdf'] = LibraryInfo()
501 libraries['lrdf'].ParseConfig('pkg-config --cflags --libs lrdf')
503 libraries['raptor'] = LibraryInfo()
504 libraries['raptor'].ParseConfig('pkg-config --cflags --libs raptor')
506 libraries['samplerate'] = LibraryInfo()
507 libraries['samplerate'].ParseConfig('pkg-config --cflags --libs samplerate')
509 conf = env.Configure (custom_tests = { 'CheckPKGExists' : CheckPKGExists } )
511 if conf.CheckPKGExists ('fftw3f'):
512 libraries['fftw3f'] = LibraryInfo()
513 libraries['fftw3f'].ParseConfig('pkg-config --cflags --libs fftw3f')
515 if conf.CheckPKGExists ('fftw3'):
516 libraries['fftw3'] = LibraryInfo()
517 libraries['fftw3'].ParseConfig('pkg-config --cflags --libs fftw3')
521 if env['FFT_ANALYSIS']:
523 # Check for fftw3 header as well as the library
526 conf = Configure(libraries['fftw3'])
528 if conf.CheckHeader ('fftw3.h') == False:
529 print ('FFT Analysis cannot be compiled without the FFTW3 headers, which do not seem to be installed')
534 conf = env.Configure(custom_tests = { 'CheckPKGExists' : CheckPKGExists })
536 if conf.CheckPKGExists ('\"slv2 >= 0.6.0\"'):
537 libraries['slv2'] = LibraryInfo()
538 libraries['slv2'].ParseConfig('pkg-config --cflags --libs slv2')
539 env.Append (CCFLAGS="-DHAVE_LV2")
541 print 'Building Ardour with LV2 support requires SLV2 >= 0.6.0'
542 print 'WARNING: SLV2 not found, or too old. Ardour will be built without LV2 support.'
543 print 'Until the 2.4 release, Ardour requires SLV2 out of SVN.'
544 print 'Testing would be very much appreciated! svn co http://svn.drobilla.net/lad/slv2'
548 print 'LV2 support is not enabled. Build with \'scons LV2=1\' to enable.'
550 libraries['jack'] = LibraryInfo()
551 libraries['jack'].ParseConfig('pkg-config --cflags --libs jack')
553 libraries['xml'] = LibraryInfo()
554 libraries['xml'].ParseConfig('pkg-config --cflags --libs libxml-2.0')
556 libraries['xslt'] = LibraryInfo()
557 libraries['xslt'].ParseConfig('pkg-config --cflags --libs libxslt')
559 libraries['glib2'] = LibraryInfo()
560 libraries['glib2'].ParseConfig ('pkg-config --cflags --libs glib-2.0')
561 libraries['glib2'].ParseConfig ('pkg-config --cflags --libs gobject-2.0')
562 libraries['glib2'].ParseConfig ('pkg-config --cflags --libs gmodule-2.0')
563 libraries['glib2'].ParseConfig ('pkg-config --cflags --libs gthread-2.0')
565 libraries['gtk2'] = LibraryInfo()
566 libraries['gtk2'].ParseConfig ('pkg-config --cflags --libs gtk+-2.0')
568 libraries['pango'] = LibraryInfo()
569 libraries['pango'].ParseConfig ('pkg-config --cflags --libs pango')
571 libraries['libgnomecanvas2'] = LibraryInfo()
572 libraries['libgnomecanvas2'].ParseConfig ('pkg-config --cflags --libs libgnomecanvas-2.0')
574 #libraries['flowcanvas'] = LibraryInfo(LIBS='flowcanvas', LIBPATH='#/libs/flowcanvas', CPPPATH='#libs/flowcanvas')
576 # The Ardour Control Protocol Library
578 libraries['ardour_cp'] = LibraryInfo (LIBS='ardour_cp', LIBPATH='#libs/surfaces/control_protocol',
579 CPPPATH='#libs/surfaces/control_protocol')
581 # The Ardour backend/engine
583 libraries['ardour'] = LibraryInfo (LIBS='ardour', LIBPATH='#libs/ardour', CPPPATH='#libs/ardour')
584 libraries['midi++2'] = LibraryInfo (LIBS='midi++', LIBPATH='#libs/midi++2', CPPPATH='#libs/midi++2')
585 libraries['pbd'] = LibraryInfo (LIBS='pbd', LIBPATH='#libs/pbd', CPPPATH='#libs/pbd')
586 libraries['gtkmm2ext'] = LibraryInfo (LIBS='gtkmm2ext', LIBPATH='#libs/gtkmm2ext', CPPPATH='#libs/gtkmm2ext')
589 # SCons should really do this for us
591 conf = env.Configure ()
593 have_cxx = conf.TryAction (Action (str(env['CXX']) + ' --version'))
595 print "This system has no functional C++ compiler. You cannot build Ardour from source without one."
598 print "Congratulations, you have a functioning C++ compiler."
604 # Compiler flags and other system-dependent stuff
608 if env['GPROFILE'] == 1:
609 debug_flags = [ '-g', '-pg' ]
611 debug_flags = [ '-g' ]
613 # guess at the platform, used to define compiler flags
615 config_guess = os.popen("tools/config.guess").read()[:-1]
621 config = config_guess.split ("-")
623 print "system triple: " + config_guess
626 if env['DIST_TARGET'] == 'auto':
627 if config[config_arch] == 'apple':
628 # The [.] matches to the dot after the major version, "." would match any character
629 if re.search ("darwin[0-7][.]", config[config_kernel]) != None:
630 env['DIST_TARGET'] = 'panther'
631 if re.search ("darwin8[.]", config[config_kernel]) != None:
632 env['DIST_TARGET'] = 'tiger'
634 env['DIST_TARGET'] = 'leopard'
636 if re.search ("x86_64", config[config_cpu]) != None:
637 env['DIST_TARGET'] = 'x86_64'
638 elif re.search("i[0-5]86", config[config_cpu]) != None:
639 env['DIST_TARGET'] = 'i386'
640 elif re.search("powerpc", config[config_cpu]) != None:
641 env['DIST_TARGET'] = 'powerpc'
643 env['DIST_TARGET'] = 'i686'
644 print "\n*******************************"
645 print "detected DIST_TARGET = " + env['DIST_TARGET']
646 print "*******************************\n"
649 if config[config_cpu] == 'powerpc' and env['DIST_TARGET'] != 'none':
651 # Apple/PowerPC optimization options
653 # -mcpu=7450 does not reliably work with gcc 3.*
655 if env['DIST_TARGET'] == 'panther' or env['DIST_TARGET'] == 'tiger':
656 if config[config_arch] == 'apple':
657 ## opt_flags.extend ([ "-mcpu=7450", "-faltivec"])
658 # to support g3s but still have some optimization for above
659 opt_flags.extend ([ "-mcpu=G3", "-mtune=7450"])
661 opt_flags.extend ([ "-mcpu=7400", "-maltivec", "-mabi=altivec"])
663 opt_flags.extend([ "-mcpu=750", "-mmultiple" ])
664 opt_flags.extend (["-mhard-float", "-mpowerpc-gfxopt"])
665 opt_flags.extend (["-Os"])
667 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':
669 build_host_supports_sse = 0
671 debug_flags.append ("-DARCH_X86")
672 opt_flags.append ("-DARCH_X86")
674 if config[config_kernel] == 'linux' :
676 if env['DIST_TARGET'] != 'i386':
678 flag_line = os.popen ("cat /proc/cpuinfo | grep '^flags'").read()[:-1]
679 x86_flags = flag_line.split (": ")[1:][0].split ()
681 if "mmx" in x86_flags:
682 opt_flags.append ("-mmmx")
683 if "sse" in x86_flags:
684 build_host_supports_sse = 1
685 if "3dnow" in x86_flags:
686 opt_flags.append ("-m3dnow")
688 if config[config_cpu] == "i586":
689 opt_flags.append ("-march=i586")
690 elif config[config_cpu] == "i686":
691 opt_flags.append ("-march=i686")
693 if ((env['DIST_TARGET'] == 'i686') or (env['DIST_TARGET'] == 'x86_64')) and build_host_supports_sse:
694 opt_flags.extend (["-msse", "-mfpmath=sse", "-DUSE_XMMINTRIN"])
695 debug_flags.extend (["-msse", "-mfpmath=sse", "-DUSE_XMMINTRIN"])
696 # end of processor-specific section
698 # optimization section
699 if env['FPU_OPTIMIZATION']:
700 if env['DIST_TARGET'] == 'tiger' or env['DIST_TARGET'] == 'leopard':
701 opt_flags.append ("-DBUILD_VECLIB_OPTIMIZATIONS");
702 debug_flags.append ("-DBUILD_VECLIB_OPTIMIZATIONS");
703 libraries['core'].Append(LINKFLAGS= '-framework Accelerate')
704 elif env['DIST_TARGET'] == 'i686' or env['DIST_TARGET'] == 'x86_64':
705 opt_flags.append ("-DBUILD_SSE_OPTIMIZATIONS")
706 debug_flags.append ("-DBUILD_SSE_OPTIMIZATIONS")
707 if env['DIST_TARGET'] == 'x86_64':
708 opt_flags.append ("-DUSE_X86_64_ASM")
709 debug_flags.append ("-DUSE_X86_64_ASM")
710 if build_host_supports_sse != 1:
711 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)"
712 # end optimization section
714 # handle x86/x86_64 libdir properly
716 if env['DIST_TARGET'] == 'x86_64':
717 env['LIBDIR']='lib64'
722 # a single way to test if we're on OS X
725 if env['DIST_TARGET'] in ['panther', 'tiger', 'leopard' ]:
727 # force tiger or later, to avoid issues on PPC which defaults
728 # back to 10.1 if we don't tell it otherwise.
729 env.Append (CCFLAGS="-DMAC_OS_X_VERSION_MIN_REQUIRED=1040")
734 # save off guessed arch element in an env
736 env.Append(CONFIG_ARCH=config[config_arch])
740 # ARCH="..." overrides all
743 if env['ARCH'] != '':
744 opt_flags = env['ARCH'].split()
747 # prepend boiler plate optimization flags
752 "-fomit-frame-pointer",
758 if env['DEBUG'] == 1:
759 env.Append(CCFLAGS=" ".join (debug_flags))
760 env.Append(LINKFLAGS=" ".join (debug_flags))
762 env.Append(CCFLAGS=" ".join (opt_flags))
763 env.Append(LINKFLAGS=" ".join (opt_flags))
765 if env['UNIVERSAL'] == 1:
766 env.Append(CCFLAGS="-arch i386 -arch ppc")
767 env.Append(LINKFLAGS="-arch i386 -arch ppc")
773 env.Append(CCFLAGS="-Wall")
774 env.Append(CXXFLAGS="-Woverloaded-virtual")
776 if env['EXTRA_WARN']:
777 env.Append(CCFLAGS="-Wextra -pedantic -ansi")
778 env.Append(CXXFLAGS="-ansi")
779 # env.Append(CFLAGS="-iso")
782 env.Append(CCFLAGS="-DHAVE_LIBLO")
786 # fix scons nitpickiness on APPLE
790 def prep_libcheck(topenv, libinfo):
793 # rationale: GTK-Quartz uses jhbuild and installs to /opt/gtk by default.
794 # All libraries needed should be built against this location
796 libinfo.Append(CPPPATH="/opt/gtk/include", LIBPATH="/opt/gtk/lib")
797 libinfo.Append(CXXFLAGS="-I/opt/gtk/include", LINKFLAGS="-L/opt/gtk/lib")
798 libinfo.Append(CPPPATH="/opt/local/include", LIBPATH="/opt/local/lib")
799 libinfo.Append(CXXFLAGS="-I/opt/local/include", LINKFLAGS="-L/opt/local/lib")
801 prep_libcheck(env, env)
805 # these are part of the Ardour source tree because they are C++
808 libraries['vamp'] = LibraryInfo (LIBS='vampsdk',
809 LIBPATH='#libs/vamp-sdk',
810 CPPPATH='#libs/vamp-sdk')
811 libraries['vamphost'] = LibraryInfo (LIBS='vamphostsdk',
812 LIBPATH='#libs/vamp-sdk',
813 CPPPATH='#libs/vamp-sdk')
815 env['RUBBERBAND'] = False
817 conf = Configure (env)
819 if conf.CheckHeader ('fftw3.h'):
820 env['RUBBERBAND'] = True
821 libraries['rubberband'] = LibraryInfo (LIBS='rubberband',
822 LIBPATH='#libs/rubberband',
823 CPPPATH='#libs/rubberband',
824 CCFLAGS='-DUSE_RUBBERBAND')
827 print "-------------------------------------------------------------------------"
828 print "You do not have the FFTW single-precision development package installed."
829 print "This prevents Ardour from using the Rubberband library for timestretching"
830 print "and pitchshifting. It will fall back on SoundTouch for timestretch, and "
831 print "pitchshifting will not be available."
832 print "-------------------------------------------------------------------------"
840 libraries['usb'] = LibraryInfo ()
841 prep_libcheck(env, libraries['usb'])
843 conf = Configure (libraries['usb'])
844 if conf.CheckLib ('usb', 'usb_interrupt_write'):
849 # check for linux/input.h while we're at it for powermate
850 if conf.CheckHeader('linux/input.h'):
851 have_linux_input = True
853 have_linux_input = False
855 libraries['usb'] = conf.Finish ()
860 libraries['flac'] = LibraryInfo ()
861 prep_libcheck(env, libraries['flac'])
862 libraries['flac'].Append(CPPPATH="/usr/local/include", LIBPATH="/usr/local/lib")
865 # june 1st 2007: look for a function that is in FLAC 1.1.2 and not in later versions
866 # since the version of libsndfile we have internally does not support
867 # the new API that libFLAC has adopted
870 conf = Configure (libraries['flac'])
871 if conf.CheckLib ('FLAC', 'FLAC__seekable_stream_decoder_init', language='CXX'):
872 conf.env.Append(CCFLAGS='-DHAVE_FLAC')
877 libraries['flac'] = conf.Finish ()
879 # or if that fails...
880 #libraries['flac'] = LibraryInfo (LIBS='FLAC')
882 # boost (we don't link against boost, just use some header files)
884 libraries['boost'] = LibraryInfo ()
885 prep_libcheck(env, libraries['boost'])
886 libraries['boost'].Append(CPPPATH="/usr/local/include", LIBPATH="/usr/local/lib")
887 conf = Configure (libraries['boost'])
888 if conf.CheckHeader ('boost/shared_ptr.hpp', language='CXX') == False:
889 print "Boost header files do not appear to be installed."
892 libraries['boost'] = conf.Finish ()
898 libraries['lo'] = LibraryInfo ()
899 prep_libcheck(env, libraries['lo'])
901 conf = Configure (libraries['lo'])
902 if conf.CheckLib ('lo', 'lo_server_new') == False:
903 print "liblo does not appear to be installed."
906 libraries['lo'] = conf.Finish ()
911 libraries['dmalloc'] = LibraryInfo ()
912 prep_libcheck(env, libraries['dmalloc'])
915 # look for the threaded version
918 conf = Configure (libraries['dmalloc'])
919 if conf.CheckLib ('dmallocth', 'dmalloc_shutdown'):
920 have_libdmalloc = True
922 have_libdmalloc = False
924 libraries['dmalloc'] = conf.Finish ()
927 # Audio/MIDI library (needed for MIDI, since audio is all handled via JACK)
930 conf = Configure(env)
932 if conf.CheckCHeader('alsa/asoundlib.h'):
933 libraries['sysmidi'] = LibraryInfo (LIBS='asound')
934 env['SYSMIDI'] = 'ALSA Sequencer'
935 subst_dict['%MIDITAG%'] = "seq"
936 subst_dict['%MIDITYPE%'] = "alsa/sequencer"
937 elif conf.CheckCHeader('/System/Library/Frameworks/CoreMIDI.framework/Headers/CoreMIDI.h'):
938 # this line is needed because scons can't handle -framework in ParseConfig() yet.
940 # We need Carbon as well as the rest
941 libraries['sysmidi'] = LibraryInfo (
942 LINKFLAGS = ' -framework CoreMIDI -framework CoreFoundation -framework CoreAudio -framework CoreServices -framework AudioUnit -framework AudioToolbox -framework Carbon -bind_at_load' )
944 libraries['sysmidi'] = LibraryInfo (
945 LINKFLAGS = ' -framework CoreMIDI -framework CoreFoundation -framework CoreAudio -framework CoreServices -framework AudioUnit -framework AudioToolbox -bind_at_load' )
946 env['SYSMIDI'] = 'CoreMIDI'
947 subst_dict['%MIDITAG%'] = "ardour"
948 subst_dict['%MIDITYPE%'] = "coremidi"
950 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."
959 'sigc++-2.0' : '2.0',
961 'libgnomecanvasmm-2.6' : '2.12.0'
964 conf = Configure(env, custom_tests = { 'CheckPKGConfig' : CheckPKGConfig,
965 'CheckPKGVersion' : CheckPKGVersion })
967 for pkg, version in syslibdeps.iteritems():
968 if not conf.CheckPKGVersion( pkg, version ):
969 print '%s >= %s not found.' %(pkg, version)
970 DependenciesRequiredMessage()
975 libraries['sigc2'] = LibraryInfo()
976 libraries['sigc2'].ParseConfig('pkg-config --cflags --libs sigc++-2.0')
977 libraries['glibmm2'] = LibraryInfo()
978 libraries['glibmm2'].ParseConfig('pkg-config --cflags --libs glibmm-2.4')
979 libraries['cairomm'] = LibraryInfo()
980 libraries['cairomm'].ParseConfig('pkg-config --cflags --libs cairomm-1.0')
981 libraries['gdkmm2'] = LibraryInfo()
982 libraries['gdkmm2'].ParseConfig ('pkg-config --cflags --libs gdkmm-2.4')
983 libraries['gtkmm2'] = LibraryInfo()
984 libraries['gtkmm2'].ParseConfig ('pkg-config --cflags --libs gtkmm-2.4')
985 libraries['atkmm'] = LibraryInfo()
986 libraries['atkmm'].ParseConfig ('pkg-config --cflags --libs atkmm-1.6')
987 libraries['pangomm'] = LibraryInfo()
988 libraries['pangomm'].ParseConfig ('pkg-config --cflags --libs pangomm-1.4')
989 libraries['libgnomecanvasmm'] = LibraryInfo()
990 libraries['libgnomecanvasmm'].ParseConfig ('pkg-config --cflags --libs libgnomecanvasmm-2.6')
993 # cannot use system one for the time being
996 libraries['sndfile-ardour'] = LibraryInfo(LIBS='libsndfile-ardour',
997 LIBPATH='#libs/libsndfile',
998 CPPPATH=['#libs/libsndfile/src'])
1000 # libraries['libglademm'] = LibraryInfo()
1001 # libraries['libglademm'].ParseConfig ('pkg-config --cflags --libs libglademm-2.4')
1003 # libraries['flowcanvas'] = LibraryInfo(LIBS='flowcanvas', LIBPATH='#/libs/flowcanvas', CPPPATH='#libs/flowcanvas')
1004 libraries['soundtouch'] = LibraryInfo()
1005 #libraries['soundtouch'].ParseConfig ('pkg-config --cflags --libs soundtouch-1.0')
1006 # Comment the previous line and uncomment this for Debian:
1007 libraries['soundtouch'].ParseConfig ('pkg-config --cflags --libs libSoundTouch')
1009 libraries['appleutility'] = LibraryInfo(LIBS='libappleutility',
1010 LIBPATH='#libs/appleutility',
1011 CPPPATH='#libs/appleutility')
1023 'libs/vamp-plugins/',
1024 # these are unconditionally included but have
1025 # tests internally to avoid compilation etc
1029 # this is unconditionally included but has
1030 # tests internally to avoid compilation etc
1031 # if COREAUDIO is not set
1036 # 'libs/flowcanvas',
1043 libraries['sigc2'] = LibraryInfo(LIBS='sigc++2',
1044 LIBPATH='#libs/sigc++2',
1045 CPPPATH='#libs/sigc++2')
1046 libraries['glibmm2'] = LibraryInfo(LIBS='glibmm2',
1047 LIBPATH='#libs/glibmm2',
1048 CPPPATH='#libs/glibmm2')
1049 libraries['pangomm'] = LibraryInfo(LIBS='pangomm',
1050 LIBPATH='#libs/gtkmm2/pango',
1051 CPPPATH='#libs/gtkmm2/pango')
1052 libraries['atkmm'] = LibraryInfo(LIBS='atkmm',
1053 LIBPATH='#libs/gtkmm2/atk',
1054 CPPPATH='#libs/gtkmm2/atk')
1055 libraries['gdkmm2'] = LibraryInfo(LIBS='gdkmm2',
1056 LIBPATH='#libs/gtkmm2/gdk',
1057 CPPPATH='#libs/gtkmm2/gdk')
1058 libraries['gtkmm2'] = LibraryInfo(LIBS='gtkmm2',
1059 LIBPATH="#libs/gtkmm2/gtk",
1060 CPPPATH='#libs/gtkmm2/gtk/')
1061 libraries['libgnomecanvasmm'] = LibraryInfo(LIBS='libgnomecanvasmm',
1062 LIBPATH='#libs/libgnomecanvasmm',
1063 CPPPATH='#libs/libgnomecanvasmm')
1065 libraries['soundtouch'] = LibraryInfo(LIBS='soundtouch',
1066 LIBPATH='#libs/soundtouch',
1067 CPPPATH=['#libs', '#libs/soundtouch'])
1068 libraries['sndfile-ardour'] = LibraryInfo(LIBS='libsndfile-ardour',
1069 LIBPATH='#libs/libsndfile',
1070 CPPPATH=['#libs/libsndfile', '#libs/libsndfile/src'])
1071 # libraries['libglademm'] = LibraryInfo(LIBS='libglademm',
1072 # LIBPATH='#libs/libglademm',
1073 # CPPPATH='#libs/libglademm')
1074 libraries['appleutility'] = LibraryInfo(LIBS='libappleutility',
1075 LIBPATH='#libs/appleutility',
1076 CPPPATH='#libs/appleutility')
1089 'libs/vamp-plugins/',
1090 # these are unconditionally included but have
1091 # tests internally to avoid compilation etc
1095 # this is unconditionally included but has
1096 # tests internally to avoid compilation etc
1097 # if COREAUDIO is not set
1103 'libs/gtkmm2/pango',
1107 'libs/libgnomecanvasmm',
1114 # * always build the LGPL control protocol lib, since we link against it from libardour
1115 # * ditto for generic MIDI
1116 # * tranzport checks whether it should build internally, but we need here so that
1117 # its included in the tarball
1120 surface_subdirs = [ 'libs/surfaces/control_protocol',
1121 'libs/surfaces/generic_midi',
1122 'libs/surfaces/tranzport',
1123 'libs/surfaces/mackie',
1124 'libs/surfaces/powermate'
1129 env['TRANZPORT'] = 1
1131 env['TRANZPORT'] = 0
1132 print 'Disabled building Tranzport code because libusb could not be found'
1134 if have_linux_input:
1135 env['POWERMATE'] = 1
1137 env['POWERMATE'] = 0
1138 print 'Disabled building Powermate code because linux/input.h could not be found'
1140 if os.access ('libs/surfaces/sony9pin', os.F_OK):
1141 surface_subdirs += [ 'libs/surfaces/sony9pin' ]
1143 env['POWERMATE'] = 0
1144 env['TRANZPORT'] = 0
1147 # timestretch libraries
1150 timefx_subdirs = ['libs/soundtouch']
1151 if env['RUBBERBAND']:
1152 timefx_subdirs += ['libs/rubberband']
1154 opts.Save('scache.conf', env)
1155 Help(opts.GenerateHelpText(env))
1157 final_prefix = '$PREFIX'
1160 install_prefix = '$DESTDIR/$PREFIX'
1162 install_prefix = env['PREFIX']
1164 subst_dict['%INSTALL_PREFIX%'] = install_prefix;
1165 subst_dict['%FINAL_PREFIX%'] = final_prefix;
1166 subst_dict['%PREFIX%'] = final_prefix;
1168 if env['PREFIX'] == '/usr':
1169 final_config_prefix = '/etc'
1171 final_config_prefix = env['PREFIX'] + '/etc'
1173 config_prefix = '$DESTDIR' + final_config_prefix
1176 # everybody needs this
1179 env.Merge ([ libraries['core'] ])
1186 conf = Configure (env)
1188 nls_error = 'This system is not configured for internationalized applications. An english-only version will be built:'
1189 print 'Checking for internationalization support ...'
1190 have_gettext = conf.TryAction(Action('xgettext --version'))
1191 if have_gettext[0] != 1:
1192 nls_error += ' No xgettext command.'
1195 print "Found xgettext"
1197 have_msgmerge = conf.TryAction(Action('msgmerge --version'))
1198 if have_msgmerge[0] != 1:
1199 nls_error += ' No msgmerge command.'
1202 print "Found msgmerge"
1204 if not conf.CheckCHeader('libintl.h'):
1205 nls_error += ' No libintl.h.'
1211 print "International version will be built."
1215 env.Append(CCFLAGS="-DENABLE_NLS")
1217 Export('env install_prefix final_prefix config_prefix final_config_prefix libraries i18n ardour_version subst_dict use_flac')
1220 # the configuration file may be system dependent
1223 conf = env.Configure ()
1225 if conf.CheckCHeader('/System/Library/Frameworks/CoreAudio.framework/Versions/A/Headers/CoreAudio.h'):
1226 subst_dict['%JACK_INPUT%'] = "coreaudio:Built-in Audio:in"
1227 subst_dict['%JACK_OUTPUT%'] = "coreaudio:Built-in Audio:out"
1229 subst_dict['%JACK_INPUT%'] = "alsa_pcm:playback_"
1230 subst_dict['%JACK_OUTPUT%'] = "alsa_pcm:capture_"
1232 # posix_memalign available
1233 if not conf.CheckFunc('posix_memalign'):
1234 print 'Did not find posix_memalign(), using malloc'
1235 env.Append(CCFLAGS='-DNO_POSIX_MEMALIGN')
1240 # generate the per-user and system rc files from the same source
1242 sysrcbuild = env.SubstInFile ('ardour_system.rc','ardour.rc.in', SUBST_DICT = subst_dict)
1244 # add to the substitution dictionary
1246 subst_dict['%VERSION%'] = ardour_version[0:3]
1247 subst_dict['%EXTRA_VERSION%'] = ardour_version[3:]
1248 subst_dict['%REVISION_STRING%'] = ''
1249 if os.path.exists('.svn'):
1250 subst_dict['%REVISION_STRING%'] = '.' + fetch_svn_revision ('.') + 'svn'
1252 # specbuild = env.SubstInFile ('ardour.spec','ardour.spec.in', SUBST_DICT = subst_dict)
1254 the_revision = env.Command ('frobnicatory_decoy', [], create_stored_revision)
1255 remove_ardour = env.Command ('frobnicatory_decoy2', [],
1256 [ Delete ('$PREFIX/etc/ardour2'),
1257 Delete ('$PREFIX/lib/ardour2'),
1258 Delete ('$PREFIX/bin/ardour2')])
1260 env.Alias('revision', the_revision)
1261 env.Alias('install', env.Install(os.path.join(config_prefix, 'ardour2'), 'ardour_system.rc'))
1262 env.Alias('uninstall', remove_ardour)
1264 Default (sysrcbuild)
1268 Precious (env['DISTTREE'])
1270 env.Distribute (env['DISTTREE'],
1271 [ 'SConstruct', 'svn_revision.h',
1272 'COPYING', 'PACKAGER_README', 'README',
1274 'tools/config.guess',
1275 'icons/icon/ardour_icon_mac_mask.png',
1276 'icons/icon/ardour_icon_mac.png',
1277 'icons/icon/ardour_icon_tango_16px_blue.png',
1278 'icons/icon/ardour_icon_tango_16px_red.png',
1279 'icons/icon/ardour_icon_tango_22px_blue.png',
1280 'icons/icon/ardour_icon_tango_22px_red.png',
1281 'icons/icon/ardour_icon_tango_32px_blue.png',
1282 'icons/icon/ardour_icon_tango_32px_red.png',
1283 'icons/icon/ardour_icon_tango_48px_blue.png',
1284 'icons/icon/ardour_icon_tango_48px_red.png'
1286 glob.glob ('DOCUMENTATION/AUTHORS*') +
1287 glob.glob ('DOCUMENTATION/CONTRIBUTORS*') +
1288 glob.glob ('DOCUMENTATION/TRANSLATORS*') +
1289 glob.glob ('DOCUMENTATION/BUILD*') +
1290 glob.glob ('DOCUMENTATION/FAQ*') +
1291 glob.glob ('DOCUMENTATION/README*')
1294 srcdist = env.Tarball(env['TARBALL'], [ env['DISTTREE'], the_revision ])
1295 env.Alias ('srctar', srcdist)
1298 # don't leave the distree around
1301 env.AddPreAction (env['DISTTREE'], Action ('rm -rf ' + str (File (env['DISTTREE']))))
1302 env.AddPostAction (srcdist, Action ('rm -rf ' + str (File (env['DISTTREE']))))
1308 for subdir in coredirs:
1309 SConscript (subdir + '/SConscript')
1311 for sublistdir in [ subdirs, timefx_subdirs, gtk_subdirs, surface_subdirs ]:
1312 for subdir in sublistdir:
1313 SConscript (subdir + '/SConscript')
1316 env.Clean ('scrub', [ 'scache.conf', '.sconf_temp', '.sconsign.dblite', 'config.log'])