17 EnsureSConsVersion(0, 96)
19 ardour_version = '2.1'
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('DEBUG', 'Set to build with debugging information and no optimizations', 0),
35 PathOption('DESTDIR', 'Set the intermediate install "prefix"', '/'),
36 EnumOption('DIST_TARGET', 'Build target for cross compiling packagers', 'auto', allowed_values=('auto', 'i386', 'i686', 'x86_64', 'powerpc', 'tiger', 'panther', 'none' ), ignorecase=2),
37 BoolOption('DMALLOC', 'Compile and link using the dmalloc library', 0),
38 BoolOption('EXTRA_WARN', 'Compile with -Wextra, -ansi, and -pedantic. Might break compilation. For pedants', 0),
39 BoolOption('FFT_ANALYSIS', 'Include FFT analysis window', 0),
40 BoolOption('FPU_OPTIMIZATION', 'Build runtime checked assembler code', 1),
41 BoolOption('LIBLO', 'Compile with support for liblo library', 1),
42 BoolOption('NLS', 'Set to turn on i18n support', 1),
43 PathOption('PREFIX', 'Set the install "prefix"', '/usr/local'),
44 BoolOption('SURFACES', 'Build support for control surfaces', 1),
45 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),
46 BoolOption('UNIVERSAL', 'Compile as universal binary. Requires that external libraries are already universal.', 0),
47 BoolOption('VERSIONED', 'Add revision information to ardour/gtk executable name inside the build directory', 0),
48 BoolOption('VST', 'Compile with support for VST', 0),
49 BoolOption('GPROFILE', 'Compile with support for gprofile (Developers only)', 0),
50 BoolOption('TRANZPORT', 'Compile with support for Frontier Designs (if libusb is available)', 1)
53 #----------------------------------------------------------------------
54 # a handy helper that provides a way to merge compile/link information
55 # from multiple different "environments"
56 #----------------------------------------------------------------------
58 class LibraryInfo(Environment):
59 def __init__(self,*args,**kw):
60 Environment.__init__ (self,*args,**kw)
62 def Merge (self,others):
64 self.Append (LIBS = other.get ('LIBS',[]))
65 self.Append (LIBPATH = other.get ('LIBPATH', []))
66 self.Append (CPPPATH = other.get('CPPPATH', []))
67 self.Append (LINKFLAGS = other.get('LINKFLAGS', []))
68 self.Append (CCFLAGS = other.get('CCFLAGS', []))
69 self.Replace(LIBPATH = list(Set(self.get('LIBPATH', []))))
70 self.Replace(CPPPATH = list(Set(self.get('CPPPATH',[]))))
71 #doing LINKFLAGS breaks -framework
72 #doing LIBS break link order dependency
74 def ENV_update(self, src_ENV):
75 for k in src_ENV.keys():
76 if k in self['ENV'].keys() and k in [ 'PATH', 'LD_LIBRARY_PATH',
78 self['ENV'][k]=SCons.Util.AppendPath(self['ENV'][k], src_ENV[k])
80 self['ENV'][k]=src_ENV[k]
82 env = LibraryInfo (options = opts,
84 VERSION = ardour_version,
85 TARBALL='ardour-' + ardour_version + '.tar.bz2',
87 DISTTREE = '#ardour-' + ardour_version,
88 DISTCHECKDIR = '#ardour-' + ardour_version + '/check'
91 env.ENV_update(os.environ)
93 #----------------------------------------------------------------------
95 #----------------------------------------------------------------------
97 # Handy subst-in-file builder
100 def do_subst_in_file(targetfile, sourcefile, dict):
101 """Replace all instances of the keys of dict with their values.
102 For example, if dict is {'%VERSION%': '1.2345', '%BASE%': 'MyProg'},
103 then all instances of %VERSION% in the file will be replaced with 1.2345 etc.
106 f = open(sourcefile, 'rb')
110 raise SCons.Errors.UserError, "Can't read source file %s"%sourcefile
111 for (k,v) in dict.items():
112 contents = re.sub(k, v, contents)
114 f = open(targetfile, 'wb')
118 raise SCons.Errors.UserError, "Can't write target file %s"%targetfile
121 def subst_in_file(target, source, env):
122 if not env.has_key('SUBST_DICT'):
123 raise SCons.Errors.UserError, "SubstInFile requires SUBST_DICT to be set."
124 d = dict(env['SUBST_DICT']) # copy it
125 for (k,v) in d.items():
127 d[k] = env.subst(v())
128 elif SCons.Util.is_String(v):
131 raise SCons.Errors.UserError, "SubstInFile: key %s: %s must be a string or callable"%(k, repr(v))
132 for (t,s) in zip(target, source):
133 return do_subst_in_file(str(t), str(s), d)
135 def subst_in_file_string(target, source, env):
136 """This is what gets printed on the console."""
137 return '\n'.join(['Substituting vars from %s into %s'%(str(s), str(t))
138 for (t,s) in zip(target, source)])
140 def subst_emitter(target, source, env):
141 """Add dependency from substituted SUBST_DICT to target.
142 Returns original target, source tuple unchanged.
144 d = env['SUBST_DICT'].copy() # copy it
145 for (k,v) in d.items():
147 d[k] = env.subst(v())
148 elif SCons.Util.is_String(v):
150 Depends(target, SCons.Node.Python.Value(d))
151 # Depends(target, source) # this doesn't help the install-sapphire-linux.sh problem
152 return target, source
154 subst_action = Action (subst_in_file, subst_in_file_string)
155 env['BUILDERS']['SubstInFile'] = Builder(action=subst_action, emitter=subst_emitter)
158 # internationalization
161 # po_builder: builder function to copy po files to the parent directory while updating them
163 # first source: .po file
164 # second source: .pot file
167 def po_builder(target,source,env):
168 os.spawnvp (os.P_WAIT, 'cp', ['cp', str(source[0]), str(target[0])])
174 print 'Updating ' + str(target[0])
175 return os.spawnvp (os.P_WAIT, 'msgmerge', args)
177 po_bld = Builder (action = po_builder)
178 env.Append(BUILDERS = {'PoBuild' : po_bld})
180 # mo_builder: builder function for (binary) message catalogs (.mo)
182 # first source: .po file
185 def mo_builder(target,source,env):
189 target[0].get_path(),
192 return os.spawnvp (os.P_WAIT, 'msgfmt', args)
194 mo_bld = Builder (action = mo_builder)
195 env.Append(BUILDERS = {'MoBuild' : mo_bld})
197 # pot_builder: builder function for message templates (.pot)
199 # source: list of C/C++ etc. files to extract messages from
202 def pot_builder(target,source,env):
207 '-o', target[0].get_path(),
208 "--default-domain=" + env['PACKAGE'],
209 '--copyright-holder="Paul Davis"' ]
210 args += [ src.get_path() for src in source ]
212 return os.spawnvp (os.P_WAIT, 'xgettext', args)
214 pot_bld = Builder (action = pot_builder)
215 env.Append(BUILDERS = {'PotBuild' : pot_bld})
218 # utility function, not a builder
221 def i18n (buildenv, sources, installenv):
222 domain = buildenv['PACKAGE']
223 potfile = buildenv['POTFILE']
225 installenv.Alias ('potupdate', buildenv.PotBuild (potfile, sources))
227 p_oze = [ os.path.basename (po) for po in glob.glob ('po/*.po') ]
228 languages = [ po.replace ('.po', '') for po in p_oze ]
230 for po_file in p_oze:
231 buildenv.PoBuild(po_file, ['po/'+po_file, potfile])
232 mo_file = po_file.replace (".po", ".mo")
233 installenv.Alias ('install', buildenv.MoBuild (mo_file, po_file))
235 for lang in languages:
236 modir = (os.path.join (install_prefix, 'share/locale/' + lang + '/LC_MESSAGES/'))
237 moname = domain + '.mo'
238 installenv.Alias('install', installenv.InstallAs (os.path.join (modir, moname), lang + '.mo'))
241 def fetch_svn_revision (path):
245 cmd += " | awk '/^Revision:/ { print $2}'"
246 return commands.getoutput (cmd)
248 def create_stored_revision (target = None, source = None, env = None):
249 if os.path.exists('.svn'):
250 rev = fetch_svn_revision ('.');
252 text = "#ifndef __ardour_svn_revision_h__\n"
253 text += "#define __ardour_svn_revision_h__\n"
254 text += "static const char* ardour_svn_revision = \"" + rev + "\";\n";
256 print '============> writing svn revision info to svn_revision.h\n'
257 o = file ('svn_revision.h', 'w')
261 print "Could not open svn_revision.h for writing\n"
264 print "You cannot use \"scons revision\" on without using a checked out"
265 print "copy of the Ardour source code repository"
269 # A generic builder for version.cc files
271 # note: requires that DOMAIN, MAJOR, MINOR, MICRO are set in the construction environment
272 # note: assumes one source files, the header that declares the version variables
275 def version_builder (target, source, env):
277 text = "int " + env['DOMAIN'] + "_major_version = " + str (env['MAJOR']) + ";\n"
278 text += "int " + env['DOMAIN'] + "_minor_version = " + str (env['MINOR']) + ";\n"
279 text += "int " + env['DOMAIN'] + "_micro_version = " + str (env['MICRO']) + ";\n"
282 o = file (target[0].get_path(), 'w')
286 print "Could not open", target[0].get_path(), " for writing\n"
289 text = "#ifndef __" + env['DOMAIN'] + "_version_h__\n"
290 text += "#define __" + env['DOMAIN'] + "_version_h__\n"
291 text += "extern const char* " + env['DOMAIN'] + "_revision;\n"
292 text += "extern int " + env['DOMAIN'] + "_major_version;\n"
293 text += "extern int " + env['DOMAIN'] + "_minor_version;\n"
294 text += "extern int " + env['DOMAIN'] + "_micro_version;\n"
295 text += "#endif /* __" + env['DOMAIN'] + "_version_h__ */\n"
298 o = file (target[1].get_path(), 'w')
302 print "Could not open", target[1].get_path(), " for writing\n"
307 version_bld = Builder (action = version_builder)
308 env.Append (BUILDERS = {'VersionBuild' : version_bld})
311 # a builder that makes a hard link from the 'source' executable to a name with
312 # a "build ID" based on the most recent CVS activity that might be reasonably
313 # related to version activity. this relies on the idea that the SConscript
314 # file that builds the executable is updated with new version info and committed
315 # to the source code repository whenever things change.
318 def versioned_builder(target,source,env):
319 w, r = os.popen2( "LANG= svn info | awk '/^Revision:/ { print $2}'")
321 last_revision = r.readline().strip()
324 if last_revision == "":
325 print "No SVN info found - versioned executable cannot be built"
328 print "The current build ID is " + last_revision
330 tagged_executable = source[0].get_path() + '-' + last_revision
332 if os.path.exists (tagged_executable):
333 print "Replacing existing executable with the same build tag."
334 os.unlink (tagged_executable)
336 return os.link (source[0].get_path(), tagged_executable)
338 verbuild = Builder (action = versioned_builder)
339 env.Append (BUILDERS = {'VersionedExecutable' : verbuild})
342 # source tar file builder
345 def distcopy (target, source, env):
346 treedir = str (target[0])
350 except OSError, (errnum, strerror):
351 if errnum != errno.EEXIST:
352 print 'mkdir ', treedir, ':', strerror
356 # we don't know what characters might be in the file names
357 # so quote them all before passing them to the shell
359 all_files = ([ str(s) for s in source ])
360 cmd += " ".join ([ "'%s'" % quoted for quoted in all_files])
361 cmd += ' | (cd ' + treedir + ' && tar xf -)'
365 def tarballer (target, source, env):
366 cmd = 'tar -jcf ' + str (target[0]) + ' ' + str(source[0]) + " --exclude '*~'"
367 print 'running ', cmd, ' ... '
371 dist_bld = Builder (action = distcopy,
372 target_factory = SCons.Node.FS.default_fs.Entry,
373 source_factory = SCons.Node.FS.default_fs.Entry,
376 tarball_bld = Builder (action = tarballer,
377 target_factory = SCons.Node.FS.default_fs.Entry,
378 source_factory = SCons.Node.FS.default_fs.Entry)
380 env.Append (BUILDERS = {'Distribute' : dist_bld})
381 env.Append (BUILDERS = {'Tarball' : tarball_bld})
384 # Make sure they know what they are doing
388 if os.path.isfile('.personal_use_only'):
389 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."
391 sys.stdout.write ("Are you building Ardour for personal use (rather than distribution to others)? [no]: ")
392 answer = sys.stdin.readline ()
393 answer = answer.rstrip().strip()
394 if answer == "yes" or answer == "y":
395 fh = open('.personal_use_only', 'w')
397 print "OK, VST support will be enabled"
399 print 'You cannot build Ardour with VST support for distribution to others.\nIt is a violation of several different licenses. Build with VST=false.'
402 if os.path.isfile('.personal_use_only'):
403 os.remove('.personal_use_only')
406 #######################
407 # Dependency Checking #
408 #######################
412 'glib-2.0' : '2.10.1',
413 'gthread-2.0' : '2.10.1',
414 'gtk+-2.0' : '2.8.1',
415 'libxml-2.0' : '2.6.0',
416 'samplerate' : '0.1.0',
420 'libgnomecanvas-2.0' : '2.0'
423 def DependenciesRequiredMessage():
424 print 'You do not have the necessary dependencies required to build ardour'
425 print 'Please consult http://ardour.org/building for more information'
427 def CheckPKGConfig(context, version):
428 context.Message( 'Checking for pkg-config version >= %s... ' %version )
429 ret = context.TryAction('pkg-config --atleast-pkgconfig-version=%s' % version)[0]
430 context.Result( ret )
433 def CheckPKGVersion(context, name, version):
434 context.Message( 'Checking for %s... ' % name )
435 ret = context.TryAction('pkg-config --atleast-version=%s %s' %(version,name) )[0]
436 context.Result( ret )
439 def CheckPKGExists(context, name):
440 context.Message ('Checking for %s...' % name)
441 ret = context.TryAction('pkg-config --exists %s' % name)
442 print ("Result was [%s]" % ret[1])
443 context.Result (ret[0])
446 conf = Configure(env, custom_tests = { 'CheckPKGConfig' : CheckPKGConfig,
447 'CheckPKGVersion' : CheckPKGVersion })
449 # I think a more recent version is needed on win32
450 min_pkg_config_version = '0.8.0'
452 if not conf.CheckPKGConfig(min_pkg_config_version):
453 print 'pkg-config >= %s not found.' % min_pkg_config_version
456 for pkg, version in deps.iteritems():
457 if not conf.CheckPKGVersion( pkg, version ):
458 print '%s >= %s not found.' %(pkg, version)
459 DependenciesRequiredMessage()
464 # ----------------------------------------------------------------------
465 # Construction environment setup
466 # ----------------------------------------------------------------------
470 libraries['core'] = LibraryInfo (CCFLAGS = '-Ilibs')
472 #libraries['sndfile'] = LibraryInfo()
473 #libraries['sndfile'].ParseConfig('pkg-config --cflags --libs sndfile')
475 libraries['lrdf'] = LibraryInfo()
476 libraries['lrdf'].ParseConfig('pkg-config --cflags --libs lrdf')
478 libraries['raptor'] = LibraryInfo()
479 libraries['raptor'].ParseConfig('pkg-config --cflags --libs raptor')
481 libraries['samplerate'] = LibraryInfo()
482 libraries['samplerate'].ParseConfig('pkg-config --cflags --libs samplerate')
484 conf = env.Configure (custom_tests = { 'CheckPKGExists' : CheckPKGExists } )
486 if conf.CheckPKGExists ('fftw3f'):
487 libraries['fftw3f'] = LibraryInfo()
488 libraries['fftw3f'].ParseConfig('pkg-config --cflags --libs fftw3f')
490 if conf.CheckPKGExists ('fftw3'):
491 libraries['fftw3'] = LibraryInfo()
492 libraries['fftw3'].ParseConfig('pkg-config --cflags --libs fftw3')
496 if env['FFT_ANALYSIS']:
498 # Check for fftw3 header as well as the library
501 conf = Configure(libraries['fftw3'])
503 if conf.CheckHeader ('fftw3.h') == False:
504 print ('FFT Analysis cannot be compiled without the FFTW3 headers, which do not seem to be installed')
508 libraries['jack'] = LibraryInfo()
509 libraries['jack'].ParseConfig('pkg-config --cflags --libs jack')
511 libraries['xml'] = LibraryInfo()
512 libraries['xml'].ParseConfig('pkg-config --cflags --libs libxml-2.0')
514 libraries['xslt'] = LibraryInfo()
515 libraries['xslt'].ParseConfig('pkg-config --cflags --libs libxslt')
517 libraries['glib2'] = LibraryInfo()
518 libraries['glib2'].ParseConfig ('pkg-config --cflags --libs glib-2.0')
519 libraries['glib2'].ParseConfig ('pkg-config --cflags --libs gobject-2.0')
520 libraries['glib2'].ParseConfig ('pkg-config --cflags --libs gmodule-2.0')
521 libraries['glib2'].ParseConfig ('pkg-config --cflags --libs gthread-2.0')
523 libraries['gtk2'] = LibraryInfo()
524 libraries['gtk2'].ParseConfig ('pkg-config --cflags --libs gtk+-2.0')
526 libraries['pango'] = LibraryInfo()
527 libraries['pango'].ParseConfig ('pkg-config --cflags --libs pango')
529 libraries['libgnomecanvas2'] = LibraryInfo()
530 libraries['libgnomecanvas2'].ParseConfig ('pkg-config --cflags --libs libgnomecanvas-2.0')
532 #libraries['flowcanvas'] = LibraryInfo(LIBS='flowcanvas', LIBPATH='#/libs/flowcanvas', CPPPATH='#libs/flowcanvas')
534 # The Ardour Control Protocol Library
536 libraries['ardour_cp'] = LibraryInfo (LIBS='ardour_cp', LIBPATH='#libs/surfaces/control_protocol',
537 CPPPATH='#libs/surfaces/control_protocol')
539 # The Ardour backend/engine
541 libraries['ardour'] = LibraryInfo (LIBS='ardour', LIBPATH='#libs/ardour', CPPPATH='#libs/ardour')
542 libraries['midi++2'] = LibraryInfo (LIBS='midi++', LIBPATH='#libs/midi++2', CPPPATH='#libs/midi++2')
543 libraries['pbd'] = LibraryInfo (LIBS='pbd', LIBPATH='#libs/pbd', CPPPATH='#libs/pbd')
544 libraries['gtkmm2ext'] = LibraryInfo (LIBS='gtkmm2ext', LIBPATH='#libs/gtkmm2ext', CPPPATH='#libs/gtkmm2ext')
547 # SCons should really do this for us
549 conf = env.Configure ()
551 have_cxx = conf.TryAction (Action (str(env['CXX']) + ' --version'))
553 print "This system has no functional C++ compiler. You cannot build Ardour from source without one."
556 print "Congratulations, you have a functioning C++ compiler."
562 # Compiler flags and other system-dependent stuff
566 if env['GPROFILE'] == 1:
567 debug_flags = [ '-g', '-pg' ]
569 debug_flags = [ '-g' ]
571 # guess at the platform, used to define compiler flags
573 config_guess = os.popen("tools/config.guess").read()[:-1]
579 config = config_guess.split ("-")
581 print "system triple: " + config_guess
584 if env['DIST_TARGET'] == 'auto':
585 if config[config_arch] == 'apple':
586 # The [.] matches to the dot after the major version, "." would match any character
587 if re.search ("darwin[0-7][.]", config[config_kernel]) != None:
588 env['DIST_TARGET'] = 'panther'
590 env['DIST_TARGET'] = 'tiger'
592 if re.search ("x86_64", config[config_cpu]) != None:
593 env['DIST_TARGET'] = 'x86_64'
594 elif re.search("i[0-5]86", config[config_cpu]) != None:
595 env['DIST_TARGET'] = 'i386'
596 elif re.search("powerpc", config[config_cpu]) != None:
597 env['DIST_TARGET'] = 'powerpc'
599 env['DIST_TARGET'] = 'i686'
600 print "\n*******************************"
601 print "detected DIST_TARGET = " + env['DIST_TARGET']
602 print "*******************************\n"
605 if config[config_cpu] == 'powerpc' and env['DIST_TARGET'] != 'none':
607 # Apple/PowerPC optimization options
609 # -mcpu=7450 does not reliably work with gcc 3.*
611 if env['DIST_TARGET'] == 'panther' or env['DIST_TARGET'] == 'tiger':
612 if config[config_arch] == 'apple':
613 ## opt_flags.extend ([ "-mcpu=7450", "-faltivec"])
614 # to support g3s but still have some optimization for above
615 opt_flags.extend ([ "-mcpu=G3", "-mtune=7450"])
617 opt_flags.extend ([ "-mcpu=7400", "-maltivec", "-mabi=altivec"])
619 opt_flags.extend([ "-mcpu=750", "-mmultiple" ])
620 opt_flags.extend (["-mhard-float", "-mpowerpc-gfxopt"])
621 opt_flags.extend (["-Os"])
623 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':
625 build_host_supports_sse = 0
627 debug_flags.append ("-DARCH_X86")
628 opt_flags.append ("-DARCH_X86")
630 if config[config_kernel] == 'linux' :
632 if env['DIST_TARGET'] != 'i386':
634 flag_line = os.popen ("cat /proc/cpuinfo | grep '^flags'").read()[:-1]
635 x86_flags = flag_line.split (": ")[1:][0].split ()
637 if "mmx" in x86_flags:
638 opt_flags.append ("-mmmx")
639 if "sse" in x86_flags:
640 build_host_supports_sse = 1
641 if "3dnow" in x86_flags:
642 opt_flags.append ("-m3dnow")
644 if config[config_cpu] == "i586":
645 opt_flags.append ("-march=i586")
646 elif config[config_cpu] == "i686":
647 opt_flags.append ("-march=i686")
649 if ((env['DIST_TARGET'] == 'i686') or (env['DIST_TARGET'] == 'x86_64')) and build_host_supports_sse:
650 opt_flags.extend (["-msse", "-mfpmath=sse", "-DUSE_XMMINTRIN"])
651 debug_flags.extend (["-msse", "-mfpmath=sse", "-DUSE_XMMINTRIN"])
652 # end of processor-specific section
654 # optimization section
655 if env['FPU_OPTIMIZATION']:
656 if env['DIST_TARGET'] == 'tiger':
657 opt_flags.append ("-DBUILD_VECLIB_OPTIMIZATIONS")
658 debug_flags.append ("-DBUILD_VECLIB_OPTIMIZATIONS")
659 libraries['core'].Append(LINKFLAGS= '-framework Accelerate')
660 elif env['DIST_TARGET'] == 'i686' or env['DIST_TARGET'] == 'x86_64':
661 opt_flags.append ("-DBUILD_SSE_OPTIMIZATIONS")
662 debug_flags.append ("-DBUILD_SSE_OPTIMIZATIONS")
663 if env['DIST_TARGET'] == 'x86_64':
664 opt_flags.append ("-DUSE_X86_64_ASM")
665 debug_flags.append ("-DUSE_X86_64_ASM")
666 if build_host_supports_sse != 1:
667 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)"
668 # end optimization section
670 # handle x86/x86_64 libdir properly
672 if env['DIST_TARGET'] == 'x86_64':
673 env['LIBDIR']='lib64'
678 # save off guessed arch element in an env
680 env.Append(CONFIG_ARCH=config[config_arch])
684 # ARCH="..." overrides all
687 if env['ARCH'] != '':
688 opt_flags = env['ARCH'].split()
691 # prepend boiler plate optimization flags
696 "-fomit-frame-pointer",
702 if env['DEBUG'] == 1:
703 env.Append(CCFLAGS=" ".join (debug_flags))
704 env.Append(LINKFLAGS=" ".join (debug_flags))
706 env.Append(CCFLAGS=" ".join (opt_flags))
707 env.Append(LINKFLAGS=" ".join (opt_flags))
709 if env['UNIVERSAL'] == 1:
710 env.Append(CCFLAGS="-arch i386 -arch ppc")
711 env.Append(LINKFLAGS="-arch i386 -arch ppc")
717 env.Append(CCFLAGS="-Wall")
718 env.Append(CXXFLAGS="-Woverloaded-virtual")
720 if env['EXTRA_WARN']:
721 env.Append(CCFLAGS="-Wextra -pedantic -ansi")
722 env.Append(CXXFLAGS="-ansi")
723 # env.Append(CFLAGS="-iso")
726 env.Append(CCFLAGS="-DHAVE_LIBLO")
730 # fix scons nitpickiness on APPLE
734 def prep_libcheck(topenv, libinfo):
735 if topenv['DIST_TARGET'] == 'panther' or topenv['DIST_TARGET'] == 'tiger':
737 # rationale: GTK-Quartz uses jhbuild and installs to /opt/gtk by default.
738 # All libraries needed should be built against this location
740 libinfo.Append(CPPPATH="/opt/gtk/include", LIBPATH="/opt/gtk/lib")
741 libinfo.Append(CXXFLAGS="-I/opt/gtk/include", LINKFLAGS="-L/opt/gtk/lib")
742 libinfo.Append(CPPPATH="/opt/local/include", LIBPATH="/opt/local/lib")
743 libinfo.Append(CXXFLAGS="-I/opt/local/include", LINKFLAGS="-L/opt/local/lib")
745 prep_libcheck(env, env)
748 # check for VAMP and rubberband (currently optional)
751 libraries['vamp'] = LibraryInfo()
753 env['RUBBERBAND'] = False
755 conf = libraries['vamp'].Configure (custom_tests = { 'CheckPKGExists' : CheckPKGExists } )
757 if conf.CheckPKGExists('vamp-sdk'):
759 libraries['vamp'].ParseConfig('pkg-config --cflags --libs vamp-sdk')
763 print "---> WE HAVE VAMP: ", have_vamp
765 libraries['vamp'] = conf.Finish ()
768 if os.path.exists ('libs/rubberband/src'):
769 conf = Configure (libraries['vamp'])
770 if conf.CheckHeader ('fftw3.h'):
771 env['RUBBERBAND'] = True
772 libraries['rubberband'] = LibraryInfo (LIBS='rubberband',
773 LIBPATH='#libs/rubberband',
774 CPPPATH='#libs/rubberband',
775 CCFLAGS='-DUSE_RUBBERBAND')
776 libraries['vamp'] = conf.Finish ()
781 libraries['usb'] = LibraryInfo ()
782 prep_libcheck(env, libraries['usb'])
784 conf = Configure (libraries['usb'])
785 if conf.CheckLib ('usb', 'usb_interrupt_write'):
790 # check for linux/input.h while we're at it for powermate
791 if conf.CheckHeader('linux/input.h'):
792 have_linux_input = True
794 have_linux_input = False
796 libraries['usb'] = conf.Finish ()
801 libraries['flac'] = LibraryInfo ()
802 prep_libcheck(env, libraries['flac'])
803 libraries['flac'].Append(CPPPATH="/usr/local/include", LIBPATH="/usr/local/lib")
806 # june 1st 2007: look for a function that is in FLAC 1.1.2 and not in later versions
807 # since the version of libsndfile we have internally does not support
808 # the new API that libFLAC has adopted
811 conf = Configure (libraries['flac'])
812 if conf.CheckLib ('FLAC', 'FLAC__seekable_stream_decoder_init', language='CXX'):
813 conf.env.Append(CCFLAGS='-DHAVE_FLAC')
818 libraries['flac'] = conf.Finish ()
820 # or if that fails...
821 #libraries['flac'] = LibraryInfo (LIBS='FLAC')
823 # boost (we don't link against boost, just use some header files)
825 libraries['boost'] = LibraryInfo ()
826 prep_libcheck(env, libraries['boost'])
827 libraries['boost'].Append(CPPPATH="/usr/local/include", LIBPATH="/usr/local/lib")
828 conf = Configure (libraries['boost'])
829 if conf.CheckHeader ('boost/shared_ptr.hpp', language='CXX') == False:
830 print "Boost header files do not appear to be installed."
833 libraries['boost'] = conf.Finish ()
839 libraries['lo'] = LibraryInfo ()
840 prep_libcheck(env, libraries['lo'])
842 conf = Configure (libraries['lo'])
843 if conf.CheckLib ('lo', 'lo_server_new') == False:
844 print "liblo does not appear to be installed."
847 libraries['lo'] = conf.Finish ()
852 libraries['dmalloc'] = LibraryInfo ()
853 prep_libcheck(env, libraries['dmalloc'])
856 # look for the threaded version
859 conf = Configure (libraries['dmalloc'])
860 if conf.CheckLib ('dmallocth', 'dmalloc_shutdown'):
861 have_libdmalloc = True
863 have_libdmalloc = False
865 libraries['dmalloc'] = conf.Finish ()
868 # Audio/MIDI library (needed for MIDI, since audio is all handled via JACK)
871 conf = Configure(env)
873 if conf.CheckCHeader('alsa/asoundlib.h'):
874 libraries['sysmidi'] = LibraryInfo (LIBS='asound')
875 env['SYSMIDI'] = 'ALSA Sequencer'
876 subst_dict['%MIDITAG%'] = "seq"
877 subst_dict['%MIDITYPE%'] = "alsa/sequencer"
878 elif conf.CheckCHeader('/System/Library/Frameworks/CoreMIDI.framework/Headers/CoreMIDI.h'):
879 # this line is needed because scons can't handle -framework in ParseConfig() yet.
881 # We need Carbon as well as the rest
882 libraries['sysmidi'] = LibraryInfo (
883 LINKFLAGS = ' -framework CoreMIDI -framework CoreFoundation -framework CoreAudio -framework CoreServices -framework AudioUnit -framework AudioToolbox -framework Carbon -bind_at_load' )
885 libraries['sysmidi'] = LibraryInfo (
886 LINKFLAGS = ' -framework CoreMIDI -framework CoreFoundation -framework CoreAudio -framework CoreServices -framework AudioUnit -framework AudioToolbox -bind_at_load' )
887 env['SYSMIDI'] = 'CoreMIDI'
888 subst_dict['%MIDITAG%'] = "ardour"
889 subst_dict['%MIDITYPE%'] = "coremidi"
891 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."
900 'sigc++-2.0' : '2.0',
902 'libgnomecanvasmm-2.6' : '2.12.0'
905 conf = Configure(env, custom_tests = { 'CheckPKGConfig' : CheckPKGConfig,
906 'CheckPKGVersion' : CheckPKGVersion })
908 for pkg, version in syslibdeps.iteritems():
909 if not conf.CheckPKGVersion( pkg, version ):
910 print '%s >= %s not found.' %(pkg, version)
911 DependenciesRequiredMessage()
916 libraries['sigc2'] = LibraryInfo()
917 libraries['sigc2'].ParseConfig('pkg-config --cflags --libs sigc++-2.0')
918 libraries['glibmm2'] = LibraryInfo()
919 libraries['glibmm2'].ParseConfig('pkg-config --cflags --libs glibmm-2.4')
920 libraries['cairomm'] = LibraryInfo()
921 libraries['cairomm'].ParseConfig('pkg-config --cflags --libs cairomm-1.0')
922 libraries['gdkmm2'] = LibraryInfo()
923 libraries['gdkmm2'].ParseConfig ('pkg-config --cflags --libs gdkmm-2.4')
924 libraries['gtkmm2'] = LibraryInfo()
925 libraries['gtkmm2'].ParseConfig ('pkg-config --cflags --libs gtkmm-2.4')
926 libraries['atkmm'] = LibraryInfo()
927 libraries['atkmm'].ParseConfig ('pkg-config --cflags --libs atkmm-1.6')
928 libraries['pangomm'] = LibraryInfo()
929 libraries['pangomm'].ParseConfig ('pkg-config --cflags --libs pangomm-1.4')
930 libraries['libgnomecanvasmm'] = LibraryInfo()
931 libraries['libgnomecanvasmm'].ParseConfig ('pkg-config --cflags --libs libgnomecanvasmm-2.6')
934 # cannot use system one for the time being
937 libraries['sndfile-ardour'] = LibraryInfo(LIBS='libsndfile-ardour',
938 LIBPATH='#libs/libsndfile',
939 CPPPATH=['#libs/libsndfile/src'])
941 # libraries['libglademm'] = LibraryInfo()
942 # libraries['libglademm'].ParseConfig ('pkg-config --cflags --libs libglademm-2.4')
944 # libraries['flowcanvas'] = LibraryInfo(LIBS='flowcanvas', LIBPATH='#/libs/flowcanvas', CPPPATH='#libs/flowcanvas')
945 libraries['soundtouch'] = LibraryInfo()
946 libraries['soundtouch'].ParseConfig ('pkg-config --cflags --libs soundtouch-1.0')
947 # Comment the previous line and uncomment this for Debian:
948 #libraries['soundtouch'].ParseConfig ('pkg-config --cflags --libs libSoundTouch')
950 libraries['appleutility'] = LibraryInfo(LIBS='libappleutility',
951 LIBPATH='#libs/appleutility',
952 CPPPATH='#libs/appleutility')
963 # these are unconditionally included but have
964 # tests internally to avoid compilation etc
968 # this is unconditionally included but has
969 # tests internally to avoid compilation etc
970 # if COREAUDIO is not set
982 libraries['sigc2'] = LibraryInfo(LIBS='sigc++2',
983 LIBPATH='#libs/sigc++2',
984 CPPPATH='#libs/sigc++2')
985 libraries['glibmm2'] = LibraryInfo(LIBS='glibmm2',
986 LIBPATH='#libs/glibmm2',
987 CPPPATH='#libs/glibmm2')
988 libraries['pangomm'] = LibraryInfo(LIBS='pangomm',
989 LIBPATH='#libs/gtkmm2/pango',
990 CPPPATH='#libs/gtkmm2/pango')
991 libraries['atkmm'] = LibraryInfo(LIBS='atkmm',
992 LIBPATH='#libs/gtkmm2/atk',
993 CPPPATH='#libs/gtkmm2/atk')
994 libraries['gdkmm2'] = LibraryInfo(LIBS='gdkmm2',
995 LIBPATH='#libs/gtkmm2/gdk',
996 CPPPATH='#libs/gtkmm2/gdk')
997 libraries['gtkmm2'] = LibraryInfo(LIBS='gtkmm2',
998 LIBPATH="#libs/gtkmm2/gtk",
999 CPPPATH='#libs/gtkmm2/gtk/')
1000 libraries['libgnomecanvasmm'] = LibraryInfo(LIBS='libgnomecanvasmm',
1001 LIBPATH='#libs/libgnomecanvasmm',
1002 CPPPATH='#libs/libgnomecanvasmm')
1004 libraries['soundtouch'] = LibraryInfo(LIBS='soundtouch',
1005 LIBPATH='#libs/soundtouch',
1006 CPPPATH=['#libs', '#libs/soundtouch'])
1007 libraries['sndfile-ardour'] = LibraryInfo(LIBS='libsndfile-ardour',
1008 LIBPATH='#libs/libsndfile',
1009 CPPPATH=['#libs/libsndfile', '#libs/libsndfile/src'])
1010 # libraries['libglademm'] = LibraryInfo(LIBS='libglademm',
1011 # LIBPATH='#libs/libglademm',
1012 # CPPPATH='#libs/libglademm')
1013 libraries['appleutility'] = LibraryInfo(LIBS='libappleutility',
1014 LIBPATH='#libs/appleutility',
1015 CPPPATH='#libs/appleutility')
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
1040 'libs/gtkmm2/pango',
1044 'libs/libgnomecanvasmm',
1045 # 'libs/flowcanvas',
1052 # * always build the LGPL control protocol lib, since we link against it from libardour
1053 # * ditto for generic MIDI
1054 # * tranzport checks whether it should build internally, but we need here so that
1055 # its included in the tarball
1058 surface_subdirs = [ 'libs/surfaces/control_protocol',
1059 'libs/surfaces/generic_midi',
1060 'libs/surfaces/tranzport',
1061 'libs/surfaces/mackie',
1062 'libs/surfaces/powermate'
1067 env['TRANZPORT'] = 1
1069 env['TRANZPORT'] = 0
1070 print 'Disabled building Tranzport code because libusb could not be found'
1072 if have_linux_input:
1073 env['POWERMATE'] = 1
1075 env['POWERMATE'] = 0
1076 print 'Disabled building Powermate code because linux/input.h could not be found'
1078 if os.access ('libs/surfaces/sony9pin', os.F_OK):
1079 surface_subdirs += [ 'libs/surfaces/sony9pin' ]
1081 env['POWERMATE'] = 0
1082 env['TRANZPORT'] = 0
1085 # timestretch libraries
1088 timefx_subdirs = ['libs/soundtouch']
1089 if env['RUBBERBAND']:
1090 timefx_subdirs += ['libs/rubberband']
1092 opts.Save('scache.conf', env)
1093 Help(opts.GenerateHelpText(env))
1095 if os.environ.has_key('PATH'):
1096 env.Append(PATH = os.environ['PATH'])
1098 if os.environ.has_key('PKG_CONFIG_PATH'):
1099 env.Append(PKG_CONFIG_PATH = os.environ['PKG_CONFIG_PATH'])
1101 if os.environ.has_key('CC'):
1102 env['CC'] = os.environ['CC']
1104 if os.environ.has_key('CXX'):
1105 env['CXX'] = os.environ['CXX']
1107 if os.environ.has_key('DISTCC_HOSTS'):
1108 env['ENV']['DISTCC_HOSTS'] = os.environ['DISTCC_HOSTS']
1109 env['ENV']['HOME'] = os.environ['HOME']
1111 final_prefix = '$PREFIX'
1114 install_prefix = '$DESTDIR/$PREFIX'
1116 install_prefix = env['PREFIX']
1118 subst_dict['%INSTALL_PREFIX%'] = install_prefix;
1119 subst_dict['%FINAL_PREFIX%'] = final_prefix;
1120 subst_dict['%PREFIX%'] = final_prefix;
1122 if env['PREFIX'] == '/usr':
1123 final_config_prefix = '/etc'
1125 final_config_prefix = env['PREFIX'] + '/etc'
1127 config_prefix = '$DESTDIR' + final_config_prefix
1130 # everybody needs this
1133 env.Merge ([ libraries['core'] ])
1140 conf = Configure (env)
1142 nls_error = 'This system is not configured for internationalized applications. An english-only version will be built:'
1143 print 'Checking for internationalization support ...'
1144 have_gettext = conf.TryAction(Action('xgettext --version'))
1145 if have_gettext[0] != 1:
1146 nls_error += ' No xgettext command.'
1149 print "Found xgettext"
1151 have_msgmerge = conf.TryAction(Action('msgmerge --version'))
1152 if have_msgmerge[0] != 1:
1153 nls_error += ' No msgmerge command.'
1156 print "Found msgmerge"
1158 if not conf.CheckCHeader('libintl.h'):
1159 nls_error += ' No libintl.h.'
1165 print "International version will be built."
1169 env.Append(CCFLAGS="-DENABLE_NLS")
1171 Export('env install_prefix final_prefix config_prefix final_config_prefix libraries i18n ardour_version subst_dict use_flac')
1174 # the configuration file may be system dependent
1177 conf = env.Configure ()
1179 if conf.CheckCHeader('/System/Library/Frameworks/CoreAudio.framework/Versions/A/Headers/CoreAudio.h'):
1180 subst_dict['%JACK_INPUT%'] = "coreaudio:Built-in Audio:in"
1181 subst_dict['%JACK_OUTPUT%'] = "coreaudio:Built-in Audio:out"
1183 subst_dict['%JACK_INPUT%'] = "alsa_pcm:playback_"
1184 subst_dict['%JACK_OUTPUT%'] = "alsa_pcm:capture_"
1186 # posix_memalign available
1187 if not conf.CheckFunc('posix_memalign'):
1188 print 'Did not find posix_memalign(), using malloc'
1189 env.Append(CCFLAGS='-DNO_POSIX_MEMALIGN')
1194 # generate the per-user and system rc files from the same source
1196 sysrcbuild = env.SubstInFile ('ardour_system.rc','ardour.rc.in', SUBST_DICT = subst_dict)
1198 # add to the substitution dictionary
1200 subst_dict['%VERSION%'] = ardour_version[0:3]
1201 subst_dict['%EXTRA_VERSION%'] = ardour_version[3:]
1202 subst_dict['%REVISION_STRING%'] = ''
1203 if os.path.exists('.svn'):
1204 subst_dict['%REVISION_STRING%'] = '.' + fetch_svn_revision ('.') + 'svn'
1206 # specbuild = env.SubstInFile ('ardour.spec','ardour.spec.in', SUBST_DICT = subst_dict)
1208 the_revision = env.Command ('frobnicatory_decoy', [], create_stored_revision)
1209 remove_ardour = env.Command ('frobnicatory_decoy2', [],
1210 [ Delete ('$PREFIX/etc/ardour2'),
1211 Delete ('$PREFIX/lib/ardour2'),
1212 Delete ('$PREFIX/bin/ardour2')])
1214 env.Alias('revision', the_revision)
1215 env.Alias('install', env.Install(os.path.join(config_prefix, 'ardour2'), 'ardour_system.rc'))
1216 env.Alias('uninstall', remove_ardour)
1218 Default (sysrcbuild)
1222 Precious (env['DISTTREE'])
1224 env.Distribute (env['DISTTREE'],
1225 [ 'SConstruct', 'svn_revision.h',
1226 'COPYING', 'PACKAGER_README', 'README',
1228 'tools/config.guess',
1229 'icons/icon/ardour_icon_mac_mask.png',
1230 'icons/icon/ardour_icon_mac.png',
1231 'icons/icon/ardour_icon_tango_16px_blue.png',
1232 'icons/icon/ardour_icon_tango_16px_red.png',
1233 'icons/icon/ardour_icon_tango_22px_blue.png',
1234 'icons/icon/ardour_icon_tango_22px_red.png',
1235 'icons/icon/ardour_icon_tango_32px_blue.png',
1236 'icons/icon/ardour_icon_tango_32px_red.png',
1237 'icons/icon/ardour_icon_tango_48px_blue.png',
1238 'icons/icon/ardour_icon_tango_48px_red.png'
1240 glob.glob ('DOCUMENTATION/AUTHORS*') +
1241 glob.glob ('DOCUMENTATION/CONTRIBUTORS*') +
1242 glob.glob ('DOCUMENTATION/TRANSLATORS*') +
1243 glob.glob ('DOCUMENTATION/BUILD*') +
1244 glob.glob ('DOCUMENTATION/FAQ*') +
1245 glob.glob ('DOCUMENTATION/README*')
1248 srcdist = env.Tarball(env['TARBALL'], [ env['DISTTREE'], the_revision ])
1249 env.Alias ('srctar', srcdist)
1252 # don't leave the distree around
1255 env.AddPreAction (env['DISTTREE'], Action ('rm -rf ' + str (File (env['DISTTREE']))))
1256 env.AddPostAction (srcdist, Action ('rm -rf ' + str (File (env['DISTTREE']))))
1262 for subdir in coredirs:
1263 SConscript (subdir + '/SConscript')
1265 for sublistdir in [ subdirs, timefx_subdirs, gtk_subdirs, surface_subdirs ]:
1266 for subdir in sublistdir:
1267 SConscript (subdir + '/SConscript')
1270 env.Clean ('scrub', [ 'scache.conf', '.sconf_temp', '.sconsign.dblite', 'config.log'])