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('FREEDESKTOP', 'Install MIME type, icons and .desktop file as per the freedesktop.org spec (requires xdg-utils and shared-mime-info). "scons uninstall" removes associations in desktop database', 0),
54 BoolOption('TRANZPORT', 'Compile with support for Frontier Designs (if libusb is available)', 1)
57 #----------------------------------------------------------------------
58 # a handy helper that provides a way to merge compile/link information
59 # from multiple different "environments"
60 #----------------------------------------------------------------------
62 class LibraryInfo(Environment):
63 def __init__(self,*args,**kw):
64 Environment.__init__ (self,*args,**kw)
66 def Merge (self,others):
68 self.Append (LIBS = other.get ('LIBS',[]))
69 self.Append (LIBPATH = other.get ('LIBPATH', []))
70 self.Append (CPPPATH = other.get('CPPPATH', []))
71 self.Append (LINKFLAGS = other.get('LINKFLAGS', []))
72 self.Append (CCFLAGS = other.get('CCFLAGS', []))
73 self.Replace(LIBPATH = list(Set(self.get('LIBPATH', []))))
74 self.Replace(CPPPATH = list(Set(self.get('CPPPATH',[]))))
75 #doing LINKFLAGS breaks -framework
76 #doing LIBS break link order dependency
78 def ENV_update(self, src_ENV):
79 for k in src_ENV.keys():
80 if k in self['ENV'].keys() and k in [ 'PATH', 'LD_LIBRARY_PATH',
82 self['ENV'][k]=SCons.Util.AppendPath(self['ENV'][k], src_ENV[k])
84 self['ENV'][k]=src_ENV[k]
86 env = LibraryInfo (options = opts,
88 VERSION = ardour_version,
89 TARBALL='ardour-' + ardour_version + '.tar.bz2',
91 DISTTREE = '#ardour-' + ardour_version,
92 DISTCHECKDIR = '#ardour-' + ardour_version + '/check'
95 env.ENV_update(os.environ)
97 #----------------------------------------------------------------------
99 #----------------------------------------------------------------------
101 # Handy subst-in-file builder
104 def do_subst_in_file(targetfile, sourcefile, dict):
105 """Replace all instances of the keys of dict with their values.
106 For example, if dict is {'%VERSION%': '1.2345', '%BASE%': 'MyProg'},
107 then all instances of %VERSION% in the file will be replaced with 1.2345 etc.
110 f = open(sourcefile, 'rb')
114 raise SCons.Errors.UserError, "Can't read source file %s"%sourcefile
115 for (k,v) in dict.items():
116 contents = re.sub(k, v, contents)
118 f = open(targetfile, 'wb')
122 raise SCons.Errors.UserError, "Can't write target file %s"%targetfile
125 def subst_in_file(target, source, env):
126 if not env.has_key('SUBST_DICT'):
127 raise SCons.Errors.UserError, "SubstInFile requires SUBST_DICT to be set."
128 d = dict(env['SUBST_DICT']) # copy it
129 for (k,v) in d.items():
131 d[k] = env.subst(v())
132 elif SCons.Util.is_String(v):
135 raise SCons.Errors.UserError, "SubstInFile: key %s: %s must be a string or callable"%(k, repr(v))
136 for (t,s) in zip(target, source):
137 return do_subst_in_file(str(t), str(s), d)
139 def subst_in_file_string(target, source, env):
140 """This is what gets printed on the console."""
141 return '\n'.join(['Substituting vars from %s into %s'%(str(s), str(t))
142 for (t,s) in zip(target, source)])
144 def subst_emitter(target, source, env):
145 """Add dependency from substituted SUBST_DICT to target.
146 Returns original target, source tuple unchanged.
148 d = env['SUBST_DICT'].copy() # copy it
149 for (k,v) in d.items():
151 d[k] = env.subst(v())
152 elif SCons.Util.is_String(v):
154 Depends(target, SCons.Node.Python.Value(d))
155 # Depends(target, source) # this doesn't help the install-sapphire-linux.sh problem
156 return target, source
158 subst_action = Action (subst_in_file, subst_in_file_string)
159 env['BUILDERS']['SubstInFile'] = Builder(action=subst_action, emitter=subst_emitter)
162 # internationalization
165 # po_builder: builder function to copy po files to the parent directory while updating them
167 # first source: .po file
168 # second source: .pot file
171 def po_builder(target,source,env):
172 os.spawnvp (os.P_WAIT, 'cp', ['cp', str(source[0]), str(target[0])])
178 print 'Updating ' + str(target[0])
179 return os.spawnvp (os.P_WAIT, 'msgmerge', args)
181 po_bld = Builder (action = po_builder)
182 env.Append(BUILDERS = {'PoBuild' : po_bld})
184 # mo_builder: builder function for (binary) message catalogs (.mo)
186 # first source: .po file
189 def mo_builder(target,source,env):
193 target[0].get_path(),
196 return os.spawnvp (os.P_WAIT, 'msgfmt', args)
198 mo_bld = Builder (action = mo_builder)
199 env.Append(BUILDERS = {'MoBuild' : mo_bld})
201 # pot_builder: builder function for message templates (.pot)
203 # source: list of C/C++ etc. files to extract messages from
206 def pot_builder(target,source,env):
211 '-o', target[0].get_path(),
212 "--default-domain=" + env['PACKAGE'],
213 '--copyright-holder="Paul Davis"' ]
214 args += [ src.get_path() for src in source ]
216 return os.spawnvp (os.P_WAIT, 'xgettext', args)
218 pot_bld = Builder (action = pot_builder)
219 env.Append(BUILDERS = {'PotBuild' : pot_bld})
222 # utility function, not a builder
225 def i18n (buildenv, sources, installenv):
226 domain = buildenv['PACKAGE']
227 potfile = buildenv['POTFILE']
229 installenv.Alias ('potupdate', buildenv.PotBuild (potfile, sources))
231 p_oze = [ os.path.basename (po) for po in glob.glob ('po/*.po') ]
232 languages = [ po.replace ('.po', '') for po in p_oze ]
234 for po_file in p_oze:
235 buildenv.PoBuild(po_file, ['po/'+po_file, potfile])
236 mo_file = po_file.replace (".po", ".mo")
237 installenv.Alias ('install', buildenv.MoBuild (mo_file, po_file))
238 installenv.Alias ('msgupdate', buildenv.MoBuild (mo_file, po_file))
240 for lang in languages:
241 modir = (os.path.join (install_prefix, 'share/locale/' + lang + '/LC_MESSAGES/'))
242 moname = domain + '.mo'
243 installenv.Alias('install', installenv.InstallAs (os.path.join (modir, moname), lang + '.mo'))
246 def fetch_svn_revision (path):
250 cmd += " | awk '/^Revision:/ { print $2}'"
251 return commands.getoutput (cmd)
253 def create_stored_revision (target = None, source = None, env = None):
254 if os.path.exists('.svn'):
255 rev = fetch_svn_revision ('.');
257 text = "#ifndef __ardour_svn_revision_h__\n"
258 text += "#define __ardour_svn_revision_h__\n"
259 text += "static const char* ardour_svn_revision = \"" + rev + "\";\n";
261 print '============> writing svn revision info to svn_revision.h\n'
262 o = file ('svn_revision.h', 'w')
266 print "Could not open svn_revision.h for writing\n"
269 print "You cannot use \"scons revision\" on without using a checked out"
270 print "copy of the Ardour source code repository"
274 # A generic builder for version.cc files
276 # note: requires that DOMAIN, MAJOR, MINOR, MICRO are set in the construction environment
277 # note: assumes one source files, the header that declares the version variables
280 def version_builder (target, source, env):
282 text = "int " + env['DOMAIN'] + "_major_version = " + str (env['MAJOR']) + ";\n"
283 text += "int " + env['DOMAIN'] + "_minor_version = " + str (env['MINOR']) + ";\n"
284 text += "int " + env['DOMAIN'] + "_micro_version = " + str (env['MICRO']) + ";\n"
287 o = file (target[0].get_path(), 'w')
291 print "Could not open", target[0].get_path(), " for writing\n"
294 text = "#ifndef __" + env['DOMAIN'] + "_version_h__\n"
295 text += "#define __" + env['DOMAIN'] + "_version_h__\n"
296 text += "extern const char* " + env['DOMAIN'] + "_revision;\n"
297 text += "extern int " + env['DOMAIN'] + "_major_version;\n"
298 text += "extern int " + env['DOMAIN'] + "_minor_version;\n"
299 text += "extern int " + env['DOMAIN'] + "_micro_version;\n"
300 text += "#endif /* __" + env['DOMAIN'] + "_version_h__ */\n"
303 o = file (target[1].get_path(), 'w')
307 print "Could not open", target[1].get_path(), " for writing\n"
312 version_bld = Builder (action = version_builder)
313 env.Append (BUILDERS = {'VersionBuild' : version_bld})
316 # a builder that makes a hard link from the 'source' executable to a name with
317 # a "build ID" based on the most recent CVS activity that might be reasonably
318 # related to version activity. this relies on the idea that the SConscript
319 # file that builds the executable is updated with new version info and committed
320 # to the source code repository whenever things change.
323 def versioned_builder(target,source,env):
324 w, r = os.popen2( "LANG= svn info | awk '/^Revision:/ { print $2}'")
326 last_revision = r.readline().strip()
329 if last_revision == "":
330 print "No SVN info found - versioned executable cannot be built"
333 print "The current build ID is " + last_revision
335 tagged_executable = source[0].get_path() + '-' + last_revision
337 if os.path.exists (tagged_executable):
338 print "Replacing existing executable with the same build tag."
339 os.unlink (tagged_executable)
341 return os.link (source[0].get_path(), tagged_executable)
343 verbuild = Builder (action = versioned_builder)
344 env.Append (BUILDERS = {'VersionedExecutable' : verbuild})
347 # source tar file builder
350 def distcopy (target, source, env):
351 treedir = str (target[0])
355 except OSError, (errnum, strerror):
356 if errnum != errno.EEXIST:
357 print 'mkdir ', treedir, ':', strerror
361 # we don't know what characters might be in the file names
362 # so quote them all before passing them to the shell
364 all_files = ([ str(s) for s in source ])
365 cmd += " ".join ([ "'%s'" % quoted for quoted in all_files])
366 cmd += ' | (cd ' + treedir + ' && tar xf -)'
370 def tarballer (target, source, env):
371 cmd = 'tar -jcf ' + str (target[0]) + ' ' + str(source[0]) + " --exclude '*~'" + " --exclude .svn --exclude '.svn/*'"
372 print 'running ', cmd, ' ... '
376 dist_bld = Builder (action = distcopy,
377 target_factory = SCons.Node.FS.default_fs.Entry,
378 source_factory = SCons.Node.FS.default_fs.Entry,
381 tarball_bld = Builder (action = tarballer,
382 target_factory = SCons.Node.FS.default_fs.Entry,
383 source_factory = SCons.Node.FS.default_fs.Entry)
385 env.Append (BUILDERS = {'Distribute' : dist_bld})
386 env.Append (BUILDERS = {'Tarball' : tarball_bld})
389 # Make sure they know what they are doing
393 if os.path.isfile('.personal_use_only'):
394 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."
396 sys.stdout.write ("Are you building Ardour for personal use (rather than distribution to others)? [no]: ")
397 answer = sys.stdin.readline ()
398 answer = answer.rstrip().strip()
399 if answer == "yes" or answer == "y":
400 fh = open('.personal_use_only', 'w')
402 print "OK, VST support will be enabled"
404 print 'You cannot build Ardour with VST support for distribution to others.\nIt is a violation of several different licenses. Build with VST=false.'
407 if os.path.isfile('.personal_use_only'):
408 os.remove('.personal_use_only')
414 def pushEnvironment(context):
415 if os.environ.has_key('PATH'):
416 context.Append(PATH = os.environ['PATH'])
418 if os.environ.has_key('PKG_CONFIG_PATH'):
419 context.Append(PKG_CONFIG_PATH = os.environ['PKG_CONFIG_PATH'])
421 if os.environ.has_key('CC'):
422 context['CC'] = os.environ['CC']
424 if os.environ.has_key('CXX'):
425 context['CXX'] = os.environ['CXX']
427 if os.environ.has_key('DISTCC_HOSTS'):
428 context['ENV']['DISTCC_HOSTS'] = os.environ['DISTCC_HOSTS']
429 context['ENV']['HOME'] = os.environ['HOME']
431 pushEnvironment (env)
433 #######################
434 # Dependency Checking #
435 #######################
439 'glib-2.0' : '2.10.1',
440 'gthread-2.0' : '2.10.1',
441 'gtk+-2.0' : '2.8.1',
442 'libxml-2.0' : '2.6.0',
443 'samplerate' : '0.1.0',
447 'libgnomecanvas-2.0' : '2.0'
450 def DependenciesRequiredMessage():
451 print 'You do not have the necessary dependencies required to build ardour'
452 print 'Please consult http://ardour.org/building for more information'
454 def CheckPKGConfig(context, version):
455 context.Message( 'Checking for pkg-config version >= %s... ' %version )
456 ret = context.TryAction('pkg-config --atleast-pkgconfig-version=%s' % version)[0]
457 context.Result( ret )
460 def CheckPKGVersion(context, name, version):
461 context.Message( 'Checking for %s... ' % name )
462 ret = context.TryAction('pkg-config --atleast-version=%s %s' %(version,name) )[0]
463 context.Result( ret )
466 def CheckPKGExists(context, name):
467 context.Message ('Checking for %s...' % name)
468 ret = context.TryAction('pkg-config --exists %s' % name)[0]
472 conf = Configure(env, custom_tests = { 'CheckPKGConfig' : CheckPKGConfig,
473 'CheckPKGVersion' : CheckPKGVersion })
475 # I think a more recent version is needed on win32
476 min_pkg_config_version = '0.8.0'
478 if not conf.CheckPKGConfig(min_pkg_config_version):
479 print 'pkg-config >= %s not found.' % min_pkg_config_version
482 for pkg, version in deps.iteritems():
483 if not conf.CheckPKGVersion( pkg, version ):
484 print '%s >= %s not found.' %(pkg, version)
485 DependenciesRequiredMessage()
490 # ----------------------------------------------------------------------
491 # Construction environment setup
492 # ----------------------------------------------------------------------
496 libraries['core'] = LibraryInfo (CCFLAGS = '-Ilibs')
498 #libraries['sndfile'] = LibraryInfo()
499 #libraries['sndfile'].ParseConfig('pkg-config --cflags --libs sndfile')
501 libraries['lrdf'] = LibraryInfo()
502 libraries['lrdf'].ParseConfig('pkg-config --cflags --libs lrdf')
504 libraries['raptor'] = LibraryInfo()
505 libraries['raptor'].ParseConfig('pkg-config --cflags --libs raptor')
507 libraries['samplerate'] = LibraryInfo()
508 libraries['samplerate'].ParseConfig('pkg-config --cflags --libs samplerate')
510 conf = env.Configure (custom_tests = { 'CheckPKGExists' : CheckPKGExists } )
512 if conf.CheckPKGExists ('fftw3f'):
513 libraries['fftw3f'] = LibraryInfo()
514 libraries['fftw3f'].ParseConfig('pkg-config --cflags --libs fftw3f')
516 if conf.CheckPKGExists ('fftw3'):
517 libraries['fftw3'] = LibraryInfo()
518 libraries['fftw3'].ParseConfig('pkg-config --cflags --libs fftw3')
522 if env['FFT_ANALYSIS']:
524 # Check for fftw3 header as well as the library
527 conf = Configure(libraries['fftw3'])
529 if conf.CheckHeader ('fftw3.h') == False:
530 print ('FFT Analysis cannot be compiled without the FFTW3 headers, which do not seem to be installed')
535 conf = env.Configure(custom_tests = { 'CheckPKGExists' : CheckPKGExists })
537 if conf.CheckPKGExists ('\"slv2 >= 0.6.0\"'):
538 libraries['slv2'] = LibraryInfo()
539 libraries['slv2'].ParseConfig('pkg-config --cflags --libs slv2')
540 env.Append (CCFLAGS="-DHAVE_LV2")
542 print 'Building Ardour with LV2 support requires SLV2 >= 0.6.0'
543 print 'WARNING: SLV2 not found, or too old. Ardour will be built without LV2 support.'
544 print 'Until the 2.4 release, Ardour requires SLV2 out of SVN.'
545 print 'Testing would be very much appreciated! svn co http://svn.drobilla.net/lad/slv2'
549 print 'LV2 support is not enabled. Build with \'scons LV2=1\' to enable.'
551 libraries['jack'] = LibraryInfo()
552 libraries['jack'].ParseConfig('pkg-config --cflags --libs jack')
554 libraries['xml'] = LibraryInfo()
555 libraries['xml'].ParseConfig('pkg-config --cflags --libs libxml-2.0')
557 libraries['xslt'] = LibraryInfo()
558 libraries['xslt'].ParseConfig('pkg-config --cflags --libs libxslt')
560 libraries['glib2'] = LibraryInfo()
561 libraries['glib2'].ParseConfig ('pkg-config --cflags --libs glib-2.0')
562 libraries['glib2'].ParseConfig ('pkg-config --cflags --libs gobject-2.0')
563 libraries['glib2'].ParseConfig ('pkg-config --cflags --libs gmodule-2.0')
564 libraries['glib2'].ParseConfig ('pkg-config --cflags --libs gthread-2.0')
566 libraries['freetype2'] = LibraryInfo()
567 libraries['freetype2'].ParseConfig ('pkg-config --cflags --libs freetype2')
569 libraries['gtk2'] = LibraryInfo()
570 libraries['gtk2'].ParseConfig ('pkg-config --cflags --libs gtk+-2.0')
572 libraries['pango'] = LibraryInfo()
573 libraries['pango'].ParseConfig ('pkg-config --cflags --libs pango')
575 libraries['libgnomecanvas2'] = LibraryInfo()
576 libraries['libgnomecanvas2'].ParseConfig ('pkg-config --cflags --libs libgnomecanvas-2.0')
578 #libraries['flowcanvas'] = LibraryInfo(LIBS='flowcanvas', LIBPATH='#/libs/flowcanvas', CPPPATH='#libs/flowcanvas')
580 # The Ardour Control Protocol Library
582 libraries['ardour_cp'] = LibraryInfo (LIBS='ardour_cp', LIBPATH='#libs/surfaces/control_protocol',
583 CPPPATH='#libs/surfaces/control_protocol')
585 # The Ardour backend/engine
587 libraries['ardour'] = LibraryInfo (LIBS='ardour', LIBPATH='#libs/ardour', CPPPATH='#libs/ardour')
588 libraries['midi++2'] = LibraryInfo (LIBS='midi++', LIBPATH='#libs/midi++2', CPPPATH='#libs/midi++2')
589 libraries['pbd'] = LibraryInfo (LIBS='pbd', LIBPATH='#libs/pbd', CPPPATH='#libs/pbd')
590 libraries['gtkmm2ext'] = LibraryInfo (LIBS='gtkmm2ext', LIBPATH='#libs/gtkmm2ext', CPPPATH='#libs/gtkmm2ext')
593 # SCons should really do this for us
595 conf = env.Configure ()
597 have_cxx = conf.TryAction (Action (str(env['CXX']) + ' --version'))
599 print "This system has no functional C++ compiler. You cannot build Ardour from source without one."
602 print "Congratulations, you have a functioning C++ compiler."
608 # Compiler flags and other system-dependent stuff
612 if env['GPROFILE'] == 1:
613 debug_flags = [ '-g', '-pg' ]
615 debug_flags = [ '-g' ]
617 # guess at the platform, used to define compiler flags
619 config_guess = os.popen("tools/config.guess").read()[:-1]
625 config = config_guess.split ("-")
627 print "system triple: " + config_guess
630 if env['DIST_TARGET'] == 'auto':
631 if config[config_arch] == 'apple':
632 # The [.] matches to the dot after the major version, "." would match any character
633 if re.search ("darwin[0-7][.]", config[config_kernel]) != None:
634 env['DIST_TARGET'] = 'panther'
635 if re.search ("darwin8[.]", config[config_kernel]) != None:
636 env['DIST_TARGET'] = 'tiger'
638 env['DIST_TARGET'] = 'leopard'
640 if re.search ("x86_64", config[config_cpu]) != None:
641 env['DIST_TARGET'] = 'x86_64'
642 elif re.search("i[0-5]86", config[config_cpu]) != None:
643 env['DIST_TARGET'] = 'i386'
644 elif re.search("powerpc", config[config_cpu]) != None:
645 env['DIST_TARGET'] = 'powerpc'
647 env['DIST_TARGET'] = 'i686'
648 print "\n*******************************"
649 print "detected DIST_TARGET = " + env['DIST_TARGET']
650 print "*******************************\n"
653 if config[config_cpu] == 'powerpc' and env['DIST_TARGET'] != 'none':
655 # Apple/PowerPC optimization options
657 # -mcpu=7450 does not reliably work with gcc 3.*
659 if env['DIST_TARGET'] == 'panther' or env['DIST_TARGET'] == 'tiger':
660 if config[config_arch] == 'apple':
661 ## opt_flags.extend ([ "-mcpu=7450", "-faltivec"])
662 # to support g3s but still have some optimization for above
663 opt_flags.extend ([ "-mcpu=G3", "-mtune=7450"])
665 opt_flags.extend ([ "-mcpu=7400", "-maltivec", "-mabi=altivec"])
667 opt_flags.extend([ "-mcpu=750", "-mmultiple" ])
668 opt_flags.extend (["-mhard-float", "-mpowerpc-gfxopt"])
669 opt_flags.extend (["-Os"])
671 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':
673 build_host_supports_sse = 0
675 debug_flags.append ("-DARCH_X86")
676 opt_flags.append ("-DARCH_X86")
678 if config[config_kernel] == 'linux' :
680 if env['DIST_TARGET'] != 'i386':
682 flag_line = os.popen ("cat /proc/cpuinfo | grep '^flags'").read()[:-1]
683 x86_flags = flag_line.split (": ")[1:][0].split ()
685 if "mmx" in x86_flags:
686 opt_flags.append ("-mmmx")
687 if "sse" in x86_flags:
688 build_host_supports_sse = 1
689 if "3dnow" in x86_flags:
690 opt_flags.append ("-m3dnow")
692 if config[config_cpu] == "i586":
693 opt_flags.append ("-march=i586")
694 elif config[config_cpu] == "i686":
695 opt_flags.append ("-march=i686")
697 if ((env['DIST_TARGET'] == 'i686') or (env['DIST_TARGET'] == 'x86_64')) and build_host_supports_sse:
698 opt_flags.extend (["-msse", "-mfpmath=sse", "-DUSE_XMMINTRIN"])
699 debug_flags.extend (["-msse", "-mfpmath=sse", "-DUSE_XMMINTRIN"])
700 # end of processor-specific section
702 # optimization section
703 if env['FPU_OPTIMIZATION']:
704 if env['DIST_TARGET'] == 'tiger' or env['DIST_TARGET'] == 'leopard':
705 opt_flags.append ("-DBUILD_VECLIB_OPTIMIZATIONS");
706 debug_flags.append ("-DBUILD_VECLIB_OPTIMIZATIONS");
707 libraries['core'].Append(LINKFLAGS= '-framework Accelerate')
708 elif env['DIST_TARGET'] == 'i686' or env['DIST_TARGET'] == 'x86_64':
709 opt_flags.append ("-DBUILD_SSE_OPTIMIZATIONS")
710 debug_flags.append ("-DBUILD_SSE_OPTIMIZATIONS")
711 if env['DIST_TARGET'] == 'x86_64':
712 opt_flags.append ("-DUSE_X86_64_ASM")
713 debug_flags.append ("-DUSE_X86_64_ASM")
714 if build_host_supports_sse != 1:
715 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)"
716 # end optimization section
718 # handle x86/x86_64 libdir properly
720 if env['DIST_TARGET'] == 'x86_64':
721 env['LIBDIR']='lib64'
726 # a single way to test if we're on OS X
729 if env['DIST_TARGET'] in ['panther', 'tiger', 'leopard' ]:
731 # force tiger or later, to avoid issues on PPC which defaults
732 # back to 10.1 if we don't tell it otherwise.
733 env.Append (CCFLAGS="-DMAC_OS_X_VERSION_MIN_REQUIRED=1040")
738 # save off guessed arch element in an env
740 env.Append(CONFIG_ARCH=config[config_arch])
744 # ARCH="..." overrides all
747 if env['ARCH'] != '':
748 opt_flags = env['ARCH'].split()
751 # prepend boiler plate optimization flags
756 "-fomit-frame-pointer",
762 if env['DEBUG'] == 1:
763 env.Append(CCFLAGS=" ".join (debug_flags))
764 env.Append(LINKFLAGS=" ".join (debug_flags))
766 env.Append(CCFLAGS=" ".join (opt_flags))
767 env.Append(LINKFLAGS=" ".join (opt_flags))
769 if env['UNIVERSAL'] == 1:
770 env.Append(CCFLAGS="-arch i386 -arch ppc")
771 env.Append(LINKFLAGS="-arch i386 -arch ppc")
777 env.Append(CCFLAGS="-Wall")
778 env.Append(CXXFLAGS="-Woverloaded-virtual")
780 if env['EXTRA_WARN']:
781 env.Append(CCFLAGS="-Wextra -pedantic -ansi")
782 env.Append(CXXFLAGS="-ansi")
783 # env.Append(CFLAGS="-iso")
786 env.Append(CCFLAGS="-DHAVE_LIBLO")
790 # fix scons nitpickiness on APPLE
794 def prep_libcheck(topenv, libinfo):
797 # rationale: GTK-Quartz uses jhbuild and installs to /opt/gtk by default.
798 # All libraries needed should be built against this location
800 libinfo.Append(CPPPATH="/opt/gtk/include", LIBPATH="/opt/gtk/lib")
801 libinfo.Append(CXXFLAGS="-I/opt/gtk/include", LINKFLAGS="-L/opt/gtk/lib")
802 libinfo.Append(CPPPATH="/opt/local/include", LIBPATH="/opt/local/lib")
803 libinfo.Append(CXXFLAGS="-I/opt/local/include", LINKFLAGS="-L/opt/local/lib")
805 prep_libcheck(env, env)
809 # these are part of the Ardour source tree because they are C++
812 libraries['vamp'] = LibraryInfo (LIBS='vampsdk',
813 LIBPATH='#libs/vamp-sdk',
814 CPPPATH='#libs/vamp-sdk')
815 libraries['vamphost'] = LibraryInfo (LIBS='vamphostsdk',
816 LIBPATH='#libs/vamp-sdk',
817 CPPPATH='#libs/vamp-sdk')
819 env['RUBBERBAND'] = False
821 conf = Configure (env)
823 if conf.CheckHeader ('fftw3.h'):
824 env['RUBBERBAND'] = True
825 libraries['rubberband'] = LibraryInfo (LIBS='rubberband',
826 LIBPATH='#libs/rubberband',
827 CPPPATH='#libs/rubberband',
828 CCFLAGS='-DUSE_RUBBERBAND')
831 print "-------------------------------------------------------------------------"
832 print "You do not have the FFTW single-precision development package installed."
833 print "This prevents Ardour from using the Rubberband library for timestretching"
834 print "and pitchshifting. It will fall back on SoundTouch for timestretch, and "
835 print "pitchshifting will not be available."
836 print "-------------------------------------------------------------------------"
844 libraries['usb'] = LibraryInfo ()
845 prep_libcheck(env, libraries['usb'])
847 conf = Configure (libraries['usb'])
848 if conf.CheckLib ('usb', 'usb_interrupt_write'):
853 # check for linux/input.h while we're at it for powermate
854 if conf.CheckHeader('linux/input.h'):
855 have_linux_input = True
857 have_linux_input = False
859 libraries['usb'] = conf.Finish ()
864 libraries['flac'] = LibraryInfo ()
865 prep_libcheck(env, libraries['flac'])
866 libraries['flac'].Append(CPPPATH="/usr/local/include", LIBPATH="/usr/local/lib")
869 # june 1st 2007: look for a function that is in FLAC 1.1.2 and not in later versions
870 # since the version of libsndfile we have internally does not support
871 # the new API that libFLAC has adopted
874 conf = Configure (libraries['flac'])
875 if conf.CheckLib ('FLAC', 'FLAC__seekable_stream_decoder_init', language='CXX'):
876 conf.env.Append(CCFLAGS='-DHAVE_FLAC')
881 libraries['flac'] = conf.Finish ()
883 # or if that fails...
884 #libraries['flac'] = LibraryInfo (LIBS='FLAC')
886 # boost (we don't link against boost, just use some header files)
888 libraries['boost'] = LibraryInfo ()
889 prep_libcheck(env, libraries['boost'])
890 libraries['boost'].Append(CPPPATH="/usr/local/include", LIBPATH="/usr/local/lib")
891 conf = Configure (libraries['boost'])
892 if conf.CheckHeader ('boost/shared_ptr.hpp', language='CXX') == False:
893 print "Boost header files do not appear to be installed."
896 libraries['boost'] = conf.Finish ()
902 libraries['lo'] = LibraryInfo ()
903 prep_libcheck(env, libraries['lo'])
905 conf = Configure (libraries['lo'])
906 if conf.CheckLib ('lo', 'lo_server_new') == False:
907 print "liblo does not appear to be installed."
910 libraries['lo'] = conf.Finish ()
915 libraries['dmalloc'] = LibraryInfo ()
916 prep_libcheck(env, libraries['dmalloc'])
919 # look for the threaded version
922 conf = Configure (libraries['dmalloc'])
923 if conf.CheckLib ('dmallocth', 'dmalloc_shutdown'):
924 have_libdmalloc = True
926 have_libdmalloc = False
928 libraries['dmalloc'] = conf.Finish ()
931 # ensure FREEDESKTOP target is doable..
934 conf = env.Configure ()
935 if env['FREEDESKTOP']:
936 have_update_mime_database = conf.TryAction (Action ('update-mime-database -v'))
937 if have_update_mime_database[0] != 1:
938 print "Warning. You have no update-mime-database command in your PATH. FREEDESKTOP is now disabled."
939 env['FREEDESKTOP'] = 0
940 have_gtk_update_icon_cache = conf.TryAction (Action ('gtk-update-icon-cache -?'))
941 if have_gtk_update_icon_cache[0] != 1:
942 print "Warning. You have no gtk-update-icon-cache command in your PATH. FREEDESKTOP is now disabled."
943 env['FREEDESKTOP'] = 0
944 have_update_desktop_database = conf.TryAction (Action ('update-desktop-database -?'))
945 if have_update_desktop_database[0] != 1:
946 print "Warning. You have no update-desktop-database command in your PATH. FREEDESKTOP is now disabled."
947 env['FREEDESKTOP'] = 0
951 # Audio/MIDI library (needed for MIDI, since audio is all handled via JACK)
954 conf = Configure(env)
956 if conf.CheckCHeader('alsa/asoundlib.h'):
957 libraries['sysmidi'] = LibraryInfo (LIBS='asound')
958 env['SYSMIDI'] = 'ALSA Sequencer'
959 subst_dict['%MIDITAG%'] = "seq"
960 subst_dict['%MIDITYPE%'] = "alsa/sequencer"
961 elif conf.CheckCHeader('/System/Library/Frameworks/CoreMIDI.framework/Headers/CoreMIDI.h'):
962 # this line is needed because scons can't handle -framework in ParseConfig() yet.
964 # We need Carbon as well as the rest
965 libraries['sysmidi'] = LibraryInfo (
966 LINKFLAGS = ' -framework CoreMIDI -framework CoreFoundation -framework CoreAudio -framework CoreServices -framework AudioUnit -framework AudioToolbox -framework Carbon -bind_at_load' )
968 libraries['sysmidi'] = LibraryInfo (
969 LINKFLAGS = ' -framework CoreMIDI -framework CoreFoundation -framework CoreAudio -framework CoreServices -framework AudioUnit -framework AudioToolbox -bind_at_load' )
970 env['SYSMIDI'] = 'CoreMIDI'
971 subst_dict['%MIDITAG%'] = "ardour"
972 subst_dict['%MIDITYPE%'] = "coremidi"
974 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."
983 'sigc++-2.0' : '2.0',
985 'libgnomecanvasmm-2.6' : '2.12.0'
988 conf = Configure(env, custom_tests = { 'CheckPKGConfig' : CheckPKGConfig,
989 'CheckPKGVersion' : CheckPKGVersion })
991 for pkg, version in syslibdeps.iteritems():
992 if not conf.CheckPKGVersion( pkg, version ):
993 print '%s >= %s not found.' %(pkg, version)
994 DependenciesRequiredMessage()
999 libraries['sigc2'] = LibraryInfo()
1000 libraries['sigc2'].ParseConfig('pkg-config --cflags --libs sigc++-2.0')
1001 libraries['glibmm2'] = LibraryInfo()
1002 libraries['glibmm2'].ParseConfig('pkg-config --cflags --libs glibmm-2.4')
1003 libraries['cairomm'] = LibraryInfo()
1004 libraries['cairomm'].ParseConfig('pkg-config --cflags --libs cairomm-1.0')
1005 libraries['gdkmm2'] = LibraryInfo()
1006 libraries['gdkmm2'].ParseConfig ('pkg-config --cflags --libs gdkmm-2.4')
1007 libraries['gtkmm2'] = LibraryInfo()
1008 libraries['gtkmm2'].ParseConfig ('pkg-config --cflags --libs gtkmm-2.4')
1009 libraries['atkmm'] = LibraryInfo()
1010 libraries['atkmm'].ParseConfig ('pkg-config --cflags --libs atkmm-1.6')
1011 libraries['pangomm'] = LibraryInfo()
1012 libraries['pangomm'].ParseConfig ('pkg-config --cflags --libs pangomm-1.4')
1013 libraries['libgnomecanvasmm'] = LibraryInfo()
1014 libraries['libgnomecanvasmm'].ParseConfig ('pkg-config --cflags --libs libgnomecanvasmm-2.6')
1017 # cannot use system one for the time being
1020 libraries['sndfile-ardour'] = LibraryInfo(LIBS='libsndfile-ardour',
1021 LIBPATH='#libs/libsndfile',
1022 CPPPATH=['#libs/libsndfile/src'])
1024 # libraries['libglademm'] = LibraryInfo()
1025 # libraries['libglademm'].ParseConfig ('pkg-config --cflags --libs libglademm-2.4')
1027 # libraries['flowcanvas'] = LibraryInfo(LIBS='flowcanvas', LIBPATH='#/libs/flowcanvas', CPPPATH='#libs/flowcanvas')
1028 libraries['soundtouch'] = LibraryInfo()
1029 #libraries['soundtouch'].ParseConfig ('pkg-config --cflags --libs soundtouch-1.0')
1030 # Comment the previous line and uncomment this for Debian:
1031 libraries['soundtouch'].ParseConfig ('pkg-config --cflags --libs libSoundTouch')
1033 libraries['appleutility'] = LibraryInfo(LIBS='libappleutility',
1034 LIBPATH='#libs/appleutility',
1035 CPPPATH='#libs/appleutility')
1047 'libs/vamp-plugins/',
1048 # these are unconditionally included but have
1049 # tests internally to avoid compilation etc
1053 # this is unconditionally included but has
1054 # tests internally to avoid compilation etc
1055 # if COREAUDIO is not set
1060 # 'libs/flowcanvas',
1067 libraries['sigc2'] = LibraryInfo(LIBS='sigc++2',
1068 LIBPATH='#libs/sigc++2',
1069 CPPPATH='#libs/sigc++2')
1070 libraries['glibmm2'] = LibraryInfo(LIBS='glibmm2',
1071 LIBPATH='#libs/glibmm2',
1072 CPPPATH='#libs/glibmm2')
1073 libraries['pangomm'] = LibraryInfo(LIBS='pangomm',
1074 LIBPATH='#libs/gtkmm2/pango',
1075 CPPPATH='#libs/gtkmm2/pango')
1076 libraries['atkmm'] = LibraryInfo(LIBS='atkmm',
1077 LIBPATH='#libs/gtkmm2/atk',
1078 CPPPATH='#libs/gtkmm2/atk')
1079 libraries['gdkmm2'] = LibraryInfo(LIBS='gdkmm2',
1080 LIBPATH='#libs/gtkmm2/gdk',
1081 CPPPATH='#libs/gtkmm2/gdk')
1082 libraries['gtkmm2'] = LibraryInfo(LIBS='gtkmm2',
1083 LIBPATH="#libs/gtkmm2/gtk",
1084 CPPPATH='#libs/gtkmm2/gtk/')
1085 libraries['libgnomecanvasmm'] = LibraryInfo(LIBS='libgnomecanvasmm',
1086 LIBPATH='#libs/libgnomecanvasmm',
1087 CPPPATH='#libs/libgnomecanvasmm')
1089 libraries['soundtouch'] = LibraryInfo(LIBS='soundtouch',
1090 LIBPATH='#libs/soundtouch',
1091 CPPPATH=['#libs', '#libs/soundtouch'])
1092 libraries['sndfile-ardour'] = LibraryInfo(LIBS='libsndfile-ardour',
1093 LIBPATH='#libs/libsndfile',
1094 CPPPATH=['#libs/libsndfile', '#libs/libsndfile/src'])
1095 # libraries['libglademm'] = LibraryInfo(LIBS='libglademm',
1096 # LIBPATH='#libs/libglademm',
1097 # CPPPATH='#libs/libglademm')
1098 libraries['appleutility'] = LibraryInfo(LIBS='libappleutility',
1099 LIBPATH='#libs/appleutility',
1100 CPPPATH='#libs/appleutility')
1113 'libs/vamp-plugins/',
1114 # these are unconditionally included but have
1115 # tests internally to avoid compilation etc
1119 # this is unconditionally included but has
1120 # tests internally to avoid compilation etc
1121 # if COREAUDIO is not set
1127 'libs/gtkmm2/pango',
1131 'libs/libgnomecanvasmm',
1138 # * always build the LGPL control protocol lib, since we link against it from libardour
1139 # * ditto for generic MIDI
1140 # * tranzport checks whether it should build internally, but we need here so that
1141 # its included in the tarball
1144 surface_subdirs = [ 'libs/surfaces/control_protocol',
1145 'libs/surfaces/generic_midi',
1146 'libs/surfaces/tranzport',
1147 'libs/surfaces/mackie',
1148 'libs/surfaces/powermate'
1153 env['TRANZPORT'] = 1
1155 env['TRANZPORT'] = 0
1156 print 'Disabled building Tranzport code because libusb could not be found'
1158 if have_linux_input:
1159 env['POWERMATE'] = 1
1161 env['POWERMATE'] = 0
1162 print 'Disabled building Powermate code because linux/input.h could not be found'
1164 if os.access ('libs/surfaces/sony9pin', os.F_OK):
1165 surface_subdirs += [ 'libs/surfaces/sony9pin' ]
1167 env['POWERMATE'] = 0
1168 env['TRANZPORT'] = 0
1171 # timestretch libraries
1174 timefx_subdirs = ['libs/soundtouch']
1175 if env['RUBBERBAND']:
1176 timefx_subdirs += ['libs/rubberband']
1178 opts.Save('scache.conf', env)
1179 Help(opts.GenerateHelpText(env))
1181 final_prefix = '$PREFIX'
1184 install_prefix = '$DESTDIR/$PREFIX'
1186 install_prefix = env['PREFIX']
1188 subst_dict['%INSTALL_PREFIX%'] = install_prefix;
1189 subst_dict['%FINAL_PREFIX%'] = final_prefix;
1190 subst_dict['%PREFIX%'] = final_prefix;
1192 if env['PREFIX'] == '/usr':
1193 final_config_prefix = '/etc'
1195 final_config_prefix = env['PREFIX'] + '/etc'
1197 config_prefix = '$DESTDIR' + final_config_prefix
1200 # everybody needs this
1203 env.Merge ([ libraries['core'] ])
1210 conf = Configure (env)
1212 nls_error = 'This system is not configured for internationalized applications. An english-only version will be built:'
1213 print 'Checking for internationalization support ...'
1214 have_gettext = conf.TryAction(Action('xgettext --version'))
1215 if have_gettext[0] != 1:
1216 nls_error += ' No xgettext command.'
1219 print "Found xgettext"
1221 have_msgmerge = conf.TryAction(Action('msgmerge --version'))
1222 if have_msgmerge[0] != 1:
1223 nls_error += ' No msgmerge command.'
1226 print "Found msgmerge"
1228 if not conf.CheckCHeader('libintl.h'):
1229 nls_error += ' No libintl.h.'
1235 print "International version will be built."
1239 env.Append(CCFLAGS="-DENABLE_NLS")
1241 Export('env install_prefix final_prefix config_prefix final_config_prefix libraries i18n ardour_version subst_dict use_flac')
1244 # the configuration file may be system dependent
1247 conf = env.Configure ()
1249 if conf.CheckCHeader('/System/Library/Frameworks/CoreAudio.framework/Versions/A/Headers/CoreAudio.h'):
1250 subst_dict['%JACK_INPUT%'] = "coreaudio:Built-in Audio:in"
1251 subst_dict['%JACK_OUTPUT%'] = "coreaudio:Built-in Audio:out"
1253 subst_dict['%JACK_INPUT%'] = "alsa_pcm:playback_"
1254 subst_dict['%JACK_OUTPUT%'] = "alsa_pcm:capture_"
1256 # posix_memalign available
1257 if not conf.CheckFunc('posix_memalign'):
1258 print 'Did not find posix_memalign(), using malloc'
1259 env.Append(CCFLAGS='-DNO_POSIX_MEMALIGN')
1264 # generate the per-user and system rc files from the same source
1266 sysrcbuild = env.SubstInFile ('ardour_system.rc','ardour.rc.in', SUBST_DICT = subst_dict)
1268 # add to the substitution dictionary
1270 subst_dict['%VERSION%'] = ardour_version[0:3]
1271 subst_dict['%EXTRA_VERSION%'] = ardour_version[3:]
1272 subst_dict['%REVISION_STRING%'] = ''
1273 if os.path.exists('.svn'):
1274 subst_dict['%REVISION_STRING%'] = '.' + fetch_svn_revision ('.') + 'svn'
1276 # specbuild = env.SubstInFile ('ardour.spec','ardour.spec.in', SUBST_DICT = subst_dict)
1278 the_revision = env.Command ('frobnicatory_decoy', [], create_stored_revision)
1279 remove_ardour = env.Command ('frobnicatory_decoy2', [],
1280 [ Delete ('$PREFIX/etc/ardour2'),
1281 Delete ('$PREFIX/lib/ardour2'),
1282 Delete ('$PREFIX/bin/ardour2')])
1284 env.Alias('revision', the_revision)
1285 env.Alias('install', env.Install(os.path.join(config_prefix, 'ardour2'), 'ardour_system.rc'))
1286 env.Alias('uninstall', remove_ardour)
1288 Default (sysrcbuild)
1292 Precious (env['DISTTREE'])
1294 env.Distribute (env['DISTTREE'],
1295 [ 'SConstruct', 'svn_revision.h',
1296 'COPYING', 'PACKAGER_README', 'README',
1298 'tools/config.guess',
1299 'icons/icon/ardour_icon_mac_mask.png',
1300 'icons/icon/ardour_icon_mac.png',
1301 'icons/icon/ardour_icon_tango_16px_blue.png',
1302 'icons/icon/ardour_icon_tango_16px_red.png',
1303 'icons/icon/ardour_icon_tango_22px_blue.png',
1304 'icons/icon/ardour_icon_tango_22px_red.png',
1305 'icons/icon/ardour_icon_tango_32px_blue.png',
1306 'icons/icon/ardour_icon_tango_32px_red.png',
1307 'icons/icon/ardour_icon_tango_48px_blue.png',
1308 'icons/icon/ardour_icon_tango_48px_red.png'
1310 glob.glob ('DOCUMENTATION/AUTHORS*') +
1311 glob.glob ('DOCUMENTATION/CONTRIBUTORS*') +
1312 glob.glob ('DOCUMENTATION/TRANSLATORS*') +
1313 glob.glob ('DOCUMENTATION/BUILD*') +
1314 glob.glob ('DOCUMENTATION/FAQ*') +
1315 glob.glob ('DOCUMENTATION/README*')
1318 srcdist = env.Tarball(env['TARBALL'], [ env['DISTTREE'], the_revision ])
1319 env.Alias ('srctar', srcdist)
1322 # don't leave the distree around
1325 env.AddPreAction (env['DISTTREE'], Action ('rm -rf ' + str (File (env['DISTTREE']))))
1326 env.AddPostAction (srcdist, Action ('rm -rf ' + str (File (env['DISTTREE']))))
1332 for subdir in coredirs:
1333 SConscript (subdir + '/SConscript')
1335 for sublistdir in [ subdirs, timefx_subdirs, gtk_subdirs, surface_subdirs ]:
1336 for subdir in sublistdir:
1337 SConscript (subdir + '/SConscript')
1340 env.Clean ('scrub', [ 'scache.conf', '.sconf_temp', '.sconsign.dblite', 'config.log'])