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('DEBUG', 'Set to build with debugging information and no optimizations', 0),
34 PathOption('DESTDIR', 'Set the intermediate install "prefix"', '/'),
35 EnumOption('DIST_TARGET', 'Build target for cross compiling packagers', 'auto', allowed_values=('auto', 'i386', 'i686', 'x86_64', 'powerpc', 'tiger', 'panther', 'none' ), ignorecase=2),
36 BoolOption('DMALLOC', 'Compile and link using the dmalloc library', 0),
37 BoolOption('EXTRA_WARN', 'Compile with -Wextra, -ansi, and -pedantic. Might break compilation. For pedants', 0),
38 BoolOption('FFT_ANALYSIS', 'Include FFT analysis window', 0),
39 BoolOption('FPU_OPTIMIZATION', 'Build runtime checked assembler code', 1),
40 BoolOption('LIBLO', 'Compile with support for liblo library', 1),
41 BoolOption('NLS', 'Set to turn on i18n support', 1),
42 PathOption('PREFIX', 'Set the install "prefix"', '/usr/local'),
43 BoolOption('SURFACES', 'Build support for control surfaces', 1),
44 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),
45 BoolOption('UNIVERSAL', 'Compile as universal binary. Requires that external libraries are already universal.', 0),
46 BoolOption('VERSIONED', 'Add revision information to ardour/gtk executable name inside the build directory', 0),
47 BoolOption('VST', 'Compile with support for VST', 0),
48 BoolOption('GPROFILE', 'Compile with support for gprofile (Developers only)', 0),
49 BoolOption('TRANZPORT', 'Compile with support for Frontier Designs (if libusb is available)', 1)
52 #----------------------------------------------------------------------
53 # a handy helper that provides a way to merge compile/link information
54 # from multiple different "environments"
55 #----------------------------------------------------------------------
57 class LibraryInfo(Environment):
58 def __init__(self,*args,**kw):
59 Environment.__init__ (self,*args,**kw)
61 def Merge (self,others):
63 self.Append (LIBS = other.get ('LIBS',[]))
64 self.Append (LIBPATH = other.get ('LIBPATH', []))
65 self.Append (CPPPATH = other.get('CPPPATH', []))
66 self.Append (LINKFLAGS = other.get('LINKFLAGS', []))
67 self.Append (CCFLAGS = other.get('CCFLAGS', []))
68 self.Replace(LIBPATH = list(Set(self.get('LIBPATH', []))))
69 self.Replace(CPPPATH = list(Set(self.get('CPPPATH',[]))))
70 #doing LINKFLAGS breaks -framework
71 #doing LIBS break link order dependency
73 def ENV_update(self, src_ENV):
74 for k in src_ENV.keys():
75 if k in self['ENV'].keys() and k in [ 'PATH', 'LD_LIBRARY_PATH',
77 self['ENV'][k]=SCons.Util.AppendPath(self['ENV'][k], src_ENV[k])
79 self['ENV'][k]=src_ENV[k]
81 env = LibraryInfo (options = opts,
83 VERSION = ardour_version,
84 TARBALL='ardour-' + ardour_version + '.tar.bz2',
86 DISTTREE = '#ardour-' + ardour_version,
87 DISTCHECKDIR = '#ardour-' + ardour_version + '/check'
90 env.ENV_update(os.environ)
92 #----------------------------------------------------------------------
94 #----------------------------------------------------------------------
96 # Handy subst-in-file builder
99 def do_subst_in_file(targetfile, sourcefile, dict):
100 """Replace all instances of the keys of dict with their values.
101 For example, if dict is {'%VERSION%': '1.2345', '%BASE%': 'MyProg'},
102 then all instances of %VERSION% in the file will be replaced with 1.2345 etc.
105 f = open(sourcefile, 'rb')
109 raise SCons.Errors.UserError, "Can't read source file %s"%sourcefile
110 for (k,v) in dict.items():
111 contents = re.sub(k, v, contents)
113 f = open(targetfile, 'wb')
117 raise SCons.Errors.UserError, "Can't write target file %s"%targetfile
120 def subst_in_file(target, source, env):
121 if not env.has_key('SUBST_DICT'):
122 raise SCons.Errors.UserError, "SubstInFile requires SUBST_DICT to be set."
123 d = dict(env['SUBST_DICT']) # copy it
124 for (k,v) in d.items():
126 d[k] = env.subst(v())
127 elif SCons.Util.is_String(v):
130 raise SCons.Errors.UserError, "SubstInFile: key %s: %s must be a string or callable"%(k, repr(v))
131 for (t,s) in zip(target, source):
132 return do_subst_in_file(str(t), str(s), d)
134 def subst_in_file_string(target, source, env):
135 """This is what gets printed on the console."""
136 return '\n'.join(['Substituting vars from %s into %s'%(str(s), str(t))
137 for (t,s) in zip(target, source)])
139 def subst_emitter(target, source, env):
140 """Add dependency from substituted SUBST_DICT to target.
141 Returns original target, source tuple unchanged.
143 d = env['SUBST_DICT'].copy() # copy it
144 for (k,v) in d.items():
146 d[k] = env.subst(v())
147 elif SCons.Util.is_String(v):
149 Depends(target, SCons.Node.Python.Value(d))
150 # Depends(target, source) # this doesn't help the install-sapphire-linux.sh problem
151 return target, source
153 subst_action = Action (subst_in_file, subst_in_file_string)
154 env['BUILDERS']['SubstInFile'] = Builder(action=subst_action, emitter=subst_emitter)
157 # internationalization
160 # po_builder: builder function to copy po files to the parent directory while updating them
162 # first source: .po file
163 # second source: .pot file
166 def po_builder(target,source,env):
167 os.spawnvp (os.P_WAIT, 'cp', ['cp', str(source[0]), str(target[0])])
173 print 'Updating ' + str(target[0])
174 return os.spawnvp (os.P_WAIT, 'msgmerge', args)
176 po_bld = Builder (action = po_builder)
177 env.Append(BUILDERS = {'PoBuild' : po_bld})
179 # mo_builder: builder function for (binary) message catalogs (.mo)
181 # first source: .po file
184 def mo_builder(target,source,env):
188 target[0].get_path(),
191 return os.spawnvp (os.P_WAIT, 'msgfmt', args)
193 mo_bld = Builder (action = mo_builder)
194 env.Append(BUILDERS = {'MoBuild' : mo_bld})
196 # pot_builder: builder function for message templates (.pot)
198 # source: list of C/C++ etc. files to extract messages from
201 def pot_builder(target,source,env):
206 '-o', target[0].get_path(),
207 "--default-domain=" + env['PACKAGE'],
208 '--copyright-holder="Paul Davis"' ]
209 args += [ src.get_path() for src in source ]
211 return os.spawnvp (os.P_WAIT, 'xgettext', args)
213 pot_bld = Builder (action = pot_builder)
214 env.Append(BUILDERS = {'PotBuild' : pot_bld})
217 # utility function, not a builder
220 def i18n (buildenv, sources, installenv):
221 domain = buildenv['PACKAGE']
222 potfile = buildenv['POTFILE']
224 installenv.Alias ('potupdate', buildenv.PotBuild (potfile, sources))
226 p_oze = [ os.path.basename (po) for po in glob.glob ('po/*.po') ]
227 languages = [ po.replace ('.po', '') for po in p_oze ]
229 for po_file in p_oze:
230 buildenv.PoBuild(po_file, ['po/'+po_file, potfile])
231 mo_file = po_file.replace (".po", ".mo")
232 installenv.Alias ('install', buildenv.MoBuild (mo_file, po_file))
234 for lang in languages:
235 modir = (os.path.join (install_prefix, 'share/locale/' + lang + '/LC_MESSAGES/'))
236 moname = domain + '.mo'
237 installenv.Alias('install', installenv.InstallAs (os.path.join (modir, moname), lang + '.mo'))
240 def fetch_svn_revision (path):
244 cmd += " | awk '/^Revision:/ { print $2}'"
245 return commands.getoutput (cmd)
247 def create_stored_revision (target = None, source = None, env = None):
248 if os.path.exists('.svn'):
249 rev = fetch_svn_revision ('.');
251 text = "#ifndef __ardour_svn_revision_h__\n"
252 text += "#define __ardour_svn_revision_h__\n"
253 text += "static const char* ardour_svn_revision = \"" + rev + "\";\n";
255 print '============> writing svn revision info to svn_revision.h\n'
256 o = file ('svn_revision.h', 'w')
260 print "Could not open svn_revision.h for writing\n"
263 print "You cannot use \"scons revision\" on without using a checked out"
264 print "copy of the Ardour source code repository"
268 # A generic builder for version.cc files
270 # note: requires that DOMAIN, MAJOR, MINOR, MICRO are set in the construction environment
271 # note: assumes one source files, the header that declares the version variables
274 def version_builder (target, source, env):
276 text = "int " + env['DOMAIN'] + "_major_version = " + str (env['MAJOR']) + ";\n"
277 text += "int " + env['DOMAIN'] + "_minor_version = " + str (env['MINOR']) + ";\n"
278 text += "int " + env['DOMAIN'] + "_micro_version = " + str (env['MICRO']) + ";\n"
281 o = file (target[0].get_path(), 'w')
285 print "Could not open", target[0].get_path(), " for writing\n"
288 text = "#ifndef __" + env['DOMAIN'] + "_version_h__\n"
289 text += "#define __" + env['DOMAIN'] + "_version_h__\n"
290 text += "extern const char* " + env['DOMAIN'] + "_revision;\n"
291 text += "extern int " + env['DOMAIN'] + "_major_version;\n"
292 text += "extern int " + env['DOMAIN'] + "_minor_version;\n"
293 text += "extern int " + env['DOMAIN'] + "_micro_version;\n"
294 text += "#endif /* __" + env['DOMAIN'] + "_version_h__ */\n"
297 o = file (target[1].get_path(), 'w')
301 print "Could not open", target[1].get_path(), " for writing\n"
306 version_bld = Builder (action = version_builder)
307 env.Append (BUILDERS = {'VersionBuild' : version_bld})
310 # a builder that makes a hard link from the 'source' executable to a name with
311 # a "build ID" based on the most recent CVS activity that might be reasonably
312 # related to version activity. this relies on the idea that the SConscript
313 # file that builds the executable is updated with new version info and committed
314 # to the source code repository whenever things change.
317 def versioned_builder(target,source,env):
318 w, r = os.popen2( "LANG= svn info | awk '/^Revision:/ { print $2}'")
320 last_revision = r.readline().strip()
323 if last_revision == "":
324 print "No SVN info found - versioned executable cannot be built"
327 print "The current build ID is " + last_revision
329 tagged_executable = source[0].get_path() + '-' + last_revision
331 if os.path.exists (tagged_executable):
332 print "Replacing existing executable with the same build tag."
333 os.unlink (tagged_executable)
335 return os.link (source[0].get_path(), tagged_executable)
337 verbuild = Builder (action = versioned_builder)
338 env.Append (BUILDERS = {'VersionedExecutable' : verbuild})
341 # source tar file builder
344 def distcopy (target, source, env):
345 treedir = str (target[0])
349 except OSError, (errnum, strerror):
350 if errnum != errno.EEXIST:
351 print 'mkdir ', treedir, ':', strerror
355 # we don't know what characters might be in the file names
356 # so quote them all before passing them to the shell
358 all_files = ([ str(s) for s in source ])
359 cmd += " ".join ([ "'%s'" % quoted for quoted in all_files])
360 cmd += ' | (cd ' + treedir + ' && tar xf -)'
364 def tarballer (target, source, env):
365 cmd = 'tar -jcf ' + str (target[0]) + ' ' + str(source[0]) + " --exclude '*~'"
366 print 'running ', cmd, ' ... '
370 dist_bld = Builder (action = distcopy,
371 target_factory = SCons.Node.FS.default_fs.Entry,
372 source_factory = SCons.Node.FS.default_fs.Entry,
375 tarball_bld = Builder (action = tarballer,
376 target_factory = SCons.Node.FS.default_fs.Entry,
377 source_factory = SCons.Node.FS.default_fs.Entry)
379 env.Append (BUILDERS = {'Distribute' : dist_bld})
380 env.Append (BUILDERS = {'Tarball' : tarball_bld})
383 # Make sure they know what they are doing
387 if os.path.isfile('.personal_use_only'):
388 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."
390 sys.stdout.write ("Are you building Ardour for personal use (rather than distribution to others)? [no]: ")
391 answer = sys.stdin.readline ()
392 answer = answer.rstrip().strip()
393 if answer == "yes" or answer == "y":
394 fh = open('.personal_use_only', 'w')
396 print "OK, VST support will be enabled"
398 print 'You cannot build Ardour with VST support for distribution to others.\nIt is a violation of several different licenses. Build with VST=false.'
401 if os.path.isfile('.personal_use_only'):
402 os.remove('.personal_use_only')
405 #######################
406 # Dependency Checking #
407 #######################
411 'glib-2.0' : '2.10.1',
412 'gthread-2.0' : '2.10.1',
413 'gtk+-2.0' : '2.8.1',
414 'libxml-2.0' : '2.6.0',
415 'samplerate' : '0.1.0',
419 'libgnomecanvas-2.0' : '2.0'
422 def DependenciesRequiredMessage():
423 print 'You do not have the necessary dependencies required to build ardour'
424 print 'Please consult http://ardour.org/building for more information'
426 def CheckPKGConfig(context, version):
427 context.Message( 'Checking for pkg-config version >= %s... ' %version )
428 ret = context.TryAction('pkg-config --atleast-pkgconfig-version=%s' % version)[0]
429 context.Result( ret )
432 def CheckPKGVersion(context, name, version):
433 context.Message( 'Checking for %s... ' % name )
434 ret = context.TryAction('pkg-config --atleast-version=%s %s' %(version,name) )[0]
435 context.Result( ret )
438 def CheckPKGExists(context, name):
439 context.Message ('Checking for %s...' % name)
440 ret = context.TryAction('pkg-config --exists %s' % name)[0]
444 conf = Configure(env, custom_tests = { 'CheckPKGConfig' : CheckPKGConfig,
445 'CheckPKGVersion' : CheckPKGVersion })
447 # I think a more recent version is needed on win32
448 min_pkg_config_version = '0.8.0'
450 if not conf.CheckPKGConfig(min_pkg_config_version):
451 print 'pkg-config >= %s not found.' % min_pkg_config_version
454 for pkg, version in deps.iteritems():
455 if not conf.CheckPKGVersion( pkg, version ):
456 print '%s >= %s not found.' %(pkg, version)
457 DependenciesRequiredMessage()
462 # ----------------------------------------------------------------------
463 # Construction environment setup
464 # ----------------------------------------------------------------------
468 libraries['core'] = LibraryInfo (CCFLAGS = '-Ilibs')
470 #libraries['sndfile'] = LibraryInfo()
471 #libraries['sndfile'].ParseConfig('pkg-config --cflags --libs sndfile')
473 libraries['lrdf'] = LibraryInfo()
474 libraries['lrdf'].ParseConfig('pkg-config --cflags --libs lrdf')
476 libraries['raptor'] = LibraryInfo()
477 libraries['raptor'].ParseConfig('pkg-config --cflags --libs raptor')
479 libraries['samplerate'] = LibraryInfo()
480 libraries['samplerate'].ParseConfig('pkg-config --cflags --libs samplerate')
482 conf = env.Configure (custom_tests = { 'CheckPKGExists' : CheckPKGExists } )
484 if conf.CheckPKGExists ('fftw3f'):
485 libraries['fftw3f'] = LibraryInfo()
486 libraries['fftw3f'].ParseConfig('pkg-config --cflags --libs fftw3f')
488 if conf.CheckPKGExists ('fftw3'):
489 libraries['fftw3'] = LibraryInfo()
490 libraries['fftw3'].ParseConfig('pkg-config --cflags --libs fftw3')
494 if env['FFT_ANALYSIS']:
496 # Check for fftw3 header as well as the library
499 conf = Configure(libraries['fftw3'])
501 if conf.CheckHeader ('fftw3.h') == False:
502 print ('FFT Analysis cannot be compiled without the FFTW3 headers, which do not seem to be installed')
506 libraries['jack'] = LibraryInfo()
507 libraries['jack'].ParseConfig('pkg-config --cflags --libs jack')
509 libraries['xml'] = LibraryInfo()
510 libraries['xml'].ParseConfig('pkg-config --cflags --libs libxml-2.0')
512 libraries['xslt'] = LibraryInfo()
513 libraries['xslt'].ParseConfig('pkg-config --cflags --libs libxslt')
515 libraries['glib2'] = LibraryInfo()
516 libraries['glib2'].ParseConfig ('pkg-config --cflags --libs glib-2.0')
517 libraries['glib2'].ParseConfig ('pkg-config --cflags --libs gobject-2.0')
518 libraries['glib2'].ParseConfig ('pkg-config --cflags --libs gmodule-2.0')
519 libraries['glib2'].ParseConfig ('pkg-config --cflags --libs gthread-2.0')
521 libraries['gtk2'] = LibraryInfo()
522 libraries['gtk2'].ParseConfig ('pkg-config --cflags --libs gtk+-2.0')
524 libraries['pango'] = LibraryInfo()
525 libraries['pango'].ParseConfig ('pkg-config --cflags --libs pango')
527 libraries['libgnomecanvas2'] = LibraryInfo()
528 libraries['libgnomecanvas2'].ParseConfig ('pkg-config --cflags --libs libgnomecanvas-2.0')
530 #libraries['flowcanvas'] = LibraryInfo(LIBS='flowcanvas', LIBPATH='#/libs/flowcanvas', CPPPATH='#libs/flowcanvas')
532 # The Ardour Control Protocol Library
534 libraries['ardour_cp'] = LibraryInfo (LIBS='ardour_cp', LIBPATH='#libs/surfaces/control_protocol',
535 CPPPATH='#libs/surfaces/control_protocol')
537 # The Ardour backend/engine
539 libraries['ardour'] = LibraryInfo (LIBS='ardour', LIBPATH='#libs/ardour', CPPPATH='#libs/ardour')
540 libraries['midi++2'] = LibraryInfo (LIBS='midi++', LIBPATH='#libs/midi++2', CPPPATH='#libs/midi++2')
541 libraries['pbd'] = LibraryInfo (LIBS='pbd', LIBPATH='#libs/pbd', CPPPATH='#libs/pbd')
542 libraries['gtkmm2ext'] = LibraryInfo (LIBS='gtkmm2ext', LIBPATH='#libs/gtkmm2ext', CPPPATH='#libs/gtkmm2ext')
545 # SCons should really do this for us
547 conf = env.Configure ()
549 have_cxx = conf.TryAction (Action (str(env['CXX']) + ' --version'))
551 print "This system has no functional C++ compiler. You cannot build Ardour from source without one."
554 print "Congratulations, you have a functioning C++ compiler."
560 # Compiler flags and other system-dependent stuff
564 if env['GPROFILE'] == 1:
565 debug_flags = [ '-g', '-pg' ]
567 debug_flags = [ '-g' ]
569 # guess at the platform, used to define compiler flags
571 config_guess = os.popen("tools/config.guess").read()[:-1]
577 config = config_guess.split ("-")
579 print "system triple: " + config_guess
582 if env['DIST_TARGET'] == 'auto':
583 if config[config_arch] == 'apple':
584 # The [.] matches to the dot after the major version, "." would match any character
585 if re.search ("darwin[0-7][.]", config[config_kernel]) != None:
586 env['DIST_TARGET'] = 'panther'
588 env['DIST_TARGET'] = 'tiger'
590 if re.search ("x86_64", config[config_cpu]) != None:
591 env['DIST_TARGET'] = 'x86_64'
592 elif re.search("i[0-5]86", config[config_cpu]) != None:
593 env['DIST_TARGET'] = 'i386'
594 elif re.search("powerpc", config[config_cpu]) != None:
595 env['DIST_TARGET'] = 'powerpc'
597 env['DIST_TARGET'] = 'i686'
598 print "\n*******************************"
599 print "detected DIST_TARGET = " + env['DIST_TARGET']
600 print "*******************************\n"
603 if config[config_cpu] == 'powerpc' and env['DIST_TARGET'] != 'none':
605 # Apple/PowerPC optimization options
607 # -mcpu=7450 does not reliably work with gcc 3.*
609 if env['DIST_TARGET'] == 'panther' or env['DIST_TARGET'] == 'tiger':
610 if config[config_arch] == 'apple':
611 ## opt_flags.extend ([ "-mcpu=7450", "-faltivec"])
612 # to support g3s but still have some optimization for above
613 opt_flags.extend ([ "-mcpu=G3", "-mtune=7450"])
615 opt_flags.extend ([ "-mcpu=7400", "-maltivec", "-mabi=altivec"])
617 opt_flags.extend([ "-mcpu=750", "-mmultiple" ])
618 opt_flags.extend (["-mhard-float", "-mpowerpc-gfxopt"])
619 opt_flags.extend (["-Os"])
621 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':
623 build_host_supports_sse = 0
625 debug_flags.append ("-DARCH_X86")
626 opt_flags.append ("-DARCH_X86")
628 if config[config_kernel] == 'linux' :
630 if env['DIST_TARGET'] != 'i386':
632 flag_line = os.popen ("cat /proc/cpuinfo | grep '^flags'").read()[:-1]
633 x86_flags = flag_line.split (": ")[1:][0].split ()
635 if "mmx" in x86_flags:
636 opt_flags.append ("-mmmx")
637 if "sse" in x86_flags:
638 build_host_supports_sse = 1
639 if "3dnow" in x86_flags:
640 opt_flags.append ("-m3dnow")
642 if config[config_cpu] == "i586":
643 opt_flags.append ("-march=i586")
644 elif config[config_cpu] == "i686":
645 opt_flags.append ("-march=i686")
647 if ((env['DIST_TARGET'] == 'i686') or (env['DIST_TARGET'] == 'x86_64')) and build_host_supports_sse:
648 opt_flags.extend (["-msse", "-mfpmath=sse", "-DUSE_XMMINTRIN"])
649 debug_flags.extend (["-msse", "-mfpmath=sse", "-DUSE_XMMINTRIN"])
650 # end of processor-specific section
652 # optimization section
653 if env['FPU_OPTIMIZATION']:
654 if env['DIST_TARGET'] == 'tiger':
655 opt_flags.append ("-DBUILD_VECLIB_OPTIMIZATIONS")
656 debug_flags.append ("-DBUILD_VECLIB_OPTIMIZATIONS")
657 libraries['core'].Append(LINKFLAGS= '-framework Accelerate')
658 elif env['DIST_TARGET'] == 'i686' or env['DIST_TARGET'] == 'x86_64':
659 opt_flags.append ("-DBUILD_SSE_OPTIMIZATIONS")
660 debug_flags.append ("-DBUILD_SSE_OPTIMIZATIONS")
661 if env['DIST_TARGET'] == 'x86_64':
662 opt_flags.append ("-DUSE_X86_64_ASM")
663 debug_flags.append ("-DUSE_X86_64_ASM")
664 if build_host_supports_sse != 1:
665 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)"
666 # end optimization section
668 # handle x86/x86_64 libdir properly
670 if env['DIST_TARGET'] == 'x86_64':
671 env['LIBDIR']='lib64'
676 # save off guessed arch element in an env
678 env.Append(CONFIG_ARCH=config[config_arch])
682 # ARCH="..." overrides all
685 if env['ARCH'] != '':
686 opt_flags = env['ARCH'].split()
689 # prepend boiler plate optimization flags
694 "-fomit-frame-pointer",
700 if env['DEBUG'] == 1:
701 env.Append(CCFLAGS=" ".join (debug_flags))
702 env.Append(LINKFLAGS=" ".join (debug_flags))
704 env.Append(CCFLAGS=" ".join (opt_flags))
705 env.Append(LINKFLAGS=" ".join (opt_flags))
707 if env['UNIVERSAL'] == 1:
708 env.Append(CCFLAGS="-arch i386 -arch ppc")
709 env.Append(LINKFLAGS="-arch i386 -arch ppc")
715 env.Append(CCFLAGS="-Wall")
716 env.Append(CXXFLAGS="-Woverloaded-virtual")
718 if env['EXTRA_WARN']:
719 env.Append(CCFLAGS="-Wextra -pedantic -ansi")
720 env.Append(CXXFLAGS="-ansi")
721 # env.Append(CFLAGS="-iso")
724 env.Append(CCFLAGS="-DHAVE_LIBLO")
728 # fix scons nitpickiness on APPLE
732 def prep_libcheck(topenv, libinfo):
733 if topenv['DIST_TARGET'] == 'panther' or topenv['DIST_TARGET'] == 'tiger':
735 # rationale: GTK-Quartz uses jhbuild and installs to /opt/gtk by default.
736 # All libraries needed should be built against this location
738 libinfo.Append(CPPPATH="/opt/gtk/include", LIBPATH="/opt/gtk/lib")
739 libinfo.Append(CXXFLAGS="-I/opt/gtk/include", LINKFLAGS="-L/opt/gtk/lib")
740 libinfo.Append(CPPPATH="/opt/local/include", LIBPATH="/opt/local/lib")
741 libinfo.Append(CXXFLAGS="-I/opt/local/include", LINKFLAGS="-L/opt/local/lib")
743 prep_libcheck(env, env)
746 # check for VAMP and rubberband (currently optional)
749 libraries['vamp'] = LibraryInfo()
751 env['RUBBERBAND'] = False
753 conf = libraries['vamp'].Configure (custom_tests = { 'CheckPKGExists' : CheckPKGExists } )
755 if conf.CheckPKGExists('vamp-sdk'):
757 libraries['vamp'].ParseConfig('pkg-config --cflags --libs vamp-sdk')
761 libraries['vamp'] = conf.Finish ()
764 if os.path.exists ('libs/rubberband/src'):
765 conf = Configure (libraries['vamp'])
766 if conf.CheckHeader ('fftw3.h'):
767 env['RUBBERBAND'] = True
768 libraries['rubberband'] = LibraryInfo (LIBS='rubberband',
769 LIBPATH='#libs/rubberband',
770 CPPPATH='#libs/rubberband/rubberband',
771 CCFLAGS='-DUSE_RUBBERBAND')
772 libraries['vamp'] = conf.Finish ()
777 libraries['usb'] = LibraryInfo ()
778 prep_libcheck(env, libraries['usb'])
780 conf = Configure (libraries['usb'])
781 if conf.CheckLib ('usb', 'usb_interrupt_write'):
786 # check for linux/input.h while we're at it for powermate
787 if conf.CheckHeader('linux/input.h'):
788 have_linux_input = True
790 have_linux_input = False
792 libraries['usb'] = conf.Finish ()
797 libraries['flac'] = LibraryInfo ()
798 prep_libcheck(env, libraries['flac'])
799 libraries['flac'].Append(CPPPATH="/usr/local/include", LIBPATH="/usr/local/lib")
802 # june 1st 2007: look for a function that is in FLAC 1.1.2 and not in later versions
803 # since the version of libsndfile we have internally does not support
804 # the new API that libFLAC has adopted
807 conf = Configure (libraries['flac'])
808 if conf.CheckLib ('FLAC', 'FLAC__seekable_stream_decoder_init', language='CXX'):
809 conf.env.Append(CCFLAGS='-DHAVE_FLAC')
814 libraries['flac'] = conf.Finish ()
816 # or if that fails...
817 #libraries['flac'] = LibraryInfo (LIBS='FLAC')
819 # boost (we don't link against boost, just use some header files)
821 libraries['boost'] = LibraryInfo ()
822 prep_libcheck(env, libraries['boost'])
823 libraries['boost'].Append(CPPPATH="/usr/local/include", LIBPATH="/usr/local/lib")
824 conf = Configure (libraries['boost'])
825 if conf.CheckHeader ('boost/shared_ptr.hpp', language='CXX') == False:
826 print "Boost header files do not appear to be installed."
829 libraries['boost'] = conf.Finish ()
835 libraries['lo'] = LibraryInfo ()
836 prep_libcheck(env, libraries['lo'])
838 conf = Configure (libraries['lo'])
839 if conf.CheckLib ('lo', 'lo_server_new') == False:
840 print "liblo does not appear to be installed."
843 libraries['lo'] = conf.Finish ()
848 libraries['dmalloc'] = LibraryInfo ()
849 prep_libcheck(env, libraries['dmalloc'])
852 # look for the threaded version
855 conf = Configure (libraries['dmalloc'])
856 if conf.CheckLib ('dmallocth', 'dmalloc_shutdown'):
857 have_libdmalloc = True
859 have_libdmalloc = False
861 libraries['dmalloc'] = conf.Finish ()
864 # Audio/MIDI library (needed for MIDI, since audio is all handled via JACK)
867 conf = Configure(env)
869 if conf.CheckCHeader('alsa/asoundlib.h'):
870 libraries['sysmidi'] = LibraryInfo (LIBS='asound')
871 env['SYSMIDI'] = 'ALSA Sequencer'
872 subst_dict['%MIDITAG%'] = "seq"
873 subst_dict['%MIDITYPE%'] = "alsa/sequencer"
874 elif conf.CheckCHeader('/System/Library/Frameworks/CoreMIDI.framework/Headers/CoreMIDI.h'):
875 # this line is needed because scons can't handle -framework in ParseConfig() yet.
877 # We need Carbon as well as the rest
878 libraries['sysmidi'] = LibraryInfo (
879 LINKFLAGS = ' -framework CoreMIDI -framework CoreFoundation -framework CoreAudio -framework CoreServices -framework AudioUnit -framework AudioToolbox -framework Carbon -bind_at_load' )
881 libraries['sysmidi'] = LibraryInfo (
882 LINKFLAGS = ' -framework CoreMIDI -framework CoreFoundation -framework CoreAudio -framework CoreServices -framework AudioUnit -framework AudioToolbox -bind_at_load' )
883 env['SYSMIDI'] = 'CoreMIDI'
884 subst_dict['%MIDITAG%'] = "ardour"
885 subst_dict['%MIDITYPE%'] = "coremidi"
887 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."
896 'sigc++-2.0' : '2.0',
898 'libgnomecanvasmm-2.6' : '2.12.0'
901 conf = Configure(env, custom_tests = { 'CheckPKGConfig' : CheckPKGConfig,
902 'CheckPKGVersion' : CheckPKGVersion })
904 for pkg, version in syslibdeps.iteritems():
905 if not conf.CheckPKGVersion( pkg, version ):
906 print '%s >= %s not found.' %(pkg, version)
907 DependenciesRequiredMessage()
912 libraries['sigc2'] = LibraryInfo()
913 libraries['sigc2'].ParseConfig('pkg-config --cflags --libs sigc++-2.0')
914 libraries['glibmm2'] = LibraryInfo()
915 libraries['glibmm2'].ParseConfig('pkg-config --cflags --libs glibmm-2.4')
916 libraries['cairomm'] = LibraryInfo()
917 libraries['cairomm'].ParseConfig('pkg-config --cflags --libs cairomm-1.0')
918 libraries['gdkmm2'] = LibraryInfo()
919 libraries['gdkmm2'].ParseConfig ('pkg-config --cflags --libs gdkmm-2.4')
920 libraries['gtkmm2'] = LibraryInfo()
921 libraries['gtkmm2'].ParseConfig ('pkg-config --cflags --libs gtkmm-2.4')
922 libraries['atkmm'] = LibraryInfo()
923 libraries['atkmm'].ParseConfig ('pkg-config --cflags --libs atkmm-1.6')
924 libraries['pangomm'] = LibraryInfo()
925 libraries['pangomm'].ParseConfig ('pkg-config --cflags --libs pangomm-1.4')
926 libraries['libgnomecanvasmm'] = LibraryInfo()
927 libraries['libgnomecanvasmm'].ParseConfig ('pkg-config --cflags --libs libgnomecanvasmm-2.6')
930 # cannot use system one for the time being
933 libraries['sndfile-ardour'] = LibraryInfo(LIBS='libsndfile-ardour',
934 LIBPATH='#libs/libsndfile',
935 CPPPATH=['#libs/libsndfile/src'])
937 # libraries['libglademm'] = LibraryInfo()
938 # libraries['libglademm'].ParseConfig ('pkg-config --cflags --libs libglademm-2.4')
940 # libraries['flowcanvas'] = LibraryInfo(LIBS='flowcanvas', LIBPATH='#/libs/flowcanvas', CPPPATH='#libs/flowcanvas')
941 libraries['soundtouch'] = LibraryInfo()
942 libraries['soundtouch'].ParseConfig ('pkg-config --cflags --libs soundtouch-1.0')
943 # Comment the previous line and uncomment this for Debian:
944 #libraries['soundtouch'].ParseConfig ('pkg-config --cflags --libs libSoundTouch')
946 libraries['appleutility'] = LibraryInfo(LIBS='libappleutility',
947 LIBPATH='#libs/appleutility',
948 CPPPATH='#libs/appleutility')
959 # these are unconditionally included but have
960 # tests internally to avoid compilation etc
964 # this is unconditionally included but has
965 # tests internally to avoid compilation etc
966 # if COREAUDIO is not set
978 libraries['sigc2'] = LibraryInfo(LIBS='sigc++2',
979 LIBPATH='#libs/sigc++2',
980 CPPPATH='#libs/sigc++2')
981 libraries['glibmm2'] = LibraryInfo(LIBS='glibmm2',
982 LIBPATH='#libs/glibmm2',
983 CPPPATH='#libs/glibmm2')
984 libraries['pangomm'] = LibraryInfo(LIBS='pangomm',
985 LIBPATH='#libs/gtkmm2/pango',
986 CPPPATH='#libs/gtkmm2/pango')
987 libraries['atkmm'] = LibraryInfo(LIBS='atkmm',
988 LIBPATH='#libs/gtkmm2/atk',
989 CPPPATH='#libs/gtkmm2/atk')
990 libraries['gdkmm2'] = LibraryInfo(LIBS='gdkmm2',
991 LIBPATH='#libs/gtkmm2/gdk',
992 CPPPATH='#libs/gtkmm2/gdk')
993 libraries['gtkmm2'] = LibraryInfo(LIBS='gtkmm2',
994 LIBPATH="#libs/gtkmm2/gtk",
995 CPPPATH='#libs/gtkmm2/gtk/')
996 libraries['libgnomecanvasmm'] = LibraryInfo(LIBS='libgnomecanvasmm',
997 LIBPATH='#libs/libgnomecanvasmm',
998 CPPPATH='#libs/libgnomecanvasmm')
1000 libraries['soundtouch'] = LibraryInfo(LIBS='soundtouch',
1001 LIBPATH='#libs/soundtouch',
1002 CPPPATH=['#libs', '#libs/soundtouch'])
1003 libraries['sndfile-ardour'] = LibraryInfo(LIBS='libsndfile-ardour',
1004 LIBPATH='#libs/libsndfile',
1005 CPPPATH=['#libs/libsndfile', '#libs/libsndfile/src'])
1006 # libraries['libglademm'] = LibraryInfo(LIBS='libglademm',
1007 # LIBPATH='#libs/libglademm',
1008 # CPPPATH='#libs/libglademm')
1009 libraries['appleutility'] = LibraryInfo(LIBS='libappleutility',
1010 LIBPATH='#libs/appleutility',
1011 CPPPATH='#libs/appleutility')
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
1036 'libs/gtkmm2/pango',
1040 'libs/libgnomecanvasmm',
1041 # 'libs/flowcanvas',
1048 # * always build the LGPL control protocol lib, since we link against it from libardour
1049 # * ditto for generic MIDI
1050 # * tranzport checks whether it should build internally, but we need here so that
1051 # its included in the tarball
1054 surface_subdirs = [ 'libs/surfaces/control_protocol',
1055 'libs/surfaces/generic_midi',
1056 'libs/surfaces/tranzport',
1057 'libs/surfaces/mackie',
1058 'libs/surfaces/powermate'
1063 env['TRANZPORT'] = 1
1065 env['TRANZPORT'] = 0
1066 print 'Disabled building Tranzport code because libusb could not be found'
1068 if have_linux_input:
1069 env['POWERMATE'] = 1
1071 env['POWERMATE'] = 0
1072 print 'Disabled building Powermate code because linux/input.h could not be found'
1074 if os.access ('libs/surfaces/sony9pin', os.F_OK):
1075 surface_subdirs += [ 'libs/surfaces/sony9pin' ]
1077 env['POWERMATE'] = 0
1078 env['TRANZPORT'] = 0
1081 # timestretch libraries
1084 timefx_subdirs = ['libs/soundtouch']
1085 if env['RUBBERBAND']:
1086 timefx_subdirs += ['libs/rubberband']
1088 opts.Save('scache.conf', env)
1089 Help(opts.GenerateHelpText(env))
1091 if os.environ.has_key('PATH'):
1092 env.Append(PATH = os.environ['PATH'])
1094 if os.environ.has_key('PKG_CONFIG_PATH'):
1095 env.Append(PKG_CONFIG_PATH = os.environ['PKG_CONFIG_PATH'])
1097 if os.environ.has_key('CC'):
1098 env['CC'] = os.environ['CC']
1100 if os.environ.has_key('CXX'):
1101 env['CXX'] = os.environ['CXX']
1103 if os.environ.has_key('DISTCC_HOSTS'):
1104 env['ENV']['DISTCC_HOSTS'] = os.environ['DISTCC_HOSTS']
1105 env['ENV']['HOME'] = os.environ['HOME']
1107 final_prefix = '$PREFIX'
1110 install_prefix = '$DESTDIR/$PREFIX'
1112 install_prefix = env['PREFIX']
1114 subst_dict['%INSTALL_PREFIX%'] = install_prefix;
1115 subst_dict['%FINAL_PREFIX%'] = final_prefix;
1116 subst_dict['%PREFIX%'] = final_prefix;
1118 if env['PREFIX'] == '/usr':
1119 final_config_prefix = '/etc'
1121 final_config_prefix = env['PREFIX'] + '/etc'
1123 config_prefix = '$DESTDIR' + final_config_prefix
1126 # everybody needs this
1129 env.Merge ([ libraries['core'] ])
1136 conf = Configure (env)
1138 nls_error = 'This system is not configured for internationalized applications. An english-only version will be built:'
1139 print 'Checking for internationalization support ...'
1140 have_gettext = conf.TryAction(Action('xgettext --version'))
1141 if have_gettext[0] != 1:
1142 nls_error += ' No xgettext command.'
1145 print "Found xgettext"
1147 have_msgmerge = conf.TryAction(Action('msgmerge --version'))
1148 if have_msgmerge[0] != 1:
1149 nls_error += ' No msgmerge command.'
1152 print "Found msgmerge"
1154 if not conf.CheckCHeader('libintl.h'):
1155 nls_error += ' No libintl.h.'
1161 print "International version will be built."
1165 env.Append(CCFLAGS="-DENABLE_NLS")
1167 Export('env install_prefix final_prefix config_prefix final_config_prefix libraries i18n ardour_version subst_dict use_flac')
1170 # the configuration file may be system dependent
1173 conf = env.Configure ()
1175 if conf.CheckCHeader('/System/Library/Frameworks/CoreAudio.framework/Versions/A/Headers/CoreAudio.h'):
1176 subst_dict['%JACK_INPUT%'] = "coreaudio:Built-in Audio:in"
1177 subst_dict['%JACK_OUTPUT%'] = "coreaudio:Built-in Audio:out"
1179 subst_dict['%JACK_INPUT%'] = "alsa_pcm:playback_"
1180 subst_dict['%JACK_OUTPUT%'] = "alsa_pcm:capture_"
1182 # posix_memalign available
1183 if not conf.CheckFunc('posix_memalign'):
1184 print 'Did not find posix_memalign(), using malloc'
1185 env.Append(CCFLAGS='-DNO_POSIX_MEMALIGN')
1190 # generate the per-user and system rc files from the same source
1192 sysrcbuild = env.SubstInFile ('ardour_system.rc','ardour.rc.in', SUBST_DICT = subst_dict)
1194 # add to the substitution dictionary
1196 subst_dict['%VERSION%'] = ardour_version[0:3]
1197 subst_dict['%EXTRA_VERSION%'] = ardour_version[3:]
1198 subst_dict['%REVISION_STRING%'] = ''
1199 if os.path.exists('.svn'):
1200 subst_dict['%REVISION_STRING%'] = '.' + fetch_svn_revision ('.') + 'svn'
1202 # specbuild = env.SubstInFile ('ardour.spec','ardour.spec.in', SUBST_DICT = subst_dict)
1204 the_revision = env.Command ('frobnicatory_decoy', [], create_stored_revision)
1205 remove_ardour = env.Command ('frobnicatory_decoy2', [],
1206 [ Delete ('$PREFIX/etc/ardour2'),
1207 Delete ('$PREFIX/lib/ardour2'),
1208 Delete ('$PREFIX/bin/ardour2')])
1210 env.Alias('revision', the_revision)
1211 env.Alias('install', env.Install(os.path.join(config_prefix, 'ardour2'), 'ardour_system.rc'))
1212 env.Alias('uninstall', remove_ardour)
1214 Default (sysrcbuild)
1218 Precious (env['DISTTREE'])
1220 env.Distribute (env['DISTTREE'],
1221 [ 'SConstruct', 'svn_revision.h',
1222 'COPYING', 'PACKAGER_README', 'README',
1224 'tools/config.guess',
1225 'icons/icon/ardour_icon_mac_mask.png',
1226 'icons/icon/ardour_icon_mac.png',
1227 'icons/icon/ardour_icon_tango_16px_blue.png',
1228 'icons/icon/ardour_icon_tango_16px_red.png',
1229 'icons/icon/ardour_icon_tango_22px_blue.png',
1230 'icons/icon/ardour_icon_tango_22px_red.png',
1231 'icons/icon/ardour_icon_tango_32px_blue.png',
1232 'icons/icon/ardour_icon_tango_32px_red.png',
1233 'icons/icon/ardour_icon_tango_48px_blue.png',
1234 'icons/icon/ardour_icon_tango_48px_red.png'
1236 glob.glob ('DOCUMENTATION/AUTHORS*') +
1237 glob.glob ('DOCUMENTATION/CONTRIBUTORS*') +
1238 glob.glob ('DOCUMENTATION/TRANSLATORS*') +
1239 glob.glob ('DOCUMENTATION/BUILD*') +
1240 glob.glob ('DOCUMENTATION/FAQ*') +
1241 glob.glob ('DOCUMENTATION/README*')
1244 srcdist = env.Tarball(env['TARBALL'], [ env['DISTTREE'], the_revision ])
1245 env.Alias ('srctar', srcdist)
1248 # don't leave the distree around
1251 env.AddPreAction (env['DISTTREE'], Action ('rm -rf ' + str (File (env['DISTTREE']))))
1252 env.AddPostAction (srcdist, Action ('rm -rf ' + str (File (env['DISTTREE']))))
1258 for subdir in coredirs:
1259 SConscript (subdir + '/SConscript')
1261 for sublistdir in [ subdirs, timefx_subdirs, gtk_subdirs, surface_subdirs ]:
1262 for subdir in sublistdir:
1263 SConscript (subdir + '/SConscript')
1266 env.Clean ('scrub', [ 'scache.conf', '.sconf_temp', '.sconsign.dblite', 'config.log'])