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 libraries['rubberband'] = LibraryInfo()
477 # chris cannam's rubberband has not yet been released
479 if os.path.exists ('libs/rubberband'):
480 libraries['rubberband'] = LibraryInfo (LIBS='rubberband',
481 LIBPATH='#libs/rubberband/lib',
482 CPPPATH='#libs/rubberband/src',
483 CXXFLAGS='-DUSE_RUBBERBAND')
485 if env['FFT_ANALYSIS']:
486 libraries['fftw3f'] = LibraryInfo()
487 libraries['fftw3f'].ParseConfig('pkg-config --cflags --libs fftw3f')
489 # Check for fftw3 header as well as the library
490 conf = Configure (libraries['fftw3f'])
491 if conf.CheckHeader ('fftw3.h') == False:
492 print "FFT Analysis cannot be compiled without the FFTW3 headers, which don't seem to be installed"
494 libraries['fftw3f'] = conf.Finish();
496 libraries['jack'] = LibraryInfo()
497 libraries['jack'].ParseConfig('pkg-config --cflags --libs jack')
499 libraries['xml'] = LibraryInfo()
500 libraries['xml'].ParseConfig('pkg-config --cflags --libs libxml-2.0')
502 libraries['xslt'] = LibraryInfo()
503 libraries['xslt'].ParseConfig('pkg-config --cflags --libs libxslt')
505 libraries['glib2'] = LibraryInfo()
506 libraries['glib2'].ParseConfig ('pkg-config --cflags --libs glib-2.0')
507 libraries['glib2'].ParseConfig ('pkg-config --cflags --libs gobject-2.0')
508 libraries['glib2'].ParseConfig ('pkg-config --cflags --libs gmodule-2.0')
509 libraries['glib2'].ParseConfig ('pkg-config --cflags --libs gthread-2.0')
511 libraries['gtk2'] = LibraryInfo()
512 libraries['gtk2'].ParseConfig ('pkg-config --cflags --libs gtk+-2.0')
514 libraries['pango'] = LibraryInfo()
515 libraries['pango'].ParseConfig ('pkg-config --cflags --libs pango')
517 libraries['libgnomecanvas2'] = LibraryInfo()
518 libraries['libgnomecanvas2'].ParseConfig ('pkg-config --cflags --libs libgnomecanvas-2.0')
520 #libraries['flowcanvas'] = LibraryInfo(LIBS='flowcanvas', LIBPATH='#/libs/flowcanvas', CPPPATH='#libs/flowcanvas')
522 # The Ardour Control Protocol Library
524 libraries['ardour_cp'] = LibraryInfo (LIBS='ardour_cp', LIBPATH='#libs/surfaces/control_protocol',
525 CPPPATH='#libs/surfaces/control_protocol')
527 # The Ardour backend/engine
529 libraries['ardour'] = LibraryInfo (LIBS='ardour', LIBPATH='#libs/ardour', CPPPATH='#libs/ardour')
530 libraries['midi++2'] = LibraryInfo (LIBS='midi++', LIBPATH='#libs/midi++2', CPPPATH='#libs/midi++2')
531 libraries['pbd'] = LibraryInfo (LIBS='pbd', LIBPATH='#libs/pbd', CPPPATH='#libs/pbd')
532 libraries['gtkmm2ext'] = LibraryInfo (LIBS='gtkmm2ext', LIBPATH='#libs/gtkmm2ext', CPPPATH='#libs/gtkmm2ext')
535 # SCons should really do this for us
537 conf = Configure (env)
539 have_cxx = conf.TryAction (Action (str(env['CXX']) + ' --version'))
541 print "This system has no functional C++ compiler. You cannot build Ardour from source without one."
544 print "Congratulations, you have a functioning C++ compiler."
550 # Compiler flags and other system-dependent stuff
554 if env['GPROFILE'] == 1:
555 debug_flags = [ '-g', '-pg' ]
557 debug_flags = [ '-g' ]
559 # guess at the platform, used to define compiler flags
561 config_guess = os.popen("tools/config.guess").read()[:-1]
567 config = config_guess.split ("-")
569 print "system triple: " + config_guess
572 if env['DIST_TARGET'] == 'auto':
573 if config[config_arch] == 'apple':
574 # The [.] matches to the dot after the major version, "." would match any character
575 if re.search ("darwin[0-7][.]", config[config_kernel]) != None:
576 env['DIST_TARGET'] = 'panther'
578 env['DIST_TARGET'] = 'tiger'
580 if re.search ("x86_64", config[config_cpu]) != None:
581 env['DIST_TARGET'] = 'x86_64'
582 elif re.search("i[0-5]86", config[config_cpu]) != None:
583 env['DIST_TARGET'] = 'i386'
584 elif re.search("powerpc", config[config_cpu]) != None:
585 env['DIST_TARGET'] = 'powerpc'
587 env['DIST_TARGET'] = 'i686'
588 print "\n*******************************"
589 print "detected DIST_TARGET = " + env['DIST_TARGET']
590 print "*******************************\n"
593 if config[config_cpu] == 'powerpc' and env['DIST_TARGET'] != 'none':
595 # Apple/PowerPC optimization options
597 # -mcpu=7450 does not reliably work with gcc 3.*
599 if env['DIST_TARGET'] == 'panther' or env['DIST_TARGET'] == 'tiger':
600 if config[config_arch] == 'apple':
601 ## opt_flags.extend ([ "-mcpu=7450", "-faltivec"])
602 # to support g3s but still have some optimization for above
603 opt_flags.extend ([ "-mcpu=G3", "-mtune=7450"])
605 opt_flags.extend ([ "-mcpu=7400", "-maltivec", "-mabi=altivec"])
607 opt_flags.extend([ "-mcpu=750", "-mmultiple" ])
608 opt_flags.extend (["-mhard-float", "-mpowerpc-gfxopt"])
609 opt_flags.extend (["-Os"])
611 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':
613 build_host_supports_sse = 0
615 debug_flags.append ("-DARCH_X86")
616 opt_flags.append ("-DARCH_X86")
618 if config[config_kernel] == 'linux' :
620 if env['DIST_TARGET'] != 'i386':
622 flag_line = os.popen ("cat /proc/cpuinfo | grep '^flags'").read()[:-1]
623 x86_flags = flag_line.split (": ")[1:][0].split ()
625 if "mmx" in x86_flags:
626 opt_flags.append ("-mmmx")
627 if "sse" in x86_flags:
628 build_host_supports_sse = 1
629 if "3dnow" in x86_flags:
630 opt_flags.append ("-m3dnow")
632 if config[config_cpu] == "i586":
633 opt_flags.append ("-march=i586")
634 elif config[config_cpu] == "i686":
635 opt_flags.append ("-march=i686")
637 if ((env['DIST_TARGET'] == 'i686') or (env['DIST_TARGET'] == 'x86_64')) and build_host_supports_sse:
638 opt_flags.extend (["-msse", "-mfpmath=sse", "-DUSE_XMMINTRIN"])
639 debug_flags.extend (["-msse", "-mfpmath=sse", "-DUSE_XMMINTRIN"])
640 # end of processor-specific section
642 # optimization section
643 if env['FPU_OPTIMIZATION']:
644 if env['DIST_TARGET'] == 'tiger':
645 opt_flags.append ("-DBUILD_VECLIB_OPTIMIZATIONS")
646 debug_flags.append ("-DBUILD_VECLIB_OPTIMIZATIONS")
647 libraries['core'].Append(LINKFLAGS= '-framework Accelerate')
648 elif env['DIST_TARGET'] == 'i686' or env['DIST_TARGET'] == 'x86_64':
649 opt_flags.append ("-DBUILD_SSE_OPTIMIZATIONS")
650 debug_flags.append ("-DBUILD_SSE_OPTIMIZATIONS")
651 if env['DIST_TARGET'] == 'x86_64':
652 opt_flags.append ("-DUSE_X86_64_ASM")
653 debug_flags.append ("-DUSE_X86_64_ASM")
654 if build_host_supports_sse != 1:
655 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)"
656 # end optimization section
658 # handle x86/x86_64 libdir properly
660 if env['DIST_TARGET'] == 'x86_64':
661 env['LIBDIR']='lib64'
666 # save off guessed arch element in an env
668 env.Append(CONFIG_ARCH=config[config_arch])
672 # ARCH="..." overrides all
675 if env['ARCH'] != '':
676 opt_flags = env['ARCH'].split()
679 # prepend boiler plate optimization flags
684 "-fomit-frame-pointer",
690 if env['DEBUG'] == 1:
691 env.Append(CCFLAGS=" ".join (debug_flags))
692 env.Append(LINKFLAGS=" ".join (debug_flags))
694 env.Append(CCFLAGS=" ".join (opt_flags))
695 env.Append(LINKFLAGS=" ".join (opt_flags))
697 if env['UNIVERSAL'] == 1:
698 env.Append(CCFLAGS="-arch i386 -arch ppc")
699 env.Append(LINKFLAGS="-arch i386 -arch ppc")
705 env.Append(CCFLAGS="-Wall")
706 env.Append(CXXFLAGS="-Woverloaded-virtual")
708 if env['EXTRA_WARN']:
709 env.Append(CCFLAGS="-Wextra -pedantic -ansi")
710 env.Append(CXXFLAGS="-ansi")
711 # env.Append(CFLAGS="-iso")
714 env.Append(CCFLAGS="-DHAVE_LIBLO")
718 # fix scons nitpickiness on APPLE
722 def prep_libcheck(topenv, libinfo):
723 if topenv['DIST_TARGET'] == 'panther' or topenv['DIST_TARGET'] == 'tiger':
725 # rationale: GTK-Quartz uses jhbuild and installs to /opt/gtk by default.
726 # All libraries needed should be built against this location
728 libinfo.Append(CPPPATH="/opt/gtk/include", LIBPATH="/opt/gtk/lib")
729 libinfo.Append(CXXFLAGS="-I/opt/gtk/include", LINKFLAGS="-L/opt/gtk/lib")
730 libinfo.Append(CPPPATH="/opt/local/include", LIBPATH="/opt/local/lib")
731 libinfo.Append(CXXFLAGS="-I/opt/local/include", LINKFLAGS="-L/opt/local/lib")
733 prep_libcheck(env, env)
738 libraries['usb'] = LibraryInfo ()
739 prep_libcheck(env, libraries['usb'])
741 conf = Configure (libraries['usb'])
742 if conf.CheckLib ('usb', 'usb_interrupt_write'):
747 # check for linux/input.h while we're at it for powermate
748 if conf.CheckHeader('linux/input.h'):
749 have_linux_input = True
751 have_linux_input = False
753 libraries['usb'] = conf.Finish ()
758 libraries['flac'] = LibraryInfo ()
759 prep_libcheck(env, libraries['flac'])
760 libraries['flac'].Append(CPPPATH="/usr/local/include", LIBPATH="/usr/local/lib")
763 # june 1st 2007: look for a function that is in FLAC 1.1.2 and not in later versions
764 # since the version of libsndfile we have internally does not support
765 # the new API that libFLAC has adopted
768 conf = Configure (libraries['flac'])
769 if conf.CheckLib ('FLAC', 'FLAC__seekable_stream_decoder_init', language='CXX'):
770 conf.env.Append(CCFLAGS='-DHAVE_FLAC')
775 libraries['flac'] = conf.Finish ()
777 # or if that fails...
778 #libraries['flac'] = LibraryInfo (LIBS='FLAC')
780 # boost (we don't link against boost, just use some header files)
782 libraries['boost'] = LibraryInfo ()
783 prep_libcheck(env, libraries['boost'])
784 libraries['boost'].Append(CPPPATH="/usr/local/include", LIBPATH="/usr/local/lib")
785 conf = Configure (libraries['boost'])
786 if conf.CheckHeader ('boost/shared_ptr.hpp', language='CXX') == False:
787 print "Boost header files do not appear to be installed."
790 libraries['boost'] = conf.Finish ()
796 libraries['lo'] = LibraryInfo ()
797 prep_libcheck(env, libraries['lo'])
799 conf = Configure (libraries['lo'])
800 if conf.CheckLib ('lo', 'lo_server_new') == False:
801 print "liblo does not appear to be installed."
804 libraries['lo'] = conf.Finish ()
809 libraries['dmalloc'] = LibraryInfo ()
810 prep_libcheck(env, libraries['dmalloc'])
813 # look for the threaded version
816 conf = Configure (libraries['dmalloc'])
817 if conf.CheckLib ('dmallocth', 'dmalloc_shutdown'):
818 have_libdmalloc = True
820 have_libdmalloc = False
822 libraries['dmalloc'] = conf.Finish ()
825 # Audio/MIDI library (needed for MIDI, since audio is all handled via JACK)
828 conf = Configure(env)
830 if conf.CheckCHeader('alsa/asoundlib.h'):
831 libraries['sysmidi'] = LibraryInfo (LIBS='asound')
832 env['SYSMIDI'] = 'ALSA Sequencer'
833 subst_dict['%MIDITAG%'] = "seq"
834 subst_dict['%MIDITYPE%'] = "alsa/sequencer"
835 elif conf.CheckCHeader('/System/Library/Frameworks/CoreMIDI.framework/Headers/CoreMIDI.h'):
836 # this line is needed because scons can't handle -framework in ParseConfig() yet.
838 # We need Carbon as well as the rest
839 libraries['sysmidi'] = LibraryInfo (
840 LINKFLAGS = ' -framework CoreMIDI -framework CoreFoundation -framework CoreAudio -framework CoreServices -framework AudioUnit -framework AudioToolbox -framework Carbon -bind_at_load' )
842 libraries['sysmidi'] = LibraryInfo (
843 LINKFLAGS = ' -framework CoreMIDI -framework CoreFoundation -framework CoreAudio -framework CoreServices -framework AudioUnit -framework AudioToolbox -bind_at_load' )
844 env['SYSMIDI'] = 'CoreMIDI'
845 subst_dict['%MIDITAG%'] = "ardour"
846 subst_dict['%MIDITYPE%'] = "coremidi"
848 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."
857 'sigc++-2.0' : '2.0',
859 'libgnomecanvasmm-2.6' : '2.12.0'
862 conf = Configure(env, custom_tests = { 'CheckPKGConfig' : CheckPKGConfig,
863 'CheckPKGVersion' : CheckPKGVersion })
865 for pkg, version in syslibdeps.iteritems():
866 if not conf.CheckPKGVersion( pkg, version ):
867 print '%s >= %s not found.' %(pkg, version)
868 DependenciesRequiredMessage()
873 libraries['sigc2'] = LibraryInfo()
874 libraries['sigc2'].ParseConfig('pkg-config --cflags --libs sigc++-2.0')
875 libraries['glibmm2'] = LibraryInfo()
876 libraries['glibmm2'].ParseConfig('pkg-config --cflags --libs glibmm-2.4')
877 libraries['cairomm'] = LibraryInfo()
878 libraries['cairomm'].ParseConfig('pkg-config --cflags --libs cairomm-1.0')
879 libraries['gdkmm2'] = LibraryInfo()
880 libraries['gdkmm2'].ParseConfig ('pkg-config --cflags --libs gdkmm-2.4')
881 libraries['gtkmm2'] = LibraryInfo()
882 libraries['gtkmm2'].ParseConfig ('pkg-config --cflags --libs gtkmm-2.4')
883 libraries['atkmm'] = LibraryInfo()
884 libraries['atkmm'].ParseConfig ('pkg-config --cflags --libs atkmm-1.6')
885 libraries['pangomm'] = LibraryInfo()
886 libraries['pangomm'].ParseConfig ('pkg-config --cflags --libs pangomm-1.4')
887 libraries['libgnomecanvasmm'] = LibraryInfo()
888 libraries['libgnomecanvasmm'].ParseConfig ('pkg-config --cflags --libs libgnomecanvasmm-2.6')
891 # cannot use system one for the time being
894 libraries['sndfile-ardour'] = LibraryInfo(LIBS='libsndfile-ardour',
895 LIBPATH='#libs/libsndfile',
896 CPPPATH=['#libs/libsndfile/src'])
898 # libraries['libglademm'] = LibraryInfo()
899 # libraries['libglademm'].ParseConfig ('pkg-config --cflags --libs libglademm-2.4')
901 # libraries['flowcanvas'] = LibraryInfo(LIBS='flowcanvas', LIBPATH='#/libs/flowcanvas', CPPPATH='#libs/flowcanvas')
902 libraries['soundtouch'] = LibraryInfo()
903 libraries['soundtouch'].ParseConfig ('pkg-config --cflags --libs soundtouch-1.0')
904 # Comment the previous line and uncomment this for Debian:
905 #libraries['soundtouch'].ParseConfig ('pkg-config --cflags --libs libSoundTouch')
907 libraries['appleutility'] = LibraryInfo(LIBS='libappleutility',
908 LIBPATH='#libs/appleutility',
909 CPPPATH='#libs/appleutility')
920 # these are unconditionally included but have
921 # tests internally to avoid compilation etc
925 # this is unconditionally included but has
926 # tests internally to avoid compilation etc
927 # if COREAUDIO is not set
939 libraries['sigc2'] = LibraryInfo(LIBS='sigc++2',
940 LIBPATH='#libs/sigc++2',
941 CPPPATH='#libs/sigc++2')
942 libraries['glibmm2'] = LibraryInfo(LIBS='glibmm2',
943 LIBPATH='#libs/glibmm2',
944 CPPPATH='#libs/glibmm2')
945 libraries['pangomm'] = LibraryInfo(LIBS='pangomm',
946 LIBPATH='#libs/gtkmm2/pango',
947 CPPPATH='#libs/gtkmm2/pango')
948 libraries['atkmm'] = LibraryInfo(LIBS='atkmm',
949 LIBPATH='#libs/gtkmm2/atk',
950 CPPPATH='#libs/gtkmm2/atk')
951 libraries['gdkmm2'] = LibraryInfo(LIBS='gdkmm2',
952 LIBPATH='#libs/gtkmm2/gdk',
953 CPPPATH='#libs/gtkmm2/gdk')
954 libraries['gtkmm2'] = LibraryInfo(LIBS='gtkmm2',
955 LIBPATH="#libs/gtkmm2/gtk",
956 CPPPATH='#libs/gtkmm2/gtk/')
957 libraries['libgnomecanvasmm'] = LibraryInfo(LIBS='libgnomecanvasmm',
958 LIBPATH='#libs/libgnomecanvasmm',
959 CPPPATH='#libs/libgnomecanvasmm')
961 libraries['soundtouch'] = LibraryInfo(LIBS='soundtouch',
962 LIBPATH='#libs/soundtouch',
963 CPPPATH=['#libs', '#libs/soundtouch'])
964 libraries['sndfile-ardour'] = LibraryInfo(LIBS='libsndfile-ardour',
965 LIBPATH='#libs/libsndfile',
966 CPPPATH=['#libs/libsndfile', '#libs/libsndfile/src'])
967 # libraries['libglademm'] = LibraryInfo(LIBS='libglademm',
968 # LIBPATH='#libs/libglademm',
969 # CPPPATH='#libs/libglademm')
970 libraries['appleutility'] = LibraryInfo(LIBS='libappleutility',
971 LIBPATH='#libs/appleutility',
972 CPPPATH='#libs/appleutility')
985 # these are unconditionally included but have
986 # tests internally to avoid compilation etc
990 # this is unconditionally included but has
991 # tests internally to avoid compilation etc
992 # if COREAUDIO is not set
1002 'libs/libgnomecanvasmm',
1003 # 'libs/flowcanvas',
1010 # * always build the LGPL control protocol lib, since we link against it from libardour
1011 # * ditto for generic MIDI
1012 # * tranzport checks whether it should build internally, but we need here so that
1013 # its included in the tarball
1016 surface_subdirs = [ 'libs/surfaces/control_protocol',
1017 'libs/surfaces/generic_midi',
1018 'libs/surfaces/tranzport',
1019 'libs/surfaces/mackie',
1020 'libs/surfaces/powermate'
1025 env['TRANZPORT'] = 1
1027 env['TRANZPORT'] = 0
1028 print 'Disabled building Tranzport code because libusb could not be found'
1030 if have_linux_input:
1031 env['POWERMATE'] = 1
1033 env['POWERMATE'] = 0
1034 print 'Disabled building Powermate code because linux/input.h could not be found'
1036 if os.access ('libs/surfaces/sony9pin', os.F_OK):
1037 surface_subdirs += [ 'libs/surfaces/sony9pin' ]
1039 env['POWERMATE'] = 0
1040 env['TRANZPORT'] = 0
1042 opts.Save('scache.conf', env)
1043 Help(opts.GenerateHelpText(env))
1045 if os.environ.has_key('PATH'):
1046 env.Append(PATH = os.environ['PATH'])
1048 if os.environ.has_key('PKG_CONFIG_PATH'):
1049 env.Append(PKG_CONFIG_PATH = os.environ['PKG_CONFIG_PATH'])
1051 if os.environ.has_key('CC'):
1052 env['CC'] = os.environ['CC']
1054 if os.environ.has_key('CXX'):
1055 env['CXX'] = os.environ['CXX']
1057 if os.environ.has_key('DISTCC_HOSTS'):
1058 env['ENV']['DISTCC_HOSTS'] = os.environ['DISTCC_HOSTS']
1059 env['ENV']['HOME'] = os.environ['HOME']
1061 final_prefix = '$PREFIX'
1064 install_prefix = '$DESTDIR/$PREFIX'
1066 install_prefix = env['PREFIX']
1068 subst_dict['%INSTALL_PREFIX%'] = install_prefix;
1069 subst_dict['%FINAL_PREFIX%'] = final_prefix;
1070 subst_dict['%PREFIX%'] = final_prefix;
1072 if env['PREFIX'] == '/usr':
1073 final_config_prefix = '/etc'
1075 final_config_prefix = env['PREFIX'] + '/etc'
1077 config_prefix = '$DESTDIR' + final_config_prefix
1080 # everybody needs this
1083 env.Merge ([ libraries['core'] ])
1090 conf = Configure (env)
1092 nls_error = 'This system is not configured for internationalized applications. An english-only version will be built:'
1093 print 'Checking for internationalization support ...'
1094 have_gettext = conf.TryAction(Action('xgettext --version'))
1095 if have_gettext[0] != 1:
1096 nls_error += ' No xgettext command.'
1099 print "Found xgettext"
1101 have_msgmerge = conf.TryAction(Action('msgmerge --version'))
1102 if have_msgmerge[0] != 1:
1103 nls_error += ' No msgmerge command.'
1106 print "Found msgmerge"
1108 if not conf.CheckCHeader('libintl.h'):
1109 nls_error += ' No libintl.h.'
1115 print "International version will be built."
1119 env.Append(CCFLAGS="-DENABLE_NLS")
1121 Export('env install_prefix final_prefix config_prefix final_config_prefix libraries i18n ardour_version subst_dict use_flac')
1124 # the configuration file may be system dependent
1127 conf = env.Configure ()
1129 if conf.CheckCHeader('/System/Library/Frameworks/CoreAudio.framework/Versions/A/Headers/CoreAudio.h'):
1130 subst_dict['%JACK_INPUT%'] = "coreaudio:Built-in Audio:in"
1131 subst_dict['%JACK_OUTPUT%'] = "coreaudio:Built-in Audio:out"
1133 subst_dict['%JACK_INPUT%'] = "alsa_pcm:playback_"
1134 subst_dict['%JACK_OUTPUT%'] = "alsa_pcm:capture_"
1136 # posix_memalign available
1137 if not conf.CheckFunc('posix_memalign'):
1138 print 'Did not find posix_memalign(), using malloc'
1139 env.Append(CCFLAGS='-DNO_POSIX_MEMALIGN')
1144 # generate the per-user and system rc files from the same source
1146 sysrcbuild = env.SubstInFile ('ardour_system.rc','ardour.rc.in', SUBST_DICT = subst_dict)
1148 # add to the substitution dictionary
1150 subst_dict['%VERSION%'] = ardour_version[0:3]
1151 subst_dict['%EXTRA_VERSION%'] = ardour_version[3:]
1152 subst_dict['%REVISION_STRING%'] = ''
1153 if os.path.exists('.svn'):
1154 subst_dict['%REVISION_STRING%'] = '.' + fetch_svn_revision ('.') + 'svn'
1156 # specbuild = env.SubstInFile ('ardour.spec','ardour.spec.in', SUBST_DICT = subst_dict)
1158 the_revision = env.Command ('frobnicatory_decoy', [], create_stored_revision)
1159 remove_ardour = env.Command ('frobnicatory_decoy2', [],
1160 [ Delete ('$PREFIX/etc/ardour2'),
1161 Delete ('$PREFIX/lib/ardour2'),
1162 Delete ('$PREFIX/bin/ardour2')])
1164 env.Alias('revision', the_revision)
1165 env.Alias('install', env.Install(os.path.join(config_prefix, 'ardour2'), 'ardour_system.rc'))
1166 env.Alias('uninstall', remove_ardour)
1168 Default (sysrcbuild)
1172 Precious (env['DISTTREE'])
1174 env.Distribute (env['DISTTREE'],
1175 [ 'SConstruct', 'svn_revision.h',
1176 'COPYING', 'PACKAGER_README', 'README',
1178 'tools/config.guess',
1179 'icons/icon/ardour_icon_mac_mask.png',
1180 'icons/icon/ardour_icon_mac.png',
1181 'icons/icon/ardour_icon_tango_16px_blue.png',
1182 'icons/icon/ardour_icon_tango_16px_red.png',
1183 'icons/icon/ardour_icon_tango_22px_blue.png',
1184 'icons/icon/ardour_icon_tango_22px_red.png',
1185 'icons/icon/ardour_icon_tango_32px_blue.png',
1186 'icons/icon/ardour_icon_tango_32px_red.png',
1187 'icons/icon/ardour_icon_tango_48px_blue.png',
1188 'icons/icon/ardour_icon_tango_48px_red.png'
1190 glob.glob ('DOCUMENTATION/AUTHORS*') +
1191 glob.glob ('DOCUMENTATION/CONTRIBUTORS*') +
1192 glob.glob ('DOCUMENTATION/TRANSLATORS*') +
1193 glob.glob ('DOCUMENTATION/BUILD*') +
1194 glob.glob ('DOCUMENTATION/FAQ*') +
1195 glob.glob ('DOCUMENTATION/README*')
1198 srcdist = env.Tarball(env['TARBALL'], [ env['DISTTREE'], the_revision ])
1199 env.Alias ('srctar', srcdist)
1202 # don't leave the distree around
1205 env.AddPreAction (env['DISTTREE'], Action ('rm -rf ' + str (File (env['DISTTREE']))))
1206 env.AddPostAction (srcdist, Action ('rm -rf ' + str (File (env['DISTTREE']))))
1212 for subdir in coredirs:
1213 SConscript (subdir + '/SConscript')
1215 for sublistdir in [ subdirs, gtk_subdirs, surface_subdirs ]:
1216 for subdir in sublistdir:
1217 SConscript (subdir + '/SConscript')
1220 env.Clean ('scrub', [ 'scache.conf', '.sconf_temp', '.sconsign.dblite', 'config.log'])