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.Replace(LIBPATH = list(Set(self.get('LIBPATH', []))))
68 self.Replace(CPPPATH = list(Set(self.get('CPPPATH',[]))))
69 #doing LINKFLAGS breaks -framework
70 #doing LIBS break link order dependency
72 def ENV_update(self, src_ENV):
73 for k in src_ENV.keys():
74 if k in self['ENV'].keys() and k in [ 'PATH', 'LD_LIBRARY_PATH',
76 self['ENV'][k]=SCons.Util.AppendPath(self['ENV'][k], src_ENV[k])
78 self['ENV'][k]=src_ENV[k]
80 env = LibraryInfo (options = opts,
82 VERSION = ardour_version,
83 TARBALL='ardour-' + ardour_version + '.tar.bz2',
85 DISTTREE = '#ardour-' + ardour_version,
86 DISTCHECKDIR = '#ardour-' + ardour_version + '/check'
89 env.ENV_update(os.environ)
91 #----------------------------------------------------------------------
93 #----------------------------------------------------------------------
95 # Handy subst-in-file builder
98 def do_subst_in_file(targetfile, sourcefile, dict):
99 """Replace all instances of the keys of dict with their values.
100 For example, if dict is {'%VERSION%': '1.2345', '%BASE%': 'MyProg'},
101 then all instances of %VERSION% in the file will be replaced with 1.2345 etc.
104 f = open(sourcefile, 'rb')
108 raise SCons.Errors.UserError, "Can't read source file %s"%sourcefile
109 for (k,v) in dict.items():
110 contents = re.sub(k, v, contents)
112 f = open(targetfile, 'wb')
116 raise SCons.Errors.UserError, "Can't write target file %s"%targetfile
119 def subst_in_file(target, source, env):
120 if not env.has_key('SUBST_DICT'):
121 raise SCons.Errors.UserError, "SubstInFile requires SUBST_DICT to be set."
122 d = dict(env['SUBST_DICT']) # copy it
123 for (k,v) in d.items():
125 d[k] = env.subst(v())
126 elif SCons.Util.is_String(v):
129 raise SCons.Errors.UserError, "SubstInFile: key %s: %s must be a string or callable"%(k, repr(v))
130 for (t,s) in zip(target, source):
131 return do_subst_in_file(str(t), str(s), d)
133 def subst_in_file_string(target, source, env):
134 """This is what gets printed on the console."""
135 return '\n'.join(['Substituting vars from %s into %s'%(str(s), str(t))
136 for (t,s) in zip(target, source)])
138 def subst_emitter(target, source, env):
139 """Add dependency from substituted SUBST_DICT to target.
140 Returns original target, source tuple unchanged.
142 d = env['SUBST_DICT'].copy() # copy it
143 for (k,v) in d.items():
145 d[k] = env.subst(v())
146 elif SCons.Util.is_String(v):
148 Depends(target, SCons.Node.Python.Value(d))
149 # Depends(target, source) # this doesn't help the install-sapphire-linux.sh problem
150 return target, source
152 subst_action = Action (subst_in_file, subst_in_file_string)
153 env['BUILDERS']['SubstInFile'] = Builder(action=subst_action, emitter=subst_emitter)
156 # internationalization
159 # po_builder: builder function to copy po files to the parent directory while updating them
161 # first source: .po file
162 # second source: .pot file
165 def po_builder(target,source,env):
166 os.spawnvp (os.P_WAIT, 'cp', ['cp', str(source[0]), str(target[0])])
172 print 'Updating ' + str(target[0])
173 return os.spawnvp (os.P_WAIT, 'msgmerge', args)
175 po_bld = Builder (action = po_builder)
176 env.Append(BUILDERS = {'PoBuild' : po_bld})
178 # mo_builder: builder function for (binary) message catalogs (.mo)
180 # first source: .po file
183 def mo_builder(target,source,env):
187 target[0].get_path(),
190 return os.spawnvp (os.P_WAIT, 'msgfmt', args)
192 mo_bld = Builder (action = mo_builder)
193 env.Append(BUILDERS = {'MoBuild' : mo_bld})
195 # pot_builder: builder function for message templates (.pot)
197 # source: list of C/C++ etc. files to extract messages from
200 def pot_builder(target,source,env):
205 '-o', target[0].get_path(),
206 "--default-domain=" + env['PACKAGE'],
207 '--copyright-holder="Paul Davis"' ]
208 args += [ src.get_path() for src in source ]
210 return os.spawnvp (os.P_WAIT, 'xgettext', args)
212 pot_bld = Builder (action = pot_builder)
213 env.Append(BUILDERS = {'PotBuild' : pot_bld})
216 # utility function, not a builder
219 def i18n (buildenv, sources, installenv):
220 domain = buildenv['PACKAGE']
221 potfile = buildenv['POTFILE']
223 installenv.Alias ('potupdate', buildenv.PotBuild (potfile, sources))
225 p_oze = [ os.path.basename (po) for po in glob.glob ('po/*.po') ]
226 languages = [ po.replace ('.po', '') for po in p_oze ]
228 for po_file in p_oze:
229 buildenv.PoBuild(po_file, ['po/'+po_file, potfile])
230 mo_file = po_file.replace (".po", ".mo")
231 installenv.Alias ('install', buildenv.MoBuild (mo_file, po_file))
233 for lang in languages:
234 modir = (os.path.join (install_prefix, 'share/locale/' + lang + '/LC_MESSAGES/'))
235 moname = domain + '.mo'
236 installenv.Alias('install', installenv.InstallAs (os.path.join (modir, moname), lang + '.mo'))
239 def fetch_svn_revision (path):
243 cmd += " | awk '/^Revision:/ { print $2}'"
244 return commands.getoutput (cmd)
246 def create_stored_revision (target = None, source = None, env = None):
247 if os.path.exists('.svn'):
248 rev = fetch_svn_revision ('.');
250 text = "#ifndef __ardour_svn_revision_h__\n"
251 text += "#define __ardour_svn_revision_h__\n"
252 text += "static const char* ardour_svn_revision = \"" + rev + "\";\n";
254 print '============> writing svn revision info to svn_revision.h\n'
255 o = file ('svn_revision.h', 'w')
259 print "Could not open svn_revision.h for writing\n"
262 print "You cannot use \"scons revision\" on without using a checked out"
263 print "copy of the Ardour source code repository"
267 # A generic builder for version.cc files
269 # note: requires that DOMAIN, MAJOR, MINOR, MICRO are set in the construction environment
270 # note: assumes one source files, the header that declares the version variables
273 def version_builder (target, source, env):
275 text = "int " + env['DOMAIN'] + "_major_version = " + str (env['MAJOR']) + ";\n"
276 text += "int " + env['DOMAIN'] + "_minor_version = " + str (env['MINOR']) + ";\n"
277 text += "int " + env['DOMAIN'] + "_micro_version = " + str (env['MICRO']) + ";\n"
280 o = file (target[0].get_path(), 'w')
284 print "Could not open", target[0].get_path(), " for writing\n"
287 text = "#ifndef __" + env['DOMAIN'] + "_version_h__\n"
288 text += "#define __" + env['DOMAIN'] + "_version_h__\n"
289 text += "extern const char* " + env['DOMAIN'] + "_revision;\n"
290 text += "extern int " + env['DOMAIN'] + "_major_version;\n"
291 text += "extern int " + env['DOMAIN'] + "_minor_version;\n"
292 text += "extern int " + env['DOMAIN'] + "_micro_version;\n"
293 text += "#endif /* __" + env['DOMAIN'] + "_version_h__ */\n"
296 o = file (target[1].get_path(), 'w')
300 print "Could not open", target[1].get_path(), " for writing\n"
305 version_bld = Builder (action = version_builder)
306 env.Append (BUILDERS = {'VersionBuild' : version_bld})
309 # a builder that makes a hard link from the 'source' executable to a name with
310 # a "build ID" based on the most recent CVS activity that might be reasonably
311 # related to version activity. this relies on the idea that the SConscript
312 # file that builds the executable is updated with new version info and committed
313 # to the source code repository whenever things change.
316 def versioned_builder(target,source,env):
317 w, r = os.popen2( "LANG= svn info | awk '/^Revision:/ { print $2}'")
319 last_revision = r.readline().strip()
322 if last_revision == "":
323 print "No SVN info found - versioned executable cannot be built"
326 print "The current build ID is " + last_revision
328 tagged_executable = source[0].get_path() + '-' + last_revision
330 if os.path.exists (tagged_executable):
331 print "Replacing existing executable with the same build tag."
332 os.unlink (tagged_executable)
334 return os.link (source[0].get_path(), tagged_executable)
336 verbuild = Builder (action = versioned_builder)
337 env.Append (BUILDERS = {'VersionedExecutable' : verbuild})
340 # source tar file builder
343 def distcopy (target, source, env):
344 treedir = str (target[0])
348 except OSError, (errnum, strerror):
349 if errnum != errno.EEXIST:
350 print 'mkdir ', treedir, ':', strerror
354 # we don't know what characters might be in the file names
355 # so quote them all before passing them to the shell
357 all_files = ([ str(s) for s in source ])
358 cmd += " ".join ([ "'%s'" % quoted for quoted in all_files])
359 cmd += ' | (cd ' + treedir + ' && tar xf -)'
363 def tarballer (target, source, env):
364 cmd = 'tar -jcf ' + str (target[0]) + ' ' + str(source[0]) + " --exclude '*~'"
365 print 'running ', cmd, ' ... '
369 dist_bld = Builder (action = distcopy,
370 target_factory = SCons.Node.FS.default_fs.Entry,
371 source_factory = SCons.Node.FS.default_fs.Entry,
374 tarball_bld = Builder (action = tarballer,
375 target_factory = SCons.Node.FS.default_fs.Entry,
376 source_factory = SCons.Node.FS.default_fs.Entry)
378 env.Append (BUILDERS = {'Distribute' : dist_bld})
379 env.Append (BUILDERS = {'Tarball' : tarball_bld})
382 # Make sure they know what they are doing
386 if os.path.isfile('.personal_use_only'):
387 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."
389 sys.stdout.write ("Are you building Ardour for personal use (rather than distribution to others)? [no]: ")
390 answer = sys.stdin.readline ()
391 answer = answer.rstrip().strip()
392 if answer == "yes" or answer == "y":
393 fh = open('.personal_use_only', 'w')
395 print "OK, VST support will be enabled"
397 print 'You cannot build Ardour with VST support for distribution to others.\nIt is a violation of several different licenses. Build with VST=false.'
400 if os.path.isfile('.personal_use_only'):
401 os.remove('.personal_use_only')
404 #######################
405 # Dependency Checking #
406 #######################
410 'glib-2.0' : '2.10.1',
411 'gthread-2.0' : '2.10.1',
412 'gtk+-2.0' : '2.8.1',
413 'libxml-2.0' : '2.6.0',
414 'samplerate' : '0.1.0',
418 'libgnomecanvas-2.0' : '2.0'
421 def DependenciesRequiredMessage():
422 print 'You do not have the necessary dependencies required to build ardour'
423 print 'Please consult http://ardour.org/building for more information'
425 def CheckPKGConfig(context, version):
426 context.Message( 'Checking for pkg-config version >= %s... ' %version )
427 ret = context.TryAction('pkg-config --atleast-pkgconfig-version=%s' % version)[0]
428 context.Result( ret )
431 def CheckPKGVersion(context, name, version):
432 context.Message( 'Checking for %s... ' % name )
433 ret = context.TryAction('pkg-config --atleast-version=%s %s' %(version,name) )[0]
434 context.Result( ret )
437 conf = Configure(env, custom_tests = { 'CheckPKGConfig' : CheckPKGConfig,
438 'CheckPKGVersion' : CheckPKGVersion })
440 # I think a more recent version is needed on win32
441 min_pkg_config_version = '0.8.0'
443 if not conf.CheckPKGConfig(min_pkg_config_version):
444 print 'pkg-config >= %s not found.' % min_pkg_config_version
447 for pkg, version in deps.iteritems():
448 if not conf.CheckPKGVersion( pkg, version ):
449 print '%s >= %s not found.' %(pkg, version)
450 DependenciesRequiredMessage()
455 # ----------------------------------------------------------------------
456 # Construction environment setup
457 # ----------------------------------------------------------------------
461 libraries['core'] = LibraryInfo (CCFLAGS = '-Ilibs')
463 #libraries['sndfile'] = LibraryInfo()
464 #libraries['sndfile'].ParseConfig('pkg-config --cflags --libs sndfile')
466 libraries['lrdf'] = LibraryInfo()
467 libraries['lrdf'].ParseConfig('pkg-config --cflags --libs lrdf')
469 libraries['raptor'] = LibraryInfo()
470 libraries['raptor'].ParseConfig('pkg-config --cflags --libs raptor')
472 libraries['samplerate'] = LibraryInfo()
473 libraries['samplerate'].ParseConfig('pkg-config --cflags --libs samplerate')
475 if env['FFT_ANALYSIS']:
476 libraries['fftw3f'] = LibraryInfo()
477 libraries['fftw3f'].ParseConfig('pkg-config --cflags --libs fftw3f')
479 # Check for fftw3 header as well as the library
480 conf = Configure (libraries['fftw3f'])
481 if conf.CheckHeader ('fftw3.h') == False:
482 print "FFT Analysis cannot be compiled without the FFTW3 headers, which don't seem to be installed"
484 libraries['fftw3f'] = conf.Finish();
486 libraries['jack'] = LibraryInfo()
487 libraries['jack'].ParseConfig('pkg-config --cflags --libs jack')
489 libraries['xml'] = LibraryInfo()
490 libraries['xml'].ParseConfig('pkg-config --cflags --libs libxml-2.0')
492 libraries['xslt'] = LibraryInfo()
493 libraries['xslt'].ParseConfig('pkg-config --cflags --libs libxslt')
495 libraries['glib2'] = LibraryInfo()
496 libraries['glib2'].ParseConfig ('pkg-config --cflags --libs glib-2.0')
497 libraries['glib2'].ParseConfig ('pkg-config --cflags --libs gobject-2.0')
498 libraries['glib2'].ParseConfig ('pkg-config --cflags --libs gmodule-2.0')
499 libraries['glib2'].ParseConfig ('pkg-config --cflags --libs gthread-2.0')
501 libraries['gtk2'] = LibraryInfo()
502 libraries['gtk2'].ParseConfig ('pkg-config --cflags --libs gtk+-2.0')
504 libraries['pango'] = LibraryInfo()
505 libraries['pango'].ParseConfig ('pkg-config --cflags --libs pango')
507 libraries['libgnomecanvas2'] = LibraryInfo()
508 libraries['libgnomecanvas2'].ParseConfig ('pkg-config --cflags --libs libgnomecanvas-2.0')
510 #libraries['flowcanvas'] = LibraryInfo(LIBS='flowcanvas', LIBPATH='#/libs/flowcanvas', CPPPATH='#libs/flowcanvas')
512 # The Ardour Control Protocol Library
514 libraries['ardour_cp'] = LibraryInfo (LIBS='ardour_cp', LIBPATH='#libs/surfaces/control_protocol',
515 CPPPATH='#libs/surfaces/control_protocol')
517 # The Ardour backend/engine
519 libraries['ardour'] = LibraryInfo (LIBS='ardour', LIBPATH='#libs/ardour', CPPPATH='#libs/ardour')
520 libraries['midi++2'] = LibraryInfo (LIBS='midi++', LIBPATH='#libs/midi++2', CPPPATH='#libs/midi++2')
521 libraries['pbd'] = LibraryInfo (LIBS='pbd', LIBPATH='#libs/pbd', CPPPATH='#libs/pbd')
522 libraries['gtkmm2ext'] = LibraryInfo (LIBS='gtkmm2ext', LIBPATH='#libs/gtkmm2ext', CPPPATH='#libs/gtkmm2ext')
525 # SCons should really do this for us
527 conf = Configure (env)
529 have_cxx = conf.TryAction (Action (str(env['CXX']) + ' --version'))
531 print "This system has no functional C++ compiler. You cannot build Ardour from source without one."
534 print "Congratulations, you have a functioning C++ compiler."
540 # Compiler flags and other system-dependent stuff
544 if env['GPROFILE'] == 1:
545 debug_flags = [ '-g', '-pg' ]
547 debug_flags = [ '-g' ]
549 # guess at the platform, used to define compiler flags
551 config_guess = os.popen("tools/config.guess").read()[:-1]
557 config = config_guess.split ("-")
559 print "system triple: " + config_guess
562 if env['DIST_TARGET'] == 'auto':
563 if config[config_arch] == 'apple':
564 # The [.] matches to the dot after the major version, "." would match any character
565 if re.search ("darwin[0-7][.]", config[config_kernel]) != None:
566 env['DIST_TARGET'] = 'panther'
568 env['DIST_TARGET'] = 'tiger'
570 if re.search ("x86_64", config[config_cpu]) != None:
571 env['DIST_TARGET'] = 'x86_64'
572 elif re.search("i[0-5]86", config[config_cpu]) != None:
573 env['DIST_TARGET'] = 'i386'
574 elif re.search("powerpc", config[config_cpu]) != None:
575 env['DIST_TARGET'] = 'powerpc'
577 env['DIST_TARGET'] = 'i686'
578 print "\n*******************************"
579 print "detected DIST_TARGET = " + env['DIST_TARGET']
580 print "*******************************\n"
583 if config[config_cpu] == 'powerpc' and env['DIST_TARGET'] != 'none':
585 # Apple/PowerPC optimization options
587 # -mcpu=7450 does not reliably work with gcc 3.*
589 if env['DIST_TARGET'] == 'panther' or env['DIST_TARGET'] == 'tiger':
590 if config[config_arch] == 'apple':
591 ## opt_flags.extend ([ "-mcpu=7450", "-faltivec"])
592 # to support g3s but still have some optimization for above
593 opt_flags.extend ([ "-mcpu=G3", "-mtune=7450"])
595 opt_flags.extend ([ "-mcpu=7400", "-maltivec", "-mabi=altivec"])
597 opt_flags.extend([ "-mcpu=750", "-mmultiple" ])
598 opt_flags.extend (["-mhard-float", "-mpowerpc-gfxopt"])
599 opt_flags.extend (["-Os"])
601 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':
603 build_host_supports_sse = 0
605 debug_flags.append ("-DARCH_X86")
606 opt_flags.append ("-DARCH_X86")
608 if config[config_kernel] == 'linux' :
610 if env['DIST_TARGET'] != 'i386':
612 flag_line = os.popen ("cat /proc/cpuinfo | grep '^flags'").read()[:-1]
613 x86_flags = flag_line.split (": ")[1:][0].split ()
615 if "mmx" in x86_flags:
616 opt_flags.append ("-mmmx")
617 if "sse" in x86_flags:
618 build_host_supports_sse = 1
619 if "3dnow" in x86_flags:
620 opt_flags.append ("-m3dnow")
622 if config[config_cpu] == "i586":
623 opt_flags.append ("-march=i586")
624 elif config[config_cpu] == "i686":
625 opt_flags.append ("-march=i686")
627 if ((env['DIST_TARGET'] == 'i686') or (env['DIST_TARGET'] == 'x86_64')) and build_host_supports_sse:
628 opt_flags.extend (["-msse", "-mfpmath=sse", "-DUSE_XMMINTRIN"])
629 debug_flags.extend (["-msse", "-mfpmath=sse", "-DUSE_XMMINTRIN"])
630 # end of processor-specific section
632 # optimization section
633 if env['FPU_OPTIMIZATION']:
634 if env['DIST_TARGET'] == 'tiger':
635 opt_flags.append ("-DBUILD_VECLIB_OPTIMIZATIONS")
636 debug_flags.append ("-DBUILD_VECLIB_OPTIMIZATIONS")
637 libraries['core'].Append(LINKFLAGS= '-framework Accelerate')
638 elif env['DIST_TARGET'] == 'i686' or env['DIST_TARGET'] == 'x86_64':
639 opt_flags.append ("-DBUILD_SSE_OPTIMIZATIONS")
640 debug_flags.append ("-DBUILD_SSE_OPTIMIZATIONS")
641 if env['DIST_TARGET'] == 'x86_64':
642 opt_flags.append ("-DUSE_X86_64_ASM")
643 debug_flags.append ("-DUSE_X86_64_ASM")
644 if build_host_supports_sse != 1:
645 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)"
646 # end optimization section
648 # handle x86/x86_64 libdir properly
650 if env['DIST_TARGET'] == 'x86_64':
651 env['LIBDIR']='lib64'
656 # save off guessed arch element in an env
658 env.Append(CONFIG_ARCH=config[config_arch])
662 # ARCH="..." overrides all
665 if env['ARCH'] != '':
666 opt_flags = env['ARCH'].split()
669 # prepend boiler plate optimization flags
674 "-fomit-frame-pointer",
680 if env['DEBUG'] == 1:
681 env.Append(CCFLAGS=" ".join (debug_flags))
682 env.Append(LINKFLAGS=" ".join (debug_flags))
684 env.Append(CCFLAGS=" ".join (opt_flags))
685 env.Append(LINKFLAGS=" ".join (opt_flags))
687 if env['UNIVERSAL'] == 1:
688 env.Append(CCFLAGS="-arch i386 -arch ppc")
689 env.Append(LINKFLAGS="-arch i386 -arch ppc")
695 env.Append(CCFLAGS="-Wall")
696 env.Append(CXXFLAGS="-Woverloaded-virtual")
698 if env['EXTRA_WARN']:
699 env.Append(CCFLAGS="-Wextra -pedantic -ansi")
700 env.Append(CXXFLAGS="-ansi")
701 # env.Append(CFLAGS="-iso")
704 env.Append(CCFLAGS="-DHAVE_LIBLO")
708 # fix scons nitpickiness on APPLE
712 def prep_libcheck(topenv, libinfo):
713 if topenv['DIST_TARGET'] == 'panther' or topenv['DIST_TARGET'] == 'tiger':
715 # rationale: GTK-Quartz uses jhbuild and installs to /opt/gtk by default.
716 # All libraries needed should be built against this location
718 libinfo.Append(CPPPATH="/opt/gtk/include", LIBPATH="/opt/gtk/lib")
719 libinfo.Append(CXXFLAGS="-I/opt/gtk/include", LINKFLAGS="-L/opt/gtk/lib")
720 libinfo.Append(CPPPATH="/opt/local/include", LIBPATH="/opt/local/lib")
721 libinfo.Append(CXXFLAGS="-I/opt/local/include", LINKFLAGS="-L/opt/local/lib")
723 prep_libcheck(env, env)
728 libraries['usb'] = LibraryInfo ()
729 prep_libcheck(env, libraries['usb'])
731 conf = Configure (libraries['usb'])
732 if conf.CheckLib ('usb', 'usb_interrupt_write'):
737 # check for linux/input.h while we're at it for powermate
738 if conf.CheckHeader('linux/input.h'):
739 have_linux_input = True
741 have_linux_input = False
743 libraries['usb'] = conf.Finish ()
748 libraries['flac'] = LibraryInfo ()
749 prep_libcheck(env, libraries['flac'])
750 libraries['flac'].Append(CPPPATH="/usr/local/include", LIBPATH="/usr/local/lib")
753 # june 1st 2007: look for a function that is in FLAC 1.1.2 and not in later versions
754 # since the version of libsndfile we have internally does not support
755 # the new API that libFLAC has adopted
758 conf = Configure (libraries['flac'])
759 if conf.CheckLib ('FLAC', 'FLAC__seekable_stream_decoder_init', language='CXX'):
760 conf.env.Append(CCFLAGS='-DHAVE_FLAC')
765 libraries['flac'] = conf.Finish ()
767 # or if that fails...
768 #libraries['flac'] = LibraryInfo (LIBS='FLAC')
770 # boost (we don't link against boost, just use some header files)
772 libraries['boost'] = LibraryInfo ()
773 prep_libcheck(env, libraries['boost'])
774 libraries['boost'].Append(CPPPATH="/usr/local/include", LIBPATH="/usr/local/lib")
775 conf = Configure (libraries['boost'])
776 if conf.CheckHeader ('boost/shared_ptr.hpp', language='CXX') == False:
777 print "Boost header files do not appear to be installed."
780 libraries['boost'] = conf.Finish ()
786 libraries['lo'] = LibraryInfo ()
787 prep_libcheck(env, libraries['lo'])
789 conf = Configure (libraries['lo'])
790 if conf.CheckLib ('lo', 'lo_server_new') == False:
791 print "liblo does not appear to be installed."
794 libraries['lo'] = conf.Finish ()
799 libraries['dmalloc'] = LibraryInfo ()
800 prep_libcheck(env, libraries['dmalloc'])
803 # look for the threaded version
806 conf = Configure (libraries['dmalloc'])
807 if conf.CheckLib ('dmallocth', 'dmalloc_shutdown'):
808 have_libdmalloc = True
810 have_libdmalloc = False
812 libraries['dmalloc'] = conf.Finish ()
815 # Audio/MIDI library (needed for MIDI, since audio is all handled via JACK)
818 conf = Configure(env)
820 if conf.CheckCHeader('alsa/asoundlib.h'):
821 libraries['sysmidi'] = LibraryInfo (LIBS='asound')
822 env['SYSMIDI'] = 'ALSA Sequencer'
823 subst_dict['%MIDITAG%'] = "seq"
824 subst_dict['%MIDITYPE%'] = "alsa/sequencer"
825 elif conf.CheckCHeader('/System/Library/Frameworks/CoreMIDI.framework/Headers/CoreMIDI.h'):
826 # this line is needed because scons can't handle -framework in ParseConfig() yet.
828 # We need Carbon as well as the rest
829 libraries['sysmidi'] = LibraryInfo (
830 LINKFLAGS = ' -framework CoreMIDI -framework CoreFoundation -framework CoreAudio -framework CoreServices -framework AudioUnit -framework AudioToolbox -framework Carbon -bind_at_load' )
832 libraries['sysmidi'] = LibraryInfo (
833 LINKFLAGS = ' -framework CoreMIDI -framework CoreFoundation -framework CoreAudio -framework CoreServices -framework AudioUnit -framework AudioToolbox -bind_at_load' )
834 env['SYSMIDI'] = 'CoreMIDI'
835 subst_dict['%MIDITAG%'] = "ardour"
836 subst_dict['%MIDITYPE%'] = "coremidi"
838 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."
847 'sigc++-2.0' : '2.0',
849 'libgnomecanvasmm-2.6' : '2.12.0'
852 conf = Configure(env, custom_tests = { 'CheckPKGConfig' : CheckPKGConfig,
853 'CheckPKGVersion' : CheckPKGVersion })
855 for pkg, version in syslibdeps.iteritems():
856 if not conf.CheckPKGVersion( pkg, version ):
857 print '%s >= %s not found.' %(pkg, version)
858 DependenciesRequiredMessage()
863 libraries['sigc2'] = LibraryInfo()
864 libraries['sigc2'].ParseConfig('pkg-config --cflags --libs sigc++-2.0')
865 libraries['glibmm2'] = LibraryInfo()
866 libraries['glibmm2'].ParseConfig('pkg-config --cflags --libs glibmm-2.4')
867 libraries['cairomm'] = LibraryInfo()
868 libraries['cairomm'].ParseConfig('pkg-config --cflags --libs cairomm-1.0')
869 libraries['gdkmm2'] = LibraryInfo()
870 libraries['gdkmm2'].ParseConfig ('pkg-config --cflags --libs gdkmm-2.4')
871 libraries['gtkmm2'] = LibraryInfo()
872 libraries['gtkmm2'].ParseConfig ('pkg-config --cflags --libs gtkmm-2.4')
873 libraries['atkmm'] = LibraryInfo()
874 libraries['atkmm'].ParseConfig ('pkg-config --cflags --libs atkmm-1.6')
875 libraries['pangomm'] = LibraryInfo()
876 libraries['pangomm'].ParseConfig ('pkg-config --cflags --libs pangomm-1.4')
877 libraries['libgnomecanvasmm'] = LibraryInfo()
878 libraries['libgnomecanvasmm'].ParseConfig ('pkg-config --cflags --libs libgnomecanvasmm-2.6')
881 # cannot use system one for the time being
884 libraries['sndfile-ardour'] = LibraryInfo(LIBS='libsndfile-ardour',
885 LIBPATH='#libs/libsndfile',
886 CPPPATH=['#libs/libsndfile/src'])
888 # libraries['libglademm'] = LibraryInfo()
889 # libraries['libglademm'].ParseConfig ('pkg-config --cflags --libs libglademm-2.4')
891 # libraries['flowcanvas'] = LibraryInfo(LIBS='flowcanvas', LIBPATH='#/libs/flowcanvas', CPPPATH='#libs/flowcanvas')
892 libraries['soundtouch'] = LibraryInfo()
893 libraries['soundtouch'].ParseConfig ('pkg-config --cflags --libs soundtouch-1.0')
894 # Comment the previous line and uncomment this for Debian:
895 #libraries['soundtouch'].ParseConfig ('pkg-config --cflags --libs libSoundTouch')
897 libraries['appleutility'] = LibraryInfo(LIBS='libappleutility',
898 LIBPATH='#libs/appleutility',
899 CPPPATH='#libs/appleutility')
910 # these are unconditionally included but have
911 # tests internally to avoid compilation etc
915 # this is unconditionally included but has
916 # tests internally to avoid compilation etc
917 # if COREAUDIO is not set
929 libraries['sigc2'] = LibraryInfo(LIBS='sigc++2',
930 LIBPATH='#libs/sigc++2',
931 CPPPATH='#libs/sigc++2')
932 libraries['glibmm2'] = LibraryInfo(LIBS='glibmm2',
933 LIBPATH='#libs/glibmm2',
934 CPPPATH='#libs/glibmm2')
935 libraries['pangomm'] = LibraryInfo(LIBS='pangomm',
936 LIBPATH='#libs/gtkmm2/pango',
937 CPPPATH='#libs/gtkmm2/pango')
938 libraries['atkmm'] = LibraryInfo(LIBS='atkmm',
939 LIBPATH='#libs/gtkmm2/atk',
940 CPPPATH='#libs/gtkmm2/atk')
941 libraries['gdkmm2'] = LibraryInfo(LIBS='gdkmm2',
942 LIBPATH='#libs/gtkmm2/gdk',
943 CPPPATH='#libs/gtkmm2/gdk')
944 libraries['gtkmm2'] = LibraryInfo(LIBS='gtkmm2',
945 LIBPATH="#libs/gtkmm2/gtk",
946 CPPPATH='#libs/gtkmm2/gtk/')
947 libraries['libgnomecanvasmm'] = LibraryInfo(LIBS='libgnomecanvasmm',
948 LIBPATH='#libs/libgnomecanvasmm',
949 CPPPATH='#libs/libgnomecanvasmm')
951 libraries['soundtouch'] = LibraryInfo(LIBS='soundtouch',
952 LIBPATH='#libs/soundtouch',
953 CPPPATH=['#libs', '#libs/soundtouch'])
954 libraries['sndfile-ardour'] = LibraryInfo(LIBS='libsndfile-ardour',
955 LIBPATH='#libs/libsndfile',
956 CPPPATH=['#libs/libsndfile', '#libs/libsndfile/src'])
957 # libraries['libglademm'] = LibraryInfo(LIBS='libglademm',
958 # LIBPATH='#libs/libglademm',
959 # CPPPATH='#libs/libglademm')
960 libraries['appleutility'] = LibraryInfo(LIBS='libappleutility',
961 LIBPATH='#libs/appleutility',
962 CPPPATH='#libs/appleutility')
975 # these are unconditionally included but have
976 # tests internally to avoid compilation etc
980 # this is unconditionally included but has
981 # tests internally to avoid compilation etc
982 # if COREAUDIO is not set
992 'libs/libgnomecanvasmm',
1000 # * always build the LGPL control protocol lib, since we link against it from libardour
1001 # * ditto for generic MIDI
1002 # * tranzport checks whether it should build internally, but we need here so that
1003 # its included in the tarball
1006 surface_subdirs = [ 'libs/surfaces/control_protocol',
1007 'libs/surfaces/generic_midi',
1008 'libs/surfaces/tranzport',
1009 'libs/surfaces/mackie',
1010 'libs/surfaces/powermate'
1015 env['TRANZPORT'] = 1
1017 env['TRANZPORT'] = 0
1018 print 'Disabled building Tranzport code because libusb could not be found'
1020 if have_linux_input:
1021 env['POWERMATE'] = 1
1023 env['POWERMATE'] = 0
1024 print 'Disabled building Powermate code because linux/input.h could not be found'
1026 if os.access ('libs/surfaces/sony9pin', os.F_OK):
1027 surface_subdirs += [ 'libs/surfaces/sony9pin' ]
1029 env['POWERMATE'] = 0
1030 env['TRANZPORT'] = 0
1032 opts.Save('scache.conf', env)
1033 Help(opts.GenerateHelpText(env))
1035 if os.environ.has_key('PATH'):
1036 env.Append(PATH = os.environ['PATH'])
1038 if os.environ.has_key('PKG_CONFIG_PATH'):
1039 env.Append(PKG_CONFIG_PATH = os.environ['PKG_CONFIG_PATH'])
1041 if os.environ.has_key('CC'):
1042 env['CC'] = os.environ['CC']
1044 if os.environ.has_key('CXX'):
1045 env['CXX'] = os.environ['CXX']
1047 if os.environ.has_key('DISTCC_HOSTS'):
1048 env['ENV']['DISTCC_HOSTS'] = os.environ['DISTCC_HOSTS']
1049 env['ENV']['HOME'] = os.environ['HOME']
1051 final_prefix = '$PREFIX'
1054 install_prefix = '$DESTDIR/$PREFIX'
1056 install_prefix = env['PREFIX']
1058 subst_dict['%INSTALL_PREFIX%'] = install_prefix;
1059 subst_dict['%FINAL_PREFIX%'] = final_prefix;
1060 subst_dict['%PREFIX%'] = final_prefix;
1062 if env['PREFIX'] == '/usr':
1063 final_config_prefix = '/etc'
1065 final_config_prefix = env['PREFIX'] + '/etc'
1067 config_prefix = '$DESTDIR' + final_config_prefix
1070 # everybody needs this
1073 env.Merge ([ libraries['core'] ])
1080 conf = Configure (env)
1082 nls_error = 'This system is not configured for internationalized applications. An english-only version will be built:'
1083 print 'Checking for internationalization support ...'
1084 have_gettext = conf.TryAction(Action('xgettext --version'))
1085 if have_gettext[0] != 1:
1086 nls_error += ' No xgettext command.'
1089 print "Found xgettext"
1091 have_msgmerge = conf.TryAction(Action('msgmerge --version'))
1092 if have_msgmerge[0] != 1:
1093 nls_error += ' No msgmerge command.'
1096 print "Found msgmerge"
1098 if not conf.CheckCHeader('libintl.h'):
1099 nls_error += ' No libintl.h.'
1105 print "International version will be built."
1109 env.Append(CCFLAGS="-DENABLE_NLS")
1111 Export('env install_prefix final_prefix config_prefix final_config_prefix libraries i18n ardour_version subst_dict use_flac')
1114 # the configuration file may be system dependent
1117 conf = env.Configure ()
1119 if conf.CheckCHeader('/System/Library/Frameworks/CoreAudio.framework/Versions/A/Headers/CoreAudio.h'):
1120 subst_dict['%JACK_INPUT%'] = "coreaudio:Built-in Audio:in"
1121 subst_dict['%JACK_OUTPUT%'] = "coreaudio:Built-in Audio:out"
1123 subst_dict['%JACK_INPUT%'] = "alsa_pcm:playback_"
1124 subst_dict['%JACK_OUTPUT%'] = "alsa_pcm:capture_"
1126 # posix_memalign available
1127 if not conf.CheckFunc('posix_memalign'):
1128 print 'Did not find posix_memalign(), using malloc'
1129 env.Append(CCFLAGS='-DNO_POSIX_MEMALIGN')
1134 # generate the per-user and system rc files from the same source
1136 sysrcbuild = env.SubstInFile ('ardour_system.rc','ardour.rc.in', SUBST_DICT = subst_dict)
1138 # add to the substitution dictionary
1140 subst_dict['%VERSION%'] = ardour_version[0:3]
1141 subst_dict['%EXTRA_VERSION%'] = ardour_version[3:]
1142 subst_dict['%REVISION_STRING%'] = ''
1143 if os.path.exists('.svn'):
1144 subst_dict['%REVISION_STRING%'] = '.' + fetch_svn_revision ('.') + 'svn'
1146 # specbuild = env.SubstInFile ('ardour.spec','ardour.spec.in', SUBST_DICT = subst_dict)
1148 the_revision = env.Command ('frobnicatory_decoy', [], create_stored_revision)
1149 remove_ardour = env.Command ('frobnicatory_decoy2', [],
1150 [ Delete ('$PREFIX/etc/ardour2'),
1151 Delete ('$PREFIX/lib/ardour2'),
1152 Delete ('$PREFIX/bin/ardour2')])
1154 env.Alias('revision', the_revision)
1155 env.Alias('install', env.Install(os.path.join(config_prefix, 'ardour2'), 'ardour_system.rc'))
1156 env.Alias('uninstall', remove_ardour)
1158 Default (sysrcbuild)
1162 Precious (env['DISTTREE'])
1164 env.Distribute (env['DISTTREE'],
1165 [ 'SConstruct', 'svn_revision.h',
1166 'COPYING', 'PACKAGER_README', 'README',
1168 'tools/config.guess',
1169 'icons/icon/ardour_icon_mac_mask.png',
1170 'icons/icon/ardour_icon_mac.png',
1171 'icons/icon/ardour_icon_tango_16px_blue.png',
1172 'icons/icon/ardour_icon_tango_16px_red.png',
1173 'icons/icon/ardour_icon_tango_22px_blue.png',
1174 'icons/icon/ardour_icon_tango_22px_red.png',
1175 'icons/icon/ardour_icon_tango_32px_blue.png',
1176 'icons/icon/ardour_icon_tango_32px_red.png',
1177 'icons/icon/ardour_icon_tango_48px_blue.png',
1178 'icons/icon/ardour_icon_tango_48px_red.png'
1180 glob.glob ('DOCUMENTATION/AUTHORS*') +
1181 glob.glob ('DOCUMENTATION/CONTRIBUTORS*') +
1182 glob.glob ('DOCUMENTATION/TRANSLATORS*') +
1183 glob.glob ('DOCUMENTATION/BUILD*') +
1184 glob.glob ('DOCUMENTATION/FAQ*') +
1185 glob.glob ('DOCUMENTATION/README*')
1188 srcdist = env.Tarball(env['TARBALL'], [ env['DISTTREE'], the_revision ])
1189 env.Alias ('srctar', srcdist)
1192 # don't leave the distree around
1195 env.AddPreAction (env['DISTTREE'], Action ('rm -rf ' + str (File (env['DISTTREE']))))
1196 env.AddPostAction (srcdist, Action ('rm -rf ' + str (File (env['DISTTREE']))))
1202 for subdir in coredirs:
1203 SConscript (subdir + '/SConscript')
1205 for sublistdir in [ subdirs, gtk_subdirs, surface_subdirs ]:
1206 for subdir in sublistdir:
1207 SConscript (subdir + '/SConscript')
1210 env.Clean ('scrub', [ 'scache.conf', '.sconf_temp', '.sconsign.dblite', 'config.log'])