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['freetype2'] = LibraryInfo()
566 libraries['freetype2'].ParseConfig ('pkg-config --cflags --libs freetype2')
568 libraries['gtk2'] = LibraryInfo()
569 libraries['gtk2'].ParseConfig ('pkg-config --cflags --libs gtk+-2.0')
571 libraries['pango'] = LibraryInfo()
572 libraries['pango'].ParseConfig ('pkg-config --cflags --libs pango')
574 libraries['libgnomecanvas2'] = LibraryInfo()
575 libraries['libgnomecanvas2'].ParseConfig ('pkg-config --cflags --libs libgnomecanvas-2.0')
577 #libraries['flowcanvas'] = LibraryInfo(LIBS='flowcanvas', LIBPATH='#/libs/flowcanvas', CPPPATH='#libs/flowcanvas')
579 # The Ardour Control Protocol Library
581 libraries['ardour_cp'] = LibraryInfo (LIBS='ardour_cp', LIBPATH='#libs/surfaces/control_protocol',
582 CPPPATH='#libs/surfaces/control_protocol')
584 # The Ardour backend/engine
586 libraries['ardour'] = LibraryInfo (LIBS='ardour', LIBPATH='#libs/ardour', CPPPATH='#libs/ardour')
587 libraries['midi++2'] = LibraryInfo (LIBS='midi++', LIBPATH='#libs/midi++2', CPPPATH='#libs/midi++2')
588 libraries['pbd'] = LibraryInfo (LIBS='pbd', LIBPATH='#libs/pbd', CPPPATH='#libs/pbd')
589 libraries['gtkmm2ext'] = LibraryInfo (LIBS='gtkmm2ext', LIBPATH='#libs/gtkmm2ext', CPPPATH='#libs/gtkmm2ext')
592 # SCons should really do this for us
594 conf = env.Configure ()
596 have_cxx = conf.TryAction (Action (str(env['CXX']) + ' --version'))
598 print "This system has no functional C++ compiler. You cannot build Ardour from source without one."
601 print "Congratulations, you have a functioning C++ compiler."
607 # Compiler flags and other system-dependent stuff
611 if env['GPROFILE'] == 1:
612 debug_flags = [ '-g', '-pg' ]
614 debug_flags = [ '-g' ]
616 # guess at the platform, used to define compiler flags
618 config_guess = os.popen("tools/config.guess").read()[:-1]
624 config = config_guess.split ("-")
626 print "system triple: " + config_guess
629 if env['DIST_TARGET'] == 'auto':
630 if config[config_arch] == 'apple':
631 # The [.] matches to the dot after the major version, "." would match any character
632 if re.search ("darwin[0-7][.]", config[config_kernel]) != None:
633 env['DIST_TARGET'] = 'panther'
634 if re.search ("darwin8[.]", config[config_kernel]) != None:
635 env['DIST_TARGET'] = 'tiger'
637 env['DIST_TARGET'] = 'leopard'
639 if re.search ("x86_64", config[config_cpu]) != None:
640 env['DIST_TARGET'] = 'x86_64'
641 elif re.search("i[0-5]86", config[config_cpu]) != None:
642 env['DIST_TARGET'] = 'i386'
643 elif re.search("powerpc", config[config_cpu]) != None:
644 env['DIST_TARGET'] = 'powerpc'
646 env['DIST_TARGET'] = 'i686'
647 print "\n*******************************"
648 print "detected DIST_TARGET = " + env['DIST_TARGET']
649 print "*******************************\n"
652 if config[config_cpu] == 'powerpc' and env['DIST_TARGET'] != 'none':
654 # Apple/PowerPC optimization options
656 # -mcpu=7450 does not reliably work with gcc 3.*
658 if env['DIST_TARGET'] == 'panther' or env['DIST_TARGET'] == 'tiger':
659 if config[config_arch] == 'apple':
660 ## opt_flags.extend ([ "-mcpu=7450", "-faltivec"])
661 # to support g3s but still have some optimization for above
662 opt_flags.extend ([ "-mcpu=G3", "-mtune=7450"])
664 opt_flags.extend ([ "-mcpu=7400", "-maltivec", "-mabi=altivec"])
666 opt_flags.extend([ "-mcpu=750", "-mmultiple" ])
667 opt_flags.extend (["-mhard-float", "-mpowerpc-gfxopt"])
668 opt_flags.extend (["-Os"])
670 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':
672 build_host_supports_sse = 0
674 debug_flags.append ("-DARCH_X86")
675 opt_flags.append ("-DARCH_X86")
677 if config[config_kernel] == 'linux' :
679 if env['DIST_TARGET'] != 'i386':
681 flag_line = os.popen ("cat /proc/cpuinfo | grep '^flags'").read()[:-1]
682 x86_flags = flag_line.split (": ")[1:][0].split ()
684 if "mmx" in x86_flags:
685 opt_flags.append ("-mmmx")
686 if "sse" in x86_flags:
687 build_host_supports_sse = 1
688 if "3dnow" in x86_flags:
689 opt_flags.append ("-m3dnow")
691 if config[config_cpu] == "i586":
692 opt_flags.append ("-march=i586")
693 elif config[config_cpu] == "i686":
694 opt_flags.append ("-march=i686")
696 if ((env['DIST_TARGET'] == 'i686') or (env['DIST_TARGET'] == 'x86_64')) and build_host_supports_sse:
697 opt_flags.extend (["-msse", "-mfpmath=sse", "-DUSE_XMMINTRIN"])
698 debug_flags.extend (["-msse", "-mfpmath=sse", "-DUSE_XMMINTRIN"])
699 # end of processor-specific section
701 # optimization section
702 if env['FPU_OPTIMIZATION']:
703 if env['DIST_TARGET'] == 'tiger' or env['DIST_TARGET'] == 'leopard':
704 opt_flags.append ("-DBUILD_VECLIB_OPTIMIZATIONS");
705 debug_flags.append ("-DBUILD_VECLIB_OPTIMIZATIONS");
706 libraries['core'].Append(LINKFLAGS= '-framework Accelerate')
707 elif env['DIST_TARGET'] == 'i686' or env['DIST_TARGET'] == 'x86_64':
708 opt_flags.append ("-DBUILD_SSE_OPTIMIZATIONS")
709 debug_flags.append ("-DBUILD_SSE_OPTIMIZATIONS")
710 if env['DIST_TARGET'] == 'x86_64':
711 opt_flags.append ("-DUSE_X86_64_ASM")
712 debug_flags.append ("-DUSE_X86_64_ASM")
713 if build_host_supports_sse != 1:
714 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)"
715 # end optimization section
717 # handle x86/x86_64 libdir properly
719 if env['DIST_TARGET'] == 'x86_64':
720 env['LIBDIR']='lib64'
725 # a single way to test if we're on OS X
728 if env['DIST_TARGET'] in ['panther', 'tiger', 'leopard' ]:
730 # force tiger or later, to avoid issues on PPC which defaults
731 # back to 10.1 if we don't tell it otherwise.
732 env.Append (CCFLAGS="-DMAC_OS_X_VERSION_MIN_REQUIRED=1040")
737 # save off guessed arch element in an env
739 env.Append(CONFIG_ARCH=config[config_arch])
743 # ARCH="..." overrides all
746 if env['ARCH'] != '':
747 opt_flags = env['ARCH'].split()
750 # prepend boiler plate optimization flags
755 "-fomit-frame-pointer",
761 if env['DEBUG'] == 1:
762 env.Append(CCFLAGS=" ".join (debug_flags))
763 env.Append(LINKFLAGS=" ".join (debug_flags))
765 env.Append(CCFLAGS=" ".join (opt_flags))
766 env.Append(LINKFLAGS=" ".join (opt_flags))
768 if env['UNIVERSAL'] == 1:
769 env.Append(CCFLAGS="-arch i386 -arch ppc")
770 env.Append(LINKFLAGS="-arch i386 -arch ppc")
776 env.Append(CCFLAGS="-Wall")
777 env.Append(CXXFLAGS="-Woverloaded-virtual")
779 if env['EXTRA_WARN']:
780 env.Append(CCFLAGS="-Wextra -pedantic -ansi")
781 env.Append(CXXFLAGS="-ansi")
782 # env.Append(CFLAGS="-iso")
785 env.Append(CCFLAGS="-DHAVE_LIBLO")
789 # fix scons nitpickiness on APPLE
793 def prep_libcheck(topenv, libinfo):
796 # rationale: GTK-Quartz uses jhbuild and installs to /opt/gtk by default.
797 # All libraries needed should be built against this location
799 libinfo.Append(CPPPATH="/opt/gtk/include", LIBPATH="/opt/gtk/lib")
800 libinfo.Append(CXXFLAGS="-I/opt/gtk/include", LINKFLAGS="-L/opt/gtk/lib")
801 libinfo.Append(CPPPATH="/opt/local/include", LIBPATH="/opt/local/lib")
802 libinfo.Append(CXXFLAGS="-I/opt/local/include", LINKFLAGS="-L/opt/local/lib")
804 prep_libcheck(env, env)
808 # these are part of the Ardour source tree because they are C++
811 libraries['vamp'] = LibraryInfo (LIBS='vampsdk',
812 LIBPATH='#libs/vamp-sdk',
813 CPPPATH='#libs/vamp-sdk')
814 libraries['vamphost'] = LibraryInfo (LIBS='vamphostsdk',
815 LIBPATH='#libs/vamp-sdk',
816 CPPPATH='#libs/vamp-sdk')
818 env['RUBBERBAND'] = False
820 conf = Configure (env)
822 if conf.CheckHeader ('fftw3.h'):
823 env['RUBBERBAND'] = True
824 libraries['rubberband'] = LibraryInfo (LIBS='rubberband',
825 LIBPATH='#libs/rubberband',
826 CPPPATH='#libs/rubberband',
827 CCFLAGS='-DUSE_RUBBERBAND')
830 print "-------------------------------------------------------------------------"
831 print "You do not have the FFTW single-precision development package installed."
832 print "This prevents Ardour from using the Rubberband library for timestretching"
833 print "and pitchshifting. It will fall back on SoundTouch for timestretch, and "
834 print "pitchshifting will not be available."
835 print "-------------------------------------------------------------------------"
843 libraries['usb'] = LibraryInfo ()
844 prep_libcheck(env, libraries['usb'])
846 conf = Configure (libraries['usb'])
847 if conf.CheckLib ('usb', 'usb_interrupt_write'):
852 # check for linux/input.h while we're at it for powermate
853 if conf.CheckHeader('linux/input.h'):
854 have_linux_input = True
856 have_linux_input = False
858 libraries['usb'] = conf.Finish ()
863 libraries['flac'] = LibraryInfo ()
864 prep_libcheck(env, libraries['flac'])
865 libraries['flac'].Append(CPPPATH="/usr/local/include", LIBPATH="/usr/local/lib")
868 # june 1st 2007: look for a function that is in FLAC 1.1.2 and not in later versions
869 # since the version of libsndfile we have internally does not support
870 # the new API that libFLAC has adopted
873 conf = Configure (libraries['flac'])
874 if conf.CheckLib ('FLAC', 'FLAC__seekable_stream_decoder_init', language='CXX'):
875 conf.env.Append(CCFLAGS='-DHAVE_FLAC')
880 libraries['flac'] = conf.Finish ()
882 # or if that fails...
883 #libraries['flac'] = LibraryInfo (LIBS='FLAC')
885 # boost (we don't link against boost, just use some header files)
887 libraries['boost'] = LibraryInfo ()
888 prep_libcheck(env, libraries['boost'])
889 libraries['boost'].Append(CPPPATH="/usr/local/include", LIBPATH="/usr/local/lib")
890 conf = Configure (libraries['boost'])
891 if conf.CheckHeader ('boost/shared_ptr.hpp', language='CXX') == False:
892 print "Boost header files do not appear to be installed."
895 libraries['boost'] = conf.Finish ()
901 libraries['lo'] = LibraryInfo ()
902 prep_libcheck(env, libraries['lo'])
904 conf = Configure (libraries['lo'])
905 if conf.CheckLib ('lo', 'lo_server_new') == False:
906 print "liblo does not appear to be installed."
909 libraries['lo'] = conf.Finish ()
914 libraries['dmalloc'] = LibraryInfo ()
915 prep_libcheck(env, libraries['dmalloc'])
918 # look for the threaded version
921 conf = Configure (libraries['dmalloc'])
922 if conf.CheckLib ('dmallocth', 'dmalloc_shutdown'):
923 have_libdmalloc = True
925 have_libdmalloc = False
927 libraries['dmalloc'] = conf.Finish ()
930 # Audio/MIDI library (needed for MIDI, since audio is all handled via JACK)
933 conf = Configure(env)
935 if conf.CheckCHeader('alsa/asoundlib.h'):
936 libraries['sysmidi'] = LibraryInfo (LIBS='asound')
937 env['SYSMIDI'] = 'ALSA Sequencer'
938 subst_dict['%MIDITAG%'] = "seq"
939 subst_dict['%MIDITYPE%'] = "alsa/sequencer"
940 elif conf.CheckCHeader('/System/Library/Frameworks/CoreMIDI.framework/Headers/CoreMIDI.h'):
941 # this line is needed because scons can't handle -framework in ParseConfig() yet.
943 # We need Carbon as well as the rest
944 libraries['sysmidi'] = LibraryInfo (
945 LINKFLAGS = ' -framework CoreMIDI -framework CoreFoundation -framework CoreAudio -framework CoreServices -framework AudioUnit -framework AudioToolbox -framework Carbon -bind_at_load' )
947 libraries['sysmidi'] = LibraryInfo (
948 LINKFLAGS = ' -framework CoreMIDI -framework CoreFoundation -framework CoreAudio -framework CoreServices -framework AudioUnit -framework AudioToolbox -bind_at_load' )
949 env['SYSMIDI'] = 'CoreMIDI'
950 subst_dict['%MIDITAG%'] = "ardour"
951 subst_dict['%MIDITYPE%'] = "coremidi"
953 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."
962 'sigc++-2.0' : '2.0',
964 'libgnomecanvasmm-2.6' : '2.12.0'
967 conf = Configure(env, custom_tests = { 'CheckPKGConfig' : CheckPKGConfig,
968 'CheckPKGVersion' : CheckPKGVersion })
970 for pkg, version in syslibdeps.iteritems():
971 if not conf.CheckPKGVersion( pkg, version ):
972 print '%s >= %s not found.' %(pkg, version)
973 DependenciesRequiredMessage()
978 libraries['sigc2'] = LibraryInfo()
979 libraries['sigc2'].ParseConfig('pkg-config --cflags --libs sigc++-2.0')
980 libraries['glibmm2'] = LibraryInfo()
981 libraries['glibmm2'].ParseConfig('pkg-config --cflags --libs glibmm-2.4')
982 libraries['cairomm'] = LibraryInfo()
983 libraries['cairomm'].ParseConfig('pkg-config --cflags --libs cairomm-1.0')
984 libraries['gdkmm2'] = LibraryInfo()
985 libraries['gdkmm2'].ParseConfig ('pkg-config --cflags --libs gdkmm-2.4')
986 libraries['gtkmm2'] = LibraryInfo()
987 libraries['gtkmm2'].ParseConfig ('pkg-config --cflags --libs gtkmm-2.4')
988 libraries['atkmm'] = LibraryInfo()
989 libraries['atkmm'].ParseConfig ('pkg-config --cflags --libs atkmm-1.6')
990 libraries['pangomm'] = LibraryInfo()
991 libraries['pangomm'].ParseConfig ('pkg-config --cflags --libs pangomm-1.4')
992 libraries['libgnomecanvasmm'] = LibraryInfo()
993 libraries['libgnomecanvasmm'].ParseConfig ('pkg-config --cflags --libs libgnomecanvasmm-2.6')
996 # cannot use system one for the time being
999 libraries['sndfile-ardour'] = LibraryInfo(LIBS='libsndfile-ardour',
1000 LIBPATH='#libs/libsndfile',
1001 CPPPATH=['#libs/libsndfile/src'])
1003 # libraries['libglademm'] = LibraryInfo()
1004 # libraries['libglademm'].ParseConfig ('pkg-config --cflags --libs libglademm-2.4')
1006 # libraries['flowcanvas'] = LibraryInfo(LIBS='flowcanvas', LIBPATH='#/libs/flowcanvas', CPPPATH='#libs/flowcanvas')
1007 libraries['soundtouch'] = LibraryInfo()
1008 #libraries['soundtouch'].ParseConfig ('pkg-config --cflags --libs soundtouch-1.0')
1009 # Comment the previous line and uncomment this for Debian:
1010 libraries['soundtouch'].ParseConfig ('pkg-config --cflags --libs libSoundTouch')
1012 libraries['appleutility'] = LibraryInfo(LIBS='libappleutility',
1013 LIBPATH='#libs/appleutility',
1014 CPPPATH='#libs/appleutility')
1026 'libs/vamp-plugins/',
1027 # these are unconditionally included but have
1028 # tests internally to avoid compilation etc
1032 # this is unconditionally included but has
1033 # tests internally to avoid compilation etc
1034 # if COREAUDIO is not set
1039 # 'libs/flowcanvas',
1046 libraries['sigc2'] = LibraryInfo(LIBS='sigc++2',
1047 LIBPATH='#libs/sigc++2',
1048 CPPPATH='#libs/sigc++2')
1049 libraries['glibmm2'] = LibraryInfo(LIBS='glibmm2',
1050 LIBPATH='#libs/glibmm2',
1051 CPPPATH='#libs/glibmm2')
1052 libraries['pangomm'] = LibraryInfo(LIBS='pangomm',
1053 LIBPATH='#libs/gtkmm2/pango',
1054 CPPPATH='#libs/gtkmm2/pango')
1055 libraries['atkmm'] = LibraryInfo(LIBS='atkmm',
1056 LIBPATH='#libs/gtkmm2/atk',
1057 CPPPATH='#libs/gtkmm2/atk')
1058 libraries['gdkmm2'] = LibraryInfo(LIBS='gdkmm2',
1059 LIBPATH='#libs/gtkmm2/gdk',
1060 CPPPATH='#libs/gtkmm2/gdk')
1061 libraries['gtkmm2'] = LibraryInfo(LIBS='gtkmm2',
1062 LIBPATH="#libs/gtkmm2/gtk",
1063 CPPPATH='#libs/gtkmm2/gtk/')
1064 libraries['libgnomecanvasmm'] = LibraryInfo(LIBS='libgnomecanvasmm',
1065 LIBPATH='#libs/libgnomecanvasmm',
1066 CPPPATH='#libs/libgnomecanvasmm')
1068 libraries['soundtouch'] = LibraryInfo(LIBS='soundtouch',
1069 LIBPATH='#libs/soundtouch',
1070 CPPPATH=['#libs', '#libs/soundtouch'])
1071 libraries['sndfile-ardour'] = LibraryInfo(LIBS='libsndfile-ardour',
1072 LIBPATH='#libs/libsndfile',
1073 CPPPATH=['#libs/libsndfile', '#libs/libsndfile/src'])
1074 # libraries['libglademm'] = LibraryInfo(LIBS='libglademm',
1075 # LIBPATH='#libs/libglademm',
1076 # CPPPATH='#libs/libglademm')
1077 libraries['appleutility'] = LibraryInfo(LIBS='libappleutility',
1078 LIBPATH='#libs/appleutility',
1079 CPPPATH='#libs/appleutility')
1092 'libs/vamp-plugins/',
1093 # these are unconditionally included but have
1094 # tests internally to avoid compilation etc
1098 # this is unconditionally included but has
1099 # tests internally to avoid compilation etc
1100 # if COREAUDIO is not set
1106 'libs/gtkmm2/pango',
1110 'libs/libgnomecanvasmm',
1117 # * always build the LGPL control protocol lib, since we link against it from libardour
1118 # * ditto for generic MIDI
1119 # * tranzport checks whether it should build internally, but we need here so that
1120 # its included in the tarball
1123 surface_subdirs = [ 'libs/surfaces/control_protocol',
1124 'libs/surfaces/generic_midi',
1125 'libs/surfaces/tranzport',
1126 'libs/surfaces/mackie',
1127 'libs/surfaces/powermate'
1132 env['TRANZPORT'] = 1
1134 env['TRANZPORT'] = 0
1135 print 'Disabled building Tranzport code because libusb could not be found'
1137 if have_linux_input:
1138 env['POWERMATE'] = 1
1140 env['POWERMATE'] = 0
1141 print 'Disabled building Powermate code because linux/input.h could not be found'
1143 if os.access ('libs/surfaces/sony9pin', os.F_OK):
1144 surface_subdirs += [ 'libs/surfaces/sony9pin' ]
1146 env['POWERMATE'] = 0
1147 env['TRANZPORT'] = 0
1150 # timestretch libraries
1153 timefx_subdirs = ['libs/soundtouch']
1154 if env['RUBBERBAND']:
1155 timefx_subdirs += ['libs/rubberband']
1157 opts.Save('scache.conf', env)
1158 Help(opts.GenerateHelpText(env))
1160 final_prefix = '$PREFIX'
1163 install_prefix = '$DESTDIR/$PREFIX'
1165 install_prefix = env['PREFIX']
1167 subst_dict['%INSTALL_PREFIX%'] = install_prefix;
1168 subst_dict['%FINAL_PREFIX%'] = final_prefix;
1169 subst_dict['%PREFIX%'] = final_prefix;
1171 if env['PREFIX'] == '/usr':
1172 final_config_prefix = '/etc'
1174 final_config_prefix = env['PREFIX'] + '/etc'
1176 config_prefix = '$DESTDIR' + final_config_prefix
1179 # everybody needs this
1182 env.Merge ([ libraries['core'] ])
1189 conf = Configure (env)
1191 nls_error = 'This system is not configured for internationalized applications. An english-only version will be built:'
1192 print 'Checking for internationalization support ...'
1193 have_gettext = conf.TryAction(Action('xgettext --version'))
1194 if have_gettext[0] != 1:
1195 nls_error += ' No xgettext command.'
1198 print "Found xgettext"
1200 have_msgmerge = conf.TryAction(Action('msgmerge --version'))
1201 if have_msgmerge[0] != 1:
1202 nls_error += ' No msgmerge command.'
1205 print "Found msgmerge"
1207 if not conf.CheckCHeader('libintl.h'):
1208 nls_error += ' No libintl.h.'
1214 print "International version will be built."
1218 env.Append(CCFLAGS="-DENABLE_NLS")
1220 Export('env install_prefix final_prefix config_prefix final_config_prefix libraries i18n ardour_version subst_dict use_flac')
1223 # the configuration file may be system dependent
1226 conf = env.Configure ()
1228 if conf.CheckCHeader('/System/Library/Frameworks/CoreAudio.framework/Versions/A/Headers/CoreAudio.h'):
1229 subst_dict['%JACK_INPUT%'] = "coreaudio:Built-in Audio:in"
1230 subst_dict['%JACK_OUTPUT%'] = "coreaudio:Built-in Audio:out"
1232 subst_dict['%JACK_INPUT%'] = "alsa_pcm:playback_"
1233 subst_dict['%JACK_OUTPUT%'] = "alsa_pcm:capture_"
1235 # posix_memalign available
1236 if not conf.CheckFunc('posix_memalign'):
1237 print 'Did not find posix_memalign(), using malloc'
1238 env.Append(CCFLAGS='-DNO_POSIX_MEMALIGN')
1243 # generate the per-user and system rc files from the same source
1245 sysrcbuild = env.SubstInFile ('ardour_system.rc','ardour.rc.in', SUBST_DICT = subst_dict)
1247 # add to the substitution dictionary
1249 subst_dict['%VERSION%'] = ardour_version[0:3]
1250 subst_dict['%EXTRA_VERSION%'] = ardour_version[3:]
1251 subst_dict['%REVISION_STRING%'] = ''
1252 if os.path.exists('.svn'):
1253 subst_dict['%REVISION_STRING%'] = '.' + fetch_svn_revision ('.') + 'svn'
1255 # specbuild = env.SubstInFile ('ardour.spec','ardour.spec.in', SUBST_DICT = subst_dict)
1257 the_revision = env.Command ('frobnicatory_decoy', [], create_stored_revision)
1258 remove_ardour = env.Command ('frobnicatory_decoy2', [],
1259 [ Delete ('$PREFIX/etc/ardour2'),
1260 Delete ('$PREFIX/lib/ardour2'),
1261 Delete ('$PREFIX/bin/ardour2')])
1263 env.Alias('revision', the_revision)
1264 env.Alias('install', env.Install(os.path.join(config_prefix, 'ardour2'), 'ardour_system.rc'))
1265 env.Alias('uninstall', remove_ardour)
1267 Default (sysrcbuild)
1271 Precious (env['DISTTREE'])
1273 env.Distribute (env['DISTTREE'],
1274 [ 'SConstruct', 'svn_revision.h',
1275 'COPYING', 'PACKAGER_README', 'README',
1277 'tools/config.guess',
1278 'icons/icon/ardour_icon_mac_mask.png',
1279 'icons/icon/ardour_icon_mac.png',
1280 'icons/icon/ardour_icon_tango_16px_blue.png',
1281 'icons/icon/ardour_icon_tango_16px_red.png',
1282 'icons/icon/ardour_icon_tango_22px_blue.png',
1283 'icons/icon/ardour_icon_tango_22px_red.png',
1284 'icons/icon/ardour_icon_tango_32px_blue.png',
1285 'icons/icon/ardour_icon_tango_32px_red.png',
1286 'icons/icon/ardour_icon_tango_48px_blue.png',
1287 'icons/icon/ardour_icon_tango_48px_red.png'
1289 glob.glob ('DOCUMENTATION/AUTHORS*') +
1290 glob.glob ('DOCUMENTATION/CONTRIBUTORS*') +
1291 glob.glob ('DOCUMENTATION/TRANSLATORS*') +
1292 glob.glob ('DOCUMENTATION/BUILD*') +
1293 glob.glob ('DOCUMENTATION/FAQ*') +
1294 glob.glob ('DOCUMENTATION/README*')
1297 srcdist = env.Tarball(env['TARBALL'], [ env['DISTTREE'], the_revision ])
1298 env.Alias ('srctar', srcdist)
1301 # don't leave the distree around
1304 env.AddPreAction (env['DISTTREE'], Action ('rm -rf ' + str (File (env['DISTTREE']))))
1305 env.AddPostAction (srcdist, Action ('rm -rf ' + str (File (env['DISTTREE']))))
1311 for subdir in coredirs:
1312 SConscript (subdir + '/SConscript')
1314 for sublistdir in [ subdirs, timefx_subdirs, gtk_subdirs, surface_subdirs ]:
1315 for subdir in sublistdir:
1316 SConscript (subdir + '/SConscript')
1319 env.Clean ('scrub', [ 'scache.conf', '.sconf_temp', '.sconsign.dblite', 'config.log'])