17 EnsureSConsVersion(0, 96)
19 ardour_version = '2.2'
24 # Command-line options
27 opts = Options('scache.conf')
29 ('ARCH', 'Set architecture-specific compilation flags by hand (all flags as 1 argument)',''),
30 BoolOption('AUDIOUNITS', 'Compile with Apple\'s AudioUnit library. (experimental)', 0),
31 BoolOption('COREAUDIO', 'Compile with Apple\'s CoreAudio library', 0),
32 BoolOption('GTKOSX', 'Compile for use with GTK-OSX, not GTK-X11', 0),
33 BoolOption('NATIVE_OSX_KEYS', 'Build key bindings file that matches OS X conventions', 0),
34 BoolOption('OLDFONTS', 'Old school font sizes', 0),
35 BoolOption('DEBUG', 'Set to build with debugging information and no optimizations', 0),
36 PathOption('DESTDIR', 'Set the intermediate install "prefix"', '/'),
37 EnumOption('DIST_TARGET', 'Build target for cross compiling packagers', 'auto', allowed_values=('auto', 'i386', 'i686', 'x86_64', 'powerpc', 'tiger', 'panther', 'leopard', 'none' ), ignorecase=2),
38 BoolOption('DMALLOC', 'Compile and link using the dmalloc library', 0),
39 BoolOption('EXTRA_WARN', 'Compile with -Wextra, -ansi, and -pedantic. Might break compilation. For pedants', 0),
40 BoolOption('FFT_ANALYSIS', 'Include FFT analysis window', 0),
41 BoolOption('FPU_OPTIMIZATION', 'Build runtime checked assembler code', 1),
42 BoolOption('LIBLO', 'Compile with support for liblo library', 1),
43 BoolOption('NLS', 'Set to turn on i18n support', 1),
44 PathOption('PREFIX', 'Set the install "prefix"', '/usr/local'),
45 BoolOption('SURFACES', 'Build support for control surfaces', 1),
46 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),
47 BoolOption('UNIVERSAL', 'Compile as universal binary. Requires that external libraries are already universal.', 0),
48 BoolOption('VERSIONED', 'Add revision information to ardour/gtk executable name inside the build directory', 0),
49 BoolOption('VST', 'Compile with support for VST', 0),
50 BoolOption('LV2', 'Compile with support for LV2 (if slv2 is available)', 1),
51 BoolOption('GPROFILE', 'Compile with support for gprofile (Developers only)', 0),
52 BoolOption('TRANZPORT', 'Compile with support for Frontier Designs (if libusb is available)', 1)
55 #----------------------------------------------------------------------
56 # a handy helper that provides a way to merge compile/link information
57 # from multiple different "environments"
58 #----------------------------------------------------------------------
60 class LibraryInfo(Environment):
61 def __init__(self,*args,**kw):
62 Environment.__init__ (self,*args,**kw)
64 def Merge (self,others):
66 self.Append (LIBS = other.get ('LIBS',[]))
67 self.Append (LIBPATH = other.get ('LIBPATH', []))
68 self.Append (CPPPATH = other.get('CPPPATH', []))
69 self.Append (LINKFLAGS = other.get('LINKFLAGS', []))
70 self.Append (CCFLAGS = other.get('CCFLAGS', []))
71 self.Replace(LIBPATH = list(Set(self.get('LIBPATH', []))))
72 self.Replace(CPPPATH = list(Set(self.get('CPPPATH',[]))))
73 #doing LINKFLAGS breaks -framework
74 #doing LIBS break link order dependency
76 def ENV_update(self, src_ENV):
77 for k in src_ENV.keys():
78 if k in self['ENV'].keys() and k in [ 'PATH', 'LD_LIBRARY_PATH',
80 self['ENV'][k]=SCons.Util.AppendPath(self['ENV'][k], src_ENV[k])
82 self['ENV'][k]=src_ENV[k]
84 env = LibraryInfo (options = opts,
86 VERSION = ardour_version,
87 TARBALL='ardour-' + ardour_version + '.tar.bz2',
89 DISTTREE = '#ardour-' + ardour_version,
90 DISTCHECKDIR = '#ardour-' + ardour_version + '/check'
93 env.ENV_update(os.environ)
95 #----------------------------------------------------------------------
97 #----------------------------------------------------------------------
99 # Handy subst-in-file builder
102 def do_subst_in_file(targetfile, sourcefile, dict):
103 """Replace all instances of the keys of dict with their values.
104 For example, if dict is {'%VERSION%': '1.2345', '%BASE%': 'MyProg'},
105 then all instances of %VERSION% in the file will be replaced with 1.2345 etc.
108 f = open(sourcefile, 'rb')
112 raise SCons.Errors.UserError, "Can't read source file %s"%sourcefile
113 for (k,v) in dict.items():
114 contents = re.sub(k, v, contents)
116 f = open(targetfile, 'wb')
120 raise SCons.Errors.UserError, "Can't write target file %s"%targetfile
123 def subst_in_file(target, source, env):
124 if not env.has_key('SUBST_DICT'):
125 raise SCons.Errors.UserError, "SubstInFile requires SUBST_DICT to be set."
126 d = dict(env['SUBST_DICT']) # copy it
127 for (k,v) in d.items():
129 d[k] = env.subst(v())
130 elif SCons.Util.is_String(v):
133 raise SCons.Errors.UserError, "SubstInFile: key %s: %s must be a string or callable"%(k, repr(v))
134 for (t,s) in zip(target, source):
135 return do_subst_in_file(str(t), str(s), d)
137 def subst_in_file_string(target, source, env):
138 """This is what gets printed on the console."""
139 return '\n'.join(['Substituting vars from %s into %s'%(str(s), str(t))
140 for (t,s) in zip(target, source)])
142 def subst_emitter(target, source, env):
143 """Add dependency from substituted SUBST_DICT to target.
144 Returns original target, source tuple unchanged.
146 d = env['SUBST_DICT'].copy() # copy it
147 for (k,v) in d.items():
149 d[k] = env.subst(v())
150 elif SCons.Util.is_String(v):
152 Depends(target, SCons.Node.Python.Value(d))
153 # Depends(target, source) # this doesn't help the install-sapphire-linux.sh problem
154 return target, source
156 subst_action = Action (subst_in_file, subst_in_file_string)
157 env['BUILDERS']['SubstInFile'] = Builder(action=subst_action, emitter=subst_emitter)
160 # internationalization
163 # po_builder: builder function to copy po files to the parent directory while updating them
165 # first source: .po file
166 # second source: .pot file
169 def po_builder(target,source,env):
170 os.spawnvp (os.P_WAIT, 'cp', ['cp', str(source[0]), str(target[0])])
176 print 'Updating ' + str(target[0])
177 return os.spawnvp (os.P_WAIT, 'msgmerge', args)
179 po_bld = Builder (action = po_builder)
180 env.Append(BUILDERS = {'PoBuild' : po_bld})
182 # mo_builder: builder function for (binary) message catalogs (.mo)
184 # first source: .po file
187 def mo_builder(target,source,env):
191 target[0].get_path(),
194 return os.spawnvp (os.P_WAIT, 'msgfmt', args)
196 mo_bld = Builder (action = mo_builder)
197 env.Append(BUILDERS = {'MoBuild' : mo_bld})
199 # pot_builder: builder function for message templates (.pot)
201 # source: list of C/C++ etc. files to extract messages from
204 def pot_builder(target,source,env):
209 '-o', target[0].get_path(),
210 "--default-domain=" + env['PACKAGE'],
211 '--copyright-holder="Paul Davis"' ]
212 args += [ src.get_path() for src in source ]
214 return os.spawnvp (os.P_WAIT, 'xgettext', args)
216 pot_bld = Builder (action = pot_builder)
217 env.Append(BUILDERS = {'PotBuild' : pot_bld})
220 # utility function, not a builder
223 def i18n (buildenv, sources, installenv):
224 domain = buildenv['PACKAGE']
225 potfile = buildenv['POTFILE']
227 installenv.Alias ('potupdate', buildenv.PotBuild (potfile, sources))
229 p_oze = [ os.path.basename (po) for po in glob.glob ('po/*.po') ]
230 languages = [ po.replace ('.po', '') for po in p_oze ]
232 for po_file in p_oze:
233 buildenv.PoBuild(po_file, ['po/'+po_file, potfile])
234 mo_file = po_file.replace (".po", ".mo")
235 installenv.Alias ('install', buildenv.MoBuild (mo_file, po_file))
236 installenv.Alias ('msgupdate', buildenv.MoBuild (mo_file, po_file))
238 for lang in languages:
239 modir = (os.path.join (install_prefix, 'share/locale/' + lang + '/LC_MESSAGES/'))
240 moname = domain + '.mo'
241 installenv.Alias('install', installenv.InstallAs (os.path.join (modir, moname), lang + '.mo'))
244 def fetch_svn_revision (path):
248 cmd += " | awk '/^Revision:/ { print $2}'"
249 return commands.getoutput (cmd)
251 def create_stored_revision (target = None, source = None, env = None):
252 if os.path.exists('.svn'):
253 rev = fetch_svn_revision ('.');
255 text = "#ifndef __ardour_svn_revision_h__\n"
256 text += "#define __ardour_svn_revision_h__\n"
257 text += "static const char* ardour_svn_revision = \"" + rev + "\";\n";
259 print '============> writing svn revision info to svn_revision.h\n'
260 o = file ('svn_revision.h', 'w')
264 print "Could not open svn_revision.h for writing\n"
267 print "You cannot use \"scons revision\" on without using a checked out"
268 print "copy of the Ardour source code repository"
272 # A generic builder for version.cc files
274 # note: requires that DOMAIN, MAJOR, MINOR, MICRO are set in the construction environment
275 # note: assumes one source files, the header that declares the version variables
278 def version_builder (target, source, env):
280 text = "int " + env['DOMAIN'] + "_major_version = " + str (env['MAJOR']) + ";\n"
281 text += "int " + env['DOMAIN'] + "_minor_version = " + str (env['MINOR']) + ";\n"
282 text += "int " + env['DOMAIN'] + "_micro_version = " + str (env['MICRO']) + ";\n"
285 o = file (target[0].get_path(), 'w')
289 print "Could not open", target[0].get_path(), " for writing\n"
292 text = "#ifndef __" + env['DOMAIN'] + "_version_h__\n"
293 text += "#define __" + env['DOMAIN'] + "_version_h__\n"
294 text += "extern const char* " + env['DOMAIN'] + "_revision;\n"
295 text += "extern int " + env['DOMAIN'] + "_major_version;\n"
296 text += "extern int " + env['DOMAIN'] + "_minor_version;\n"
297 text += "extern int " + env['DOMAIN'] + "_micro_version;\n"
298 text += "#endif /* __" + env['DOMAIN'] + "_version_h__ */\n"
301 o = file (target[1].get_path(), 'w')
305 print "Could not open", target[1].get_path(), " for writing\n"
310 version_bld = Builder (action = version_builder)
311 env.Append (BUILDERS = {'VersionBuild' : version_bld})
314 # a builder that makes a hard link from the 'source' executable to a name with
315 # a "build ID" based on the most recent CVS activity that might be reasonably
316 # related to version activity. this relies on the idea that the SConscript
317 # file that builds the executable is updated with new version info and committed
318 # to the source code repository whenever things change.
321 def versioned_builder(target,source,env):
322 w, r = os.popen2( "LANG= svn info | awk '/^Revision:/ { print $2}'")
324 last_revision = r.readline().strip()
327 if last_revision == "":
328 print "No SVN info found - versioned executable cannot be built"
331 print "The current build ID is " + last_revision
333 tagged_executable = source[0].get_path() + '-' + last_revision
335 if os.path.exists (tagged_executable):
336 print "Replacing existing executable with the same build tag."
337 os.unlink (tagged_executable)
339 return os.link (source[0].get_path(), tagged_executable)
341 verbuild = Builder (action = versioned_builder)
342 env.Append (BUILDERS = {'VersionedExecutable' : verbuild})
345 # source tar file builder
348 def distcopy (target, source, env):
349 treedir = str (target[0])
353 except OSError, (errnum, strerror):
354 if errnum != errno.EEXIST:
355 print 'mkdir ', treedir, ':', strerror
359 # we don't know what characters might be in the file names
360 # so quote them all before passing them to the shell
362 all_files = ([ str(s) for s in source ])
363 cmd += " ".join ([ "'%s'" % quoted for quoted in all_files])
364 cmd += ' | (cd ' + treedir + ' && tar xf -)'
368 def tarballer (target, source, env):
369 cmd = 'tar -jcf ' + str (target[0]) + ' ' + str(source[0]) + " --exclude '*~'" + " --exclude .svn --exclude '.svn/*'"
370 print 'running ', cmd, ' ... '
374 dist_bld = Builder (action = distcopy,
375 target_factory = SCons.Node.FS.default_fs.Entry,
376 source_factory = SCons.Node.FS.default_fs.Entry,
379 tarball_bld = Builder (action = tarballer,
380 target_factory = SCons.Node.FS.default_fs.Entry,
381 source_factory = SCons.Node.FS.default_fs.Entry)
383 env.Append (BUILDERS = {'Distribute' : dist_bld})
384 env.Append (BUILDERS = {'Tarball' : tarball_bld})
387 # Make sure they know what they are doing
391 if os.path.isfile('.personal_use_only'):
392 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."
394 sys.stdout.write ("Are you building Ardour for personal use (rather than distribution to others)? [no]: ")
395 answer = sys.stdin.readline ()
396 answer = answer.rstrip().strip()
397 if answer == "yes" or answer == "y":
398 fh = open('.personal_use_only', 'w')
400 print "OK, VST support will be enabled"
402 print 'You cannot build Ardour with VST support for distribution to others.\nIt is a violation of several different licenses. Build with VST=false.'
405 if os.path.isfile('.personal_use_only'):
406 os.remove('.personal_use_only')
412 def pushEnvironment(context):
413 if os.environ.has_key('PATH'):
414 context.Append(PATH = os.environ['PATH'])
416 if os.environ.has_key('PKG_CONFIG_PATH'):
417 context.Append(PKG_CONFIG_PATH = os.environ['PKG_CONFIG_PATH'])
419 if os.environ.has_key('CC'):
420 context['CC'] = os.environ['CC']
422 if os.environ.has_key('CXX'):
423 context['CXX'] = os.environ['CXX']
425 if os.environ.has_key('DISTCC_HOSTS'):
426 context['ENV']['DISTCC_HOSTS'] = os.environ['DISTCC_HOSTS']
427 context['ENV']['HOME'] = os.environ['HOME']
429 pushEnvironment (env)
431 #######################
432 # Dependency Checking #
433 #######################
437 'glib-2.0' : '2.10.1',
438 'gthread-2.0' : '2.10.1',
439 'gtk+-2.0' : '2.8.1',
440 'libxml-2.0' : '2.6.0',
441 'samplerate' : '0.1.0',
445 'libgnomecanvas-2.0' : '2.0'
448 def DependenciesRequiredMessage():
449 print 'You do not have the necessary dependencies required to build ardour'
450 print 'Please consult http://ardour.org/building for more information'
452 def CheckPKGConfig(context, version):
453 context.Message( 'Checking for pkg-config version >= %s... ' %version )
454 ret = context.TryAction('pkg-config --atleast-pkgconfig-version=%s' % version)[0]
455 context.Result( ret )
458 def CheckPKGVersion(context, name, version):
459 context.Message( 'Checking for %s... ' % name )
460 ret = context.TryAction('pkg-config --atleast-version=%s %s' %(version,name) )[0]
461 context.Result( ret )
464 def CheckPKGExists(context, name):
465 context.Message ('Checking for %s...' % name)
466 ret = context.TryAction('pkg-config --exists %s' % name)[0]
470 conf = Configure(env, custom_tests = { 'CheckPKGConfig' : CheckPKGConfig,
471 'CheckPKGVersion' : CheckPKGVersion })
473 # I think a more recent version is needed on win32
474 min_pkg_config_version = '0.8.0'
476 if not conf.CheckPKGConfig(min_pkg_config_version):
477 print 'pkg-config >= %s not found.' % min_pkg_config_version
480 for pkg, version in deps.iteritems():
481 if not conf.CheckPKGVersion( pkg, version ):
482 print '%s >= %s not found.' %(pkg, version)
483 DependenciesRequiredMessage()
488 # ----------------------------------------------------------------------
489 # Construction environment setup
490 # ----------------------------------------------------------------------
494 libraries['core'] = LibraryInfo (CCFLAGS = '-Ilibs')
496 #libraries['sndfile'] = LibraryInfo()
497 #libraries['sndfile'].ParseConfig('pkg-config --cflags --libs sndfile')
499 libraries['lrdf'] = LibraryInfo()
500 libraries['lrdf'].ParseConfig('pkg-config --cflags --libs lrdf')
502 libraries['raptor'] = LibraryInfo()
503 libraries['raptor'].ParseConfig('pkg-config --cflags --libs raptor')
505 libraries['samplerate'] = LibraryInfo()
506 libraries['samplerate'].ParseConfig('pkg-config --cflags --libs samplerate')
508 conf = env.Configure (custom_tests = { 'CheckPKGExists' : CheckPKGExists } )
510 if conf.CheckPKGExists ('fftw3f'):
511 libraries['fftw3f'] = LibraryInfo()
512 libraries['fftw3f'].ParseConfig('pkg-config --cflags --libs fftw3f')
514 if conf.CheckPKGExists ('fftw3'):
515 libraries['fftw3'] = LibraryInfo()
516 libraries['fftw3'].ParseConfig('pkg-config --cflags --libs fftw3')
520 if env['FFT_ANALYSIS']:
522 # Check for fftw3 header as well as the library
525 conf = Configure(libraries['fftw3'])
527 if conf.CheckHeader ('fftw3.h') == False:
528 print ('FFT Analysis cannot be compiled without the FFTW3 headers, which do not seem to be installed')
533 conf = env.Configure(custom_tests = { 'CheckPKGExists' : CheckPKGExists })
535 if conf.CheckPKGExists ('\"slv2 >= 0.6.0\"'):
536 libraries['slv2'] = LibraryInfo()
537 libraries['slv2'].ParseConfig('pkg-config --cflags --libs slv2')
538 env.Append (CCFLAGS="-DHAVE_LV2")
540 print 'Building Ardour with LV2 support requires SLV2 >= 0.6.0'
541 print 'WARNING: SLV2 not found, or too old. Ardour will be built without LV2 support.'
542 print 'Until the 2.3 release, Ardour requires SLV2 out of SVN.'
543 print 'Testing would be very much appreciated! svn co http://svn.drobilla.net/lad/slv2'
547 print 'LV2 support is not enabled. Build with \'scons LV2=1\' to enable.'
549 libraries['jack'] = LibraryInfo()
550 libraries['jack'].ParseConfig('pkg-config --cflags --libs jack')
552 libraries['xml'] = LibraryInfo()
553 libraries['xml'].ParseConfig('pkg-config --cflags --libs libxml-2.0')
555 libraries['xslt'] = LibraryInfo()
556 libraries['xslt'].ParseConfig('pkg-config --cflags --libs libxslt')
558 libraries['glib2'] = LibraryInfo()
559 libraries['glib2'].ParseConfig ('pkg-config --cflags --libs glib-2.0')
560 libraries['glib2'].ParseConfig ('pkg-config --cflags --libs gobject-2.0')
561 libraries['glib2'].ParseConfig ('pkg-config --cflags --libs gmodule-2.0')
562 libraries['glib2'].ParseConfig ('pkg-config --cflags --libs gthread-2.0')
564 libraries['gtk2'] = LibraryInfo()
565 libraries['gtk2'].ParseConfig ('pkg-config --cflags --libs gtk+-2.0')
567 libraries['pango'] = LibraryInfo()
568 libraries['pango'].ParseConfig ('pkg-config --cflags --libs pango')
570 libraries['libgnomecanvas2'] = LibraryInfo()
571 libraries['libgnomecanvas2'].ParseConfig ('pkg-config --cflags --libs libgnomecanvas-2.0')
573 #libraries['flowcanvas'] = LibraryInfo(LIBS='flowcanvas', LIBPATH='#/libs/flowcanvas', CPPPATH='#libs/flowcanvas')
575 # The Ardour Control Protocol Library
577 libraries['ardour_cp'] = LibraryInfo (LIBS='ardour_cp', LIBPATH='#libs/surfaces/control_protocol',
578 CPPPATH='#libs/surfaces/control_protocol')
580 # The Ardour backend/engine
582 libraries['ardour'] = LibraryInfo (LIBS='ardour', LIBPATH='#libs/ardour', CPPPATH='#libs/ardour')
583 libraries['midi++2'] = LibraryInfo (LIBS='midi++', LIBPATH='#libs/midi++2', CPPPATH='#libs/midi++2')
584 libraries['pbd'] = LibraryInfo (LIBS='pbd', LIBPATH='#libs/pbd', CPPPATH='#libs/pbd')
585 libraries['gtkmm2ext'] = LibraryInfo (LIBS='gtkmm2ext', LIBPATH='#libs/gtkmm2ext', CPPPATH='#libs/gtkmm2ext')
588 # SCons should really do this for us
590 conf = env.Configure ()
592 have_cxx = conf.TryAction (Action (str(env['CXX']) + ' --version'))
594 print "This system has no functional C++ compiler. You cannot build Ardour from source without one."
597 print "Congratulations, you have a functioning C++ compiler."
603 # Compiler flags and other system-dependent stuff
607 if env['GPROFILE'] == 1:
608 debug_flags = [ '-g', '-pg' ]
610 debug_flags = [ '-g' ]
612 # guess at the platform, used to define compiler flags
614 config_guess = os.popen("tools/config.guess").read()[:-1]
620 config = config_guess.split ("-")
622 print "system triple: " + config_guess
625 if env['DIST_TARGET'] == 'auto':
626 if config[config_arch] == 'apple':
627 # The [.] matches to the dot after the major version, "." would match any character
628 if re.search ("darwin[0-7][.]", config[config_kernel]) != None:
629 env['DIST_TARGET'] = 'panther'
630 if re.search ("darwin8[.]", config[config_kernel]) != None:
631 env['DIST_TARGET'] = 'tiger'
633 env['DIST_TARGET'] = 'leopard'
635 if re.search ("x86_64", config[config_cpu]) != None:
636 env['DIST_TARGET'] = 'x86_64'
637 elif re.search("i[0-5]86", config[config_cpu]) != None:
638 env['DIST_TARGET'] = 'i386'
639 elif re.search("powerpc", config[config_cpu]) != None:
640 env['DIST_TARGET'] = 'powerpc'
642 env['DIST_TARGET'] = 'i686'
643 print "\n*******************************"
644 print "detected DIST_TARGET = " + env['DIST_TARGET']
645 print "*******************************\n"
648 if config[config_cpu] == 'powerpc' and env['DIST_TARGET'] != 'none':
650 # Apple/PowerPC optimization options
652 # -mcpu=7450 does not reliably work with gcc 3.*
654 if env['DIST_TARGET'] == 'panther' or env['DIST_TARGET'] == 'tiger':
655 if config[config_arch] == 'apple':
656 ## opt_flags.extend ([ "-mcpu=7450", "-faltivec"])
657 # to support g3s but still have some optimization for above
658 opt_flags.extend ([ "-mcpu=G3", "-mtune=7450"])
660 opt_flags.extend ([ "-mcpu=7400", "-maltivec", "-mabi=altivec"])
662 opt_flags.extend([ "-mcpu=750", "-mmultiple" ])
663 opt_flags.extend (["-mhard-float", "-mpowerpc-gfxopt"])
664 opt_flags.extend (["-Os"])
666 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':
668 build_host_supports_sse = 0
670 debug_flags.append ("-DARCH_X86")
671 opt_flags.append ("-DARCH_X86")
673 if config[config_kernel] == 'linux' :
675 if env['DIST_TARGET'] != 'i386':
677 flag_line = os.popen ("cat /proc/cpuinfo | grep '^flags'").read()[:-1]
678 x86_flags = flag_line.split (": ")[1:][0].split ()
680 if "mmx" in x86_flags:
681 opt_flags.append ("-mmmx")
682 if "sse" in x86_flags:
683 build_host_supports_sse = 1
684 if "3dnow" in x86_flags:
685 opt_flags.append ("-m3dnow")
687 if config[config_cpu] == "i586":
688 opt_flags.append ("-march=i586")
689 elif config[config_cpu] == "i686":
690 opt_flags.append ("-march=i686")
692 if ((env['DIST_TARGET'] == 'i686') or (env['DIST_TARGET'] == 'x86_64')) and build_host_supports_sse:
693 opt_flags.extend (["-msse", "-mfpmath=sse", "-DUSE_XMMINTRIN"])
694 debug_flags.extend (["-msse", "-mfpmath=sse", "-DUSE_XMMINTRIN"])
695 # end of processor-specific section
697 # optimization section
698 if env['FPU_OPTIMIZATION']:
699 if env['DIST_TARGET'] == 'tiger' or env['DIST_TARGET'] == 'leopard':
700 opt_flags.append ("-DBUILD_VECLIB_OPTIMIZATIONS");
701 debug_flags.append ("-DBUILD_VECLIB_OPTIMIZATIONS");
702 libraries['core'].Append(LINKFLAGS= '-framework Accelerate')
703 elif env['DIST_TARGET'] == 'i686' or env['DIST_TARGET'] == 'x86_64':
704 opt_flags.append ("-DBUILD_SSE_OPTIMIZATIONS")
705 debug_flags.append ("-DBUILD_SSE_OPTIMIZATIONS")
706 if env['DIST_TARGET'] == 'x86_64':
707 opt_flags.append ("-DUSE_X86_64_ASM")
708 debug_flags.append ("-DUSE_X86_64_ASM")
709 if build_host_supports_sse != 1:
710 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)"
711 # end optimization section
713 # handle x86/x86_64 libdir properly
715 if env['DIST_TARGET'] == 'x86_64':
716 env['LIBDIR']='lib64'
721 # a single way to test if we're on OS X
724 if env['DIST_TARGET'] in ['panther', 'tiger', 'leopard' ]:
726 # force tiger or later, to avoid issues on PPC which defaults
727 # back to 10.1 if we don't tell it otherwise.
728 env.Append (CCFLAGS="-DMAC_OS_X_VERSION_MIN_REQUIRED=1040")
733 # save off guessed arch element in an env
735 env.Append(CONFIG_ARCH=config[config_arch])
739 # ARCH="..." overrides all
742 if env['ARCH'] != '':
743 opt_flags = env['ARCH'].split()
746 # prepend boiler plate optimization flags
751 "-fomit-frame-pointer",
757 if env['DEBUG'] == 1:
758 env.Append(CCFLAGS=" ".join (debug_flags))
759 env.Append(LINKFLAGS=" ".join (debug_flags))
761 env.Append(CCFLAGS=" ".join (opt_flags))
762 env.Append(LINKFLAGS=" ".join (opt_flags))
764 if env['UNIVERSAL'] == 1:
765 env.Append(CCFLAGS="-arch i386 -arch ppc")
766 env.Append(LINKFLAGS="-arch i386 -arch ppc")
772 env.Append(CCFLAGS="-Wall")
773 env.Append(CXXFLAGS="-Woverloaded-virtual")
775 if env['EXTRA_WARN']:
776 env.Append(CCFLAGS="-Wextra -pedantic -ansi")
777 env.Append(CXXFLAGS="-ansi")
778 # env.Append(CFLAGS="-iso")
781 env.Append(CCFLAGS="-DHAVE_LIBLO")
785 # fix scons nitpickiness on APPLE
789 def prep_libcheck(topenv, libinfo):
792 # rationale: GTK-Quartz uses jhbuild and installs to /opt/gtk by default.
793 # All libraries needed should be built against this location
795 libinfo.Append(CPPPATH="/opt/gtk/include", LIBPATH="/opt/gtk/lib")
796 libinfo.Append(CXXFLAGS="-I/opt/gtk/include", LINKFLAGS="-L/opt/gtk/lib")
797 libinfo.Append(CPPPATH="/opt/local/include", LIBPATH="/opt/local/lib")
798 libinfo.Append(CXXFLAGS="-I/opt/local/include", LINKFLAGS="-L/opt/local/lib")
800 prep_libcheck(env, env)
804 # these are part of the Ardour source tree because they are C++
807 libraries['vamp'] = LibraryInfo (LIBS='vampsdk',
808 LIBPATH='#libs/vamp-sdk',
809 CPPPATH='#libs/vamp-sdk')
810 libraries['vamphost'] = LibraryInfo (LIBS='vamphostsdk',
811 LIBPATH='#libs/vamp-sdk',
812 CPPPATH='#libs/vamp-sdk')
814 env['RUBBERBAND'] = False
816 conf = Configure (env)
818 if conf.CheckHeader ('fftw3.h'):
819 env['RUBBERBAND'] = True
820 libraries['rubberband'] = LibraryInfo (LIBS='rubberband',
821 LIBPATH='#libs/rubberband',
822 CPPPATH='#libs/rubberband',
823 CCFLAGS='-DUSE_RUBBERBAND')
826 print "-------------------------------------------------------------------------"
827 print "You do not have the FFTW single-precision development package installed."
828 print "This prevents Ardour from using the Rubberband library for timestretching"
829 print "and pitchshifting. It will fall back on SoundTouch for timestretch, and "
830 print "pitchshifting will not be available."
831 print "-------------------------------------------------------------------------"
839 libraries['usb'] = LibraryInfo ()
840 prep_libcheck(env, libraries['usb'])
842 conf = Configure (libraries['usb'])
843 if conf.CheckLib ('usb', 'usb_interrupt_write'):
848 # check for linux/input.h while we're at it for powermate
849 if conf.CheckHeader('linux/input.h'):
850 have_linux_input = True
852 have_linux_input = False
854 libraries['usb'] = conf.Finish ()
859 libraries['flac'] = LibraryInfo ()
860 prep_libcheck(env, libraries['flac'])
861 libraries['flac'].Append(CPPPATH="/usr/local/include", LIBPATH="/usr/local/lib")
864 # june 1st 2007: look for a function that is in FLAC 1.1.2 and not in later versions
865 # since the version of libsndfile we have internally does not support
866 # the new API that libFLAC has adopted
869 conf = Configure (libraries['flac'])
870 if conf.CheckLib ('FLAC', 'FLAC__seekable_stream_decoder_init', language='CXX'):
871 conf.env.Append(CCFLAGS='-DHAVE_FLAC')
876 libraries['flac'] = conf.Finish ()
878 # or if that fails...
879 #libraries['flac'] = LibraryInfo (LIBS='FLAC')
881 # boost (we don't link against boost, just use some header files)
883 libraries['boost'] = LibraryInfo ()
884 prep_libcheck(env, libraries['boost'])
885 libraries['boost'].Append(CPPPATH="/usr/local/include", LIBPATH="/usr/local/lib")
886 conf = Configure (libraries['boost'])
887 if conf.CheckHeader ('boost/shared_ptr.hpp', language='CXX') == False:
888 print "Boost header files do not appear to be installed."
891 libraries['boost'] = conf.Finish ()
897 libraries['lo'] = LibraryInfo ()
898 prep_libcheck(env, libraries['lo'])
900 conf = Configure (libraries['lo'])
901 if conf.CheckLib ('lo', 'lo_server_new') == False:
902 print "liblo does not appear to be installed."
905 libraries['lo'] = conf.Finish ()
910 libraries['dmalloc'] = LibraryInfo ()
911 prep_libcheck(env, libraries['dmalloc'])
914 # look for the threaded version
917 conf = Configure (libraries['dmalloc'])
918 if conf.CheckLib ('dmallocth', 'dmalloc_shutdown'):
919 have_libdmalloc = True
921 have_libdmalloc = False
923 libraries['dmalloc'] = conf.Finish ()
926 # Audio/MIDI library (needed for MIDI, since audio is all handled via JACK)
929 conf = Configure(env)
931 if conf.CheckCHeader('alsa/asoundlib.h'):
932 libraries['sysmidi'] = LibraryInfo (LIBS='asound')
933 env['SYSMIDI'] = 'ALSA Sequencer'
934 subst_dict['%MIDITAG%'] = "seq"
935 subst_dict['%MIDITYPE%'] = "alsa/sequencer"
936 elif conf.CheckCHeader('/System/Library/Frameworks/CoreMIDI.framework/Headers/CoreMIDI.h'):
937 # this line is needed because scons can't handle -framework in ParseConfig() yet.
939 # We need Carbon as well as the rest
940 libraries['sysmidi'] = LibraryInfo (
941 LINKFLAGS = ' -framework CoreMIDI -framework CoreFoundation -framework CoreAudio -framework CoreServices -framework AudioUnit -framework AudioToolbox -framework Carbon -bind_at_load' )
943 libraries['sysmidi'] = LibraryInfo (
944 LINKFLAGS = ' -framework CoreMIDI -framework CoreFoundation -framework CoreAudio -framework CoreServices -framework AudioUnit -framework AudioToolbox -bind_at_load' )
945 env['SYSMIDI'] = 'CoreMIDI'
946 subst_dict['%MIDITAG%'] = "ardour"
947 subst_dict['%MIDITYPE%'] = "coremidi"
949 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."
958 'sigc++-2.0' : '2.0',
960 'libgnomecanvasmm-2.6' : '2.12.0'
963 conf = Configure(env, custom_tests = { 'CheckPKGConfig' : CheckPKGConfig,
964 'CheckPKGVersion' : CheckPKGVersion })
966 for pkg, version in syslibdeps.iteritems():
967 if not conf.CheckPKGVersion( pkg, version ):
968 print '%s >= %s not found.' %(pkg, version)
969 DependenciesRequiredMessage()
974 libraries['sigc2'] = LibraryInfo()
975 libraries['sigc2'].ParseConfig('pkg-config --cflags --libs sigc++-2.0')
976 libraries['glibmm2'] = LibraryInfo()
977 libraries['glibmm2'].ParseConfig('pkg-config --cflags --libs glibmm-2.4')
978 libraries['cairomm'] = LibraryInfo()
979 libraries['cairomm'].ParseConfig('pkg-config --cflags --libs cairomm-1.0')
980 libraries['gdkmm2'] = LibraryInfo()
981 libraries['gdkmm2'].ParseConfig ('pkg-config --cflags --libs gdkmm-2.4')
982 libraries['gtkmm2'] = LibraryInfo()
983 libraries['gtkmm2'].ParseConfig ('pkg-config --cflags --libs gtkmm-2.4')
984 libraries['atkmm'] = LibraryInfo()
985 libraries['atkmm'].ParseConfig ('pkg-config --cflags --libs atkmm-1.6')
986 libraries['pangomm'] = LibraryInfo()
987 libraries['pangomm'].ParseConfig ('pkg-config --cflags --libs pangomm-1.4')
988 libraries['libgnomecanvasmm'] = LibraryInfo()
989 libraries['libgnomecanvasmm'].ParseConfig ('pkg-config --cflags --libs libgnomecanvasmm-2.6')
992 # cannot use system one for the time being
995 libraries['sndfile-ardour'] = LibraryInfo(LIBS='libsndfile-ardour',
996 LIBPATH='#libs/libsndfile',
997 CPPPATH=['#libs/libsndfile/src'])
999 # libraries['libglademm'] = LibraryInfo()
1000 # libraries['libglademm'].ParseConfig ('pkg-config --cflags --libs libglademm-2.4')
1002 # libraries['flowcanvas'] = LibraryInfo(LIBS='flowcanvas', LIBPATH='#/libs/flowcanvas', CPPPATH='#libs/flowcanvas')
1003 libraries['soundtouch'] = LibraryInfo()
1004 #libraries['soundtouch'].ParseConfig ('pkg-config --cflags --libs soundtouch-1.0')
1005 # Comment the previous line and uncomment this for Debian:
1006 libraries['soundtouch'].ParseConfig ('pkg-config --cflags --libs libSoundTouch')
1008 libraries['appleutility'] = LibraryInfo(LIBS='libappleutility',
1009 LIBPATH='#libs/appleutility',
1010 CPPPATH='#libs/appleutility')
1022 'libs/vamp-plugins/',
1023 # these are unconditionally included but have
1024 # tests internally to avoid compilation etc
1028 # this is unconditionally included but has
1029 # tests internally to avoid compilation etc
1030 # if COREAUDIO is not set
1035 # 'libs/flowcanvas',
1042 libraries['sigc2'] = LibraryInfo(LIBS='sigc++2',
1043 LIBPATH='#libs/sigc++2',
1044 CPPPATH='#libs/sigc++2')
1045 libraries['glibmm2'] = LibraryInfo(LIBS='glibmm2',
1046 LIBPATH='#libs/glibmm2',
1047 CPPPATH='#libs/glibmm2')
1048 libraries['pangomm'] = LibraryInfo(LIBS='pangomm',
1049 LIBPATH='#libs/gtkmm2/pango',
1050 CPPPATH='#libs/gtkmm2/pango')
1051 libraries['atkmm'] = LibraryInfo(LIBS='atkmm',
1052 LIBPATH='#libs/gtkmm2/atk',
1053 CPPPATH='#libs/gtkmm2/atk')
1054 libraries['gdkmm2'] = LibraryInfo(LIBS='gdkmm2',
1055 LIBPATH='#libs/gtkmm2/gdk',
1056 CPPPATH='#libs/gtkmm2/gdk')
1057 libraries['gtkmm2'] = LibraryInfo(LIBS='gtkmm2',
1058 LIBPATH="#libs/gtkmm2/gtk",
1059 CPPPATH='#libs/gtkmm2/gtk/')
1060 libraries['libgnomecanvasmm'] = LibraryInfo(LIBS='libgnomecanvasmm',
1061 LIBPATH='#libs/libgnomecanvasmm',
1062 CPPPATH='#libs/libgnomecanvasmm')
1064 libraries['soundtouch'] = LibraryInfo(LIBS='soundtouch',
1065 LIBPATH='#libs/soundtouch',
1066 CPPPATH=['#libs', '#libs/soundtouch'])
1067 libraries['sndfile-ardour'] = LibraryInfo(LIBS='libsndfile-ardour',
1068 LIBPATH='#libs/libsndfile',
1069 CPPPATH=['#libs/libsndfile', '#libs/libsndfile/src'])
1070 # libraries['libglademm'] = LibraryInfo(LIBS='libglademm',
1071 # LIBPATH='#libs/libglademm',
1072 # CPPPATH='#libs/libglademm')
1073 libraries['appleutility'] = LibraryInfo(LIBS='libappleutility',
1074 LIBPATH='#libs/appleutility',
1075 CPPPATH='#libs/appleutility')
1088 'libs/vamp-plugins/',
1089 # these are unconditionally included but have
1090 # tests internally to avoid compilation etc
1094 # this is unconditionally included but has
1095 # tests internally to avoid compilation etc
1096 # if COREAUDIO is not set
1102 'libs/gtkmm2/pango',
1106 'libs/libgnomecanvasmm',
1113 # * always build the LGPL control protocol lib, since we link against it from libardour
1114 # * ditto for generic MIDI
1115 # * tranzport checks whether it should build internally, but we need here so that
1116 # its included in the tarball
1119 surface_subdirs = [ 'libs/surfaces/control_protocol',
1120 'libs/surfaces/generic_midi',
1121 'libs/surfaces/tranzport',
1122 'libs/surfaces/mackie',
1123 'libs/surfaces/powermate'
1128 env['TRANZPORT'] = 1
1130 env['TRANZPORT'] = 0
1131 print 'Disabled building Tranzport code because libusb could not be found'
1133 if have_linux_input:
1134 env['POWERMATE'] = 1
1136 env['POWERMATE'] = 0
1137 print 'Disabled building Powermate code because linux/input.h could not be found'
1139 if os.access ('libs/surfaces/sony9pin', os.F_OK):
1140 surface_subdirs += [ 'libs/surfaces/sony9pin' ]
1142 env['POWERMATE'] = 0
1143 env['TRANZPORT'] = 0
1146 # timestretch libraries
1149 timefx_subdirs = ['libs/soundtouch']
1150 if env['RUBBERBAND']:
1151 timefx_subdirs += ['libs/rubberband']
1153 opts.Save('scache.conf', env)
1154 Help(opts.GenerateHelpText(env))
1156 final_prefix = '$PREFIX'
1159 install_prefix = '$DESTDIR/$PREFIX'
1161 install_prefix = env['PREFIX']
1163 subst_dict['%INSTALL_PREFIX%'] = install_prefix;
1164 subst_dict['%FINAL_PREFIX%'] = final_prefix;
1165 subst_dict['%PREFIX%'] = final_prefix;
1167 if env['PREFIX'] == '/usr':
1168 final_config_prefix = '/etc'
1170 final_config_prefix = env['PREFIX'] + '/etc'
1172 config_prefix = '$DESTDIR' + final_config_prefix
1175 # everybody needs this
1178 env.Merge ([ libraries['core'] ])
1185 conf = Configure (env)
1187 nls_error = 'This system is not configured for internationalized applications. An english-only version will be built:'
1188 print 'Checking for internationalization support ...'
1189 have_gettext = conf.TryAction(Action('xgettext --version'))
1190 if have_gettext[0] != 1:
1191 nls_error += ' No xgettext command.'
1194 print "Found xgettext"
1196 have_msgmerge = conf.TryAction(Action('msgmerge --version'))
1197 if have_msgmerge[0] != 1:
1198 nls_error += ' No msgmerge command.'
1201 print "Found msgmerge"
1203 if not conf.CheckCHeader('libintl.h'):
1204 nls_error += ' No libintl.h.'
1210 print "International version will be built."
1214 env.Append(CCFLAGS="-DENABLE_NLS")
1216 Export('env install_prefix final_prefix config_prefix final_config_prefix libraries i18n ardour_version subst_dict use_flac')
1219 # the configuration file may be system dependent
1222 conf = env.Configure ()
1224 if conf.CheckCHeader('/System/Library/Frameworks/CoreAudio.framework/Versions/A/Headers/CoreAudio.h'):
1225 subst_dict['%JACK_INPUT%'] = "coreaudio:Built-in Audio:in"
1226 subst_dict['%JACK_OUTPUT%'] = "coreaudio:Built-in Audio:out"
1228 subst_dict['%JACK_INPUT%'] = "alsa_pcm:playback_"
1229 subst_dict['%JACK_OUTPUT%'] = "alsa_pcm:capture_"
1231 # posix_memalign available
1232 if not conf.CheckFunc('posix_memalign'):
1233 print 'Did not find posix_memalign(), using malloc'
1234 env.Append(CCFLAGS='-DNO_POSIX_MEMALIGN')
1239 # generate the per-user and system rc files from the same source
1241 sysrcbuild = env.SubstInFile ('ardour_system.rc','ardour.rc.in', SUBST_DICT = subst_dict)
1243 # add to the substitution dictionary
1245 subst_dict['%VERSION%'] = ardour_version[0:3]
1246 subst_dict['%EXTRA_VERSION%'] = ardour_version[3:]
1247 subst_dict['%REVISION_STRING%'] = ''
1248 if os.path.exists('.svn'):
1249 subst_dict['%REVISION_STRING%'] = '.' + fetch_svn_revision ('.') + 'svn'
1251 # specbuild = env.SubstInFile ('ardour.spec','ardour.spec.in', SUBST_DICT = subst_dict)
1253 the_revision = env.Command ('frobnicatory_decoy', [], create_stored_revision)
1254 remove_ardour = env.Command ('frobnicatory_decoy2', [],
1255 [ Delete ('$PREFIX/etc/ardour2'),
1256 Delete ('$PREFIX/lib/ardour2'),
1257 Delete ('$PREFIX/bin/ardour2')])
1259 env.Alias('revision', the_revision)
1260 env.Alias('install', env.Install(os.path.join(config_prefix, 'ardour2'), 'ardour_system.rc'))
1261 env.Alias('uninstall', remove_ardour)
1263 Default (sysrcbuild)
1267 Precious (env['DISTTREE'])
1269 env.Distribute (env['DISTTREE'],
1270 [ 'SConstruct', 'svn_revision.h',
1271 'COPYING', 'PACKAGER_README', 'README',
1273 'tools/config.guess',
1274 'icons/icon/ardour_icon_mac_mask.png',
1275 'icons/icon/ardour_icon_mac.png',
1276 'icons/icon/ardour_icon_tango_16px_blue.png',
1277 'icons/icon/ardour_icon_tango_16px_red.png',
1278 'icons/icon/ardour_icon_tango_22px_blue.png',
1279 'icons/icon/ardour_icon_tango_22px_red.png',
1280 'icons/icon/ardour_icon_tango_32px_blue.png',
1281 'icons/icon/ardour_icon_tango_32px_red.png',
1282 'icons/icon/ardour_icon_tango_48px_blue.png',
1283 'icons/icon/ardour_icon_tango_48px_red.png'
1285 glob.glob ('DOCUMENTATION/AUTHORS*') +
1286 glob.glob ('DOCUMENTATION/CONTRIBUTORS*') +
1287 glob.glob ('DOCUMENTATION/TRANSLATORS*') +
1288 glob.glob ('DOCUMENTATION/BUILD*') +
1289 glob.glob ('DOCUMENTATION/FAQ*') +
1290 glob.glob ('DOCUMENTATION/README*')
1293 srcdist = env.Tarball(env['TARBALL'], [ env['DISTTREE'], the_revision ])
1294 env.Alias ('srctar', srcdist)
1297 # don't leave the distree around
1300 env.AddPreAction (env['DISTTREE'], Action ('rm -rf ' + str (File (env['DISTTREE']))))
1301 env.AddPostAction (srcdist, Action ('rm -rf ' + str (File (env['DISTTREE']))))
1307 for subdir in coredirs:
1308 SConscript (subdir + '/SConscript')
1310 for sublistdir in [ subdirs, timefx_subdirs, gtk_subdirs, surface_subdirs ]:
1311 for subdir in sublistdir:
1312 SConscript (subdir + '/SConscript')
1315 env.Clean ('scrub', [ 'scache.conf', '.sconf_temp', '.sconsign.dblite', 'config.log'])