17 EnsureSConsVersion(0, 96)
19 ardour_version = '3.0'
24 # Command-line options
27 opts = Options('scache.conf')
29 ('ARCH', 'Set architecture-specific compilation flags by hand (all flags as 1 argument)',''),
30 BoolOption('AUDIOUNITS', 'Compile with Apple\'s AudioUnit library. (experimental)', 0),
31 BoolOption('COREAUDIO', 'Compile with Apple\'s CoreAudio library', 0),
32 BoolOption('GTKOSX', 'Compile for use with GTK-OSX, not GTK-X11', 0),
33 BoolOption('NATIVE_OSX_KEYS', 'Build key bindings file that matches OS X conventions', 0),
34 BoolOption('DEBUG', 'Set to build with debugging information and no optimizations', 0),
35 PathOption('DESTDIR', 'Set the intermediate install "prefix"', '/'),
36 EnumOption('DIST_TARGET', 'Build target for cross compiling packagers', 'auto', allowed_values=('auto', 'i386', 'i686', 'x86_64', 'powerpc', 'tiger', 'panther', 'none' ), ignorecase=2),
37 BoolOption('DMALLOC', 'Compile and link using the dmalloc library', 0),
38 BoolOption('EXTRA_WARN', 'Compile with -Wextra, -ansi, and -pedantic. Might break compilation. For pedants', 0),
39 BoolOption('FFT_ANALYSIS', 'Include FFT analysis window', 0),
40 BoolOption('FPU_OPTIMIZATION', 'Build runtime checked assembler code', 1),
41 BoolOption('LIBLO', 'Compile with support for liblo library', 1),
42 BoolOption('NLS', 'Set to turn on i18n support', 1),
43 PathOption('PREFIX', 'Set the install "prefix"', '/usr/local'),
44 BoolOption('SURFACES', 'Build support for control surfaces', 1),
45 BoolOption('SYSLIBS', 'USE AT YOUR OWN RISK: CANCELS ALL SUPPORT FROM ARDOUR AUTHORS: Use existing system versions of various libraries instead of internal ones', 0),
46 BoolOption('UNIVERSAL', 'Compile as universal binary. Requires that external libraries are already universal.', 0),
47 BoolOption('VERSIONED', 'Add revision information to ardour/gtk executable name inside the build directory', 0),
48 BoolOption('VST', 'Compile with support for VST', 0),
49 BoolOption('GPROFILE', 'Compile with support for gprofile (Developers only)', 0),
50 BoolOption('TRANZPORT', 'Compile with support for Frontier Designs (if libusb is available)', 1)
53 #----------------------------------------------------------------------
54 # a handy helper that provides a way to merge compile/link information
55 # from multiple different "environments"
56 #----------------------------------------------------------------------
58 class LibraryInfo(Environment):
59 def __init__(self,*args,**kw):
60 Environment.__init__ (self,*args,**kw)
62 def Merge (self,others):
64 self.Append (LIBS = other.get ('LIBS',[]))
65 self.Append (LIBPATH = other.get ('LIBPATH', []))
66 self.Append (CPPPATH = other.get('CPPPATH', []))
67 self.Append (LINKFLAGS = other.get('LINKFLAGS', []))
68 self.Append (CCFLAGS = other.get('CCFLAGS', []))
69 self.Replace(LIBPATH = list(Set(self.get('LIBPATH', []))))
70 self.Replace(CPPPATH = list(Set(self.get('CPPPATH',[]))))
71 #doing LINKFLAGS breaks -framework
72 #doing LIBS break link order dependency
74 def ENV_update(self, src_ENV):
75 for k in src_ENV.keys():
76 if k in self['ENV'].keys() and k in [ 'PATH', 'LD_LIBRARY_PATH',
78 self['ENV'][k]=SCons.Util.AppendPath(self['ENV'][k], src_ENV[k])
80 self['ENV'][k]=src_ENV[k]
82 env = LibraryInfo (options = opts,
84 VERSION = ardour_version,
85 TARBALL='ardour-' + ardour_version + '.tar.bz2',
87 DISTTREE = '#ardour-' + ardour_version,
88 DISTCHECKDIR = '#ardour-' + ardour_version + '/check'
91 env.ENV_update(os.environ)
93 #----------------------------------------------------------------------
95 #----------------------------------------------------------------------
97 # Handy subst-in-file builder
100 def do_subst_in_file(targetfile, sourcefile, dict):
101 """Replace all instances of the keys of dict with their values.
102 For example, if dict is {'%VERSION%': '1.2345', '%BASE%': 'MyProg'},
103 then all instances of %VERSION% in the file will be replaced with 1.2345 etc.
106 f = open(sourcefile, 'rb')
110 raise SCons.Errors.UserError, "Can't read source file %s"%sourcefile
111 for (k,v) in dict.items():
112 contents = re.sub(k, v, contents)
114 f = open(targetfile, 'wb')
118 raise SCons.Errors.UserError, "Can't write target file %s"%targetfile
121 def subst_in_file(target, source, env):
122 if not env.has_key('SUBST_DICT'):
123 raise SCons.Errors.UserError, "SubstInFile requires SUBST_DICT to be set."
124 d = dict(env['SUBST_DICT']) # copy it
125 for (k,v) in d.items():
127 d[k] = env.subst(v())
128 elif SCons.Util.is_String(v):
131 raise SCons.Errors.UserError, "SubstInFile: key %s: %s must be a string or callable"%(k, repr(v))
132 for (t,s) in zip(target, source):
133 return do_subst_in_file(str(t), str(s), d)
135 def subst_in_file_string(target, source, env):
136 """This is what gets printed on the console."""
137 return '\n'.join(['Substituting vars from %s into %s'%(str(s), str(t))
138 for (t,s) in zip(target, source)])
140 def subst_emitter(target, source, env):
141 """Add dependency from substituted SUBST_DICT to target.
142 Returns original target, source tuple unchanged.
144 d = env['SUBST_DICT'].copy() # copy it
145 for (k,v) in d.items():
147 d[k] = env.subst(v())
148 elif SCons.Util.is_String(v):
150 Depends(target, SCons.Node.Python.Value(d))
151 # Depends(target, source) # this doesn't help the install-sapphire-linux.sh problem
152 return target, source
154 subst_action = Action (subst_in_file, subst_in_file_string)
155 env['BUILDERS']['SubstInFile'] = Builder(action=subst_action, emitter=subst_emitter)
158 # internationalization
161 # po_builder: builder function to copy po files to the parent directory while updating them
163 # first source: .po file
164 # second source: .pot file
167 def po_builder(target,source,env):
168 os.spawnvp (os.P_WAIT, 'cp', ['cp', str(source[0]), str(target[0])])
174 print 'Updating ' + str(target[0])
175 return os.spawnvp (os.P_WAIT, 'msgmerge', args)
177 po_bld = Builder (action = po_builder)
178 env.Append(BUILDERS = {'PoBuild' : po_bld})
180 # mo_builder: builder function for (binary) message catalogs (.mo)
182 # first source: .po file
185 def mo_builder(target,source,env):
189 target[0].get_path(),
192 return os.spawnvp (os.P_WAIT, 'msgfmt', args)
194 mo_bld = Builder (action = mo_builder)
195 env.Append(BUILDERS = {'MoBuild' : mo_bld})
197 # pot_builder: builder function for message templates (.pot)
199 # source: list of C/C++ etc. files to extract messages from
202 def pot_builder(target,source,env):
207 '-o', target[0].get_path(),
208 "--default-domain=" + env['PACKAGE'],
209 '--copyright-holder="Paul Davis"' ]
210 args += [ src.get_path() for src in source ]
212 return os.spawnvp (os.P_WAIT, 'xgettext', args)
214 pot_bld = Builder (action = pot_builder)
215 env.Append(BUILDERS = {'PotBuild' : pot_bld})
218 # utility function, not a builder
221 def i18n (buildenv, sources, installenv):
222 domain = buildenv['PACKAGE']
223 potfile = buildenv['POTFILE']
225 installenv.Alias ('potupdate', buildenv.PotBuild (potfile, sources))
227 p_oze = [ os.path.basename (po) for po in glob.glob ('po/*.po') ]
228 languages = [ po.replace ('.po', '') for po in p_oze ]
230 for po_file in p_oze:
231 buildenv.PoBuild(po_file, ['po/'+po_file, potfile])
232 mo_file = po_file.replace (".po", ".mo")
233 installenv.Alias ('install', buildenv.MoBuild (mo_file, po_file))
235 for lang in languages:
236 modir = (os.path.join (install_prefix, 'share/locale/' + lang + '/LC_MESSAGES/'))
237 moname = domain + '.mo'
238 installenv.Alias('install', installenv.InstallAs (os.path.join (modir, moname), lang + '.mo'))
241 def fetch_svn_revision (path):
245 cmd += " | awk '/^Revision:/ { print $2}'"
246 return commands.getoutput (cmd)
248 def create_stored_revision (target = None, source = None, env = None):
249 if os.path.exists('.svn'):
250 rev = fetch_svn_revision ('.');
252 text = "#ifndef __ardour_svn_revision_h__\n"
253 text += "#define __ardour_svn_revision_h__\n"
254 text += "static const char* ardour_svn_revision = \"" + rev + "\";\n";
256 print '============> writing svn revision info to svn_revision.h\n'
257 o = file ('svn_revision.h', 'w')
261 print "Could not open svn_revision.h for writing\n"
264 print "You cannot use \"scons revision\" on without using a checked out"
265 print "copy of the Ardour source code repository"
269 # A generic builder for version.cc files
271 # note: requires that DOMAIN, MAJOR, MINOR, MICRO are set in the construction environment
272 # note: assumes one source files, the header that declares the version variables
275 def version_builder (target, source, env):
277 text = "int " + env['DOMAIN'] + "_major_version = " + str (env['MAJOR']) + ";\n"
278 text += "int " + env['DOMAIN'] + "_minor_version = " + str (env['MINOR']) + ";\n"
279 text += "int " + env['DOMAIN'] + "_micro_version = " + str (env['MICRO']) + ";\n"
282 o = file (target[0].get_path(), 'w')
286 print "Could not open", target[0].get_path(), " for writing\n"
289 text = "#ifndef __" + env['DOMAIN'] + "_version_h__\n"
290 text += "#define __" + env['DOMAIN'] + "_version_h__\n"
291 text += "extern const char* " + env['DOMAIN'] + "_revision;\n"
292 text += "extern int " + env['DOMAIN'] + "_major_version;\n"
293 text += "extern int " + env['DOMAIN'] + "_minor_version;\n"
294 text += "extern int " + env['DOMAIN'] + "_micro_version;\n"
295 text += "#endif /* __" + env['DOMAIN'] + "_version_h__ */\n"
298 o = file (target[1].get_path(), 'w')
302 print "Could not open", target[1].get_path(), " for writing\n"
307 version_bld = Builder (action = version_builder)
308 env.Append (BUILDERS = {'VersionBuild' : version_bld})
311 # a builder that makes a hard link from the 'source' executable to a name with
312 # a "build ID" based on the most recent CVS activity that might be reasonably
313 # related to version activity. this relies on the idea that the SConscript
314 # file that builds the executable is updated with new version info and committed
315 # to the source code repository whenever things change.
318 def versioned_builder(target,source,env):
319 w, r = os.popen2( "LANG= svn info | awk '/^Revision:/ { print $2}'")
321 last_revision = r.readline().strip()
324 if last_revision == "":
325 print "No SVN info found - versioned executable cannot be built"
328 print "The current build ID is " + last_revision
330 tagged_executable = source[0].get_path() + '-' + last_revision
332 if os.path.exists (tagged_executable):
333 print "Replacing existing executable with the same build tag."
334 os.unlink (tagged_executable)
336 return os.link (source[0].get_path(), tagged_executable)
338 verbuild = Builder (action = versioned_builder)
339 env.Append (BUILDERS = {'VersionedExecutable' : verbuild})
342 # source tar file builder
345 def distcopy (target, source, env):
346 treedir = str (target[0])
350 except OSError, (errnum, strerror):
351 if errnum != errno.EEXIST:
352 print 'mkdir ', treedir, ':', strerror
356 # we don't know what characters might be in the file names
357 # so quote them all before passing them to the shell
359 all_files = ([ str(s) for s in source ])
360 cmd += " ".join ([ "'%s'" % quoted for quoted in all_files])
361 cmd += ' | (cd ' + treedir + ' && tar xf -)'
365 def tarballer (target, source, env):
366 cmd = 'tar -jcf ' + str (target[0]) + ' ' + str(source[0]) + " --exclude '*~'"
367 print 'running ', cmd, ' ... '
371 dist_bld = Builder (action = distcopy,
372 target_factory = SCons.Node.FS.default_fs.Entry,
373 source_factory = SCons.Node.FS.default_fs.Entry,
376 tarball_bld = Builder (action = tarballer,
377 target_factory = SCons.Node.FS.default_fs.Entry,
378 source_factory = SCons.Node.FS.default_fs.Entry)
380 env.Append (BUILDERS = {'Distribute' : dist_bld})
381 env.Append (BUILDERS = {'Tarball' : tarball_bld})
384 # Make sure they know what they are doing
388 if os.path.isfile('.personal_use_only'):
389 print "Enabling VST support. Note that distributing a VST-enabled ardour\nis a violation of several different licences.\nBuild with VST=false if you intend to distribute ardour to others."
391 sys.stdout.write ("Are you building Ardour for personal use (rather than distribution to others)? [no]: ")
392 answer = sys.stdin.readline ()
393 answer = answer.rstrip().strip()
394 if answer == "yes" or answer == "y":
395 fh = open('.personal_use_only', 'w')
397 print "OK, VST support will be enabled"
399 print 'You cannot build Ardour with VST support for distribution to others.\nIt is a violation of several different licenses. Build with VST=false.'
402 if os.path.isfile('.personal_use_only'):
403 os.remove('.personal_use_only')
410 def pushEnvironment(context):
411 if os.environ.has_key('PATH'):
412 context.Append(PATH = os.environ['PATH'])
414 if os.environ.has_key('PKG_CONFIG_PATH'):
415 context.Append(PKG_CONFIG_PATH = os.environ['PKG_CONFIG_PATH'])
417 if os.environ.has_key('CC'):
418 context['CC'] = os.environ['CC']
420 if os.environ.has_key('CXX'):
421 context['CXX'] = os.environ['CXX']
423 if os.environ.has_key('DISTCC_HOSTS'):
424 context['ENV']['DISTCC_HOSTS'] = os.environ['DISTCC_HOSTS']
425 context['ENV']['HOME'] = os.environ['HOME']
427 pushEnvironment (env)
429 #######################
430 # Dependency Checking #
431 #######################
435 'glib-2.0' : '2.10.1',
436 'gthread-2.0' : '2.10.1',
437 'gtk+-2.0' : '2.8.1',
438 'libxml-2.0' : '2.6.0',
439 'samplerate' : '0.1.0',
443 'libgnomecanvas-2.0' : '2.0'
446 def DependenciesRequiredMessage():
447 print 'You do not have the necessary dependencies required to build ardour'
448 print 'Please consult http://ardour.org/building for more information'
450 def CheckPKGConfig(context, version):
451 context.Message( 'Checking for pkg-config version >= %s... ' %version )
452 ret = context.TryAction('pkg-config --atleast-pkgconfig-version=%s' % version)[0]
453 context.Result( ret )
456 def CheckPKGVersion(context, name, version):
457 context.Message( 'Checking for %s... ' % name )
458 ret = context.TryAction('pkg-config --atleast-version=%s %s' %(version,name) )[0]
459 context.Result( ret )
462 def CheckPKGExists(context, name):
463 context.Message ('Checking for %s...' % name)
464 ret = context.TryAction('pkg-config --exists %s' % name)[0]
468 conf = Configure(env, custom_tests = { 'CheckPKGConfig' : CheckPKGConfig,
469 'CheckPKGVersion' : CheckPKGVersion })
471 # I think a more recent version is needed on win32
472 min_pkg_config_version = '0.8.0'
474 if not conf.CheckPKGConfig(min_pkg_config_version):
475 print 'pkg-config >= %s not found.' % min_pkg_config_version
478 for pkg, version in deps.iteritems():
479 if not conf.CheckPKGVersion( pkg, version ):
480 print '%s >= %s not found.' %(pkg, version)
481 DependenciesRequiredMessage()
486 # ----------------------------------------------------------------------
487 # Construction environment setup
488 # ----------------------------------------------------------------------
492 libraries['core'] = LibraryInfo (CCFLAGS = '-Ilibs')
494 #libraries['sndfile'] = LibraryInfo()
495 #libraries['sndfile'].ParseConfig('pkg-config --cflags --libs sndfile')
497 libraries['lrdf'] = LibraryInfo()
498 libraries['lrdf'].ParseConfig('pkg-config --cflags --libs lrdf')
500 libraries['raptor'] = LibraryInfo()
501 libraries['raptor'].ParseConfig('pkg-config --cflags --libs raptor')
503 libraries['samplerate'] = LibraryInfo()
504 libraries['samplerate'].ParseConfig('pkg-config --cflags --libs samplerate')
506 conf = env.Configure (custom_tests = { 'CheckPKGExists' : CheckPKGExists } )
508 if conf.CheckPKGExists ('fftw3f'):
509 libraries['fftw3f'] = LibraryInfo()
510 libraries['fftw3f'].ParseConfig('pkg-config --cflags --libs fftw3f')
512 if conf.CheckPKGExists ('fftw3'):
513 libraries['fftw3'] = LibraryInfo()
514 libraries['fftw3'].ParseConfig('pkg-config --cflags --libs fftw3')
518 if env['FFT_ANALYSIS']:
520 # Check for fftw3 header as well as the library
523 conf = Configure(libraries['fftw3'])
525 if conf.CheckHeader ('fftw3.h') == False:
526 print ('FFT Analysis cannot be compiled without the FFTW3 headers, which do not seem to be installed')
530 libraries['jack'] = LibraryInfo()
531 libraries['jack'].ParseConfig('pkg-config --cflags --libs jack')
533 libraries['xml'] = LibraryInfo()
534 libraries['xml'].ParseConfig('pkg-config --cflags --libs libxml-2.0')
536 libraries['xslt'] = LibraryInfo()
537 libraries['xslt'].ParseConfig('pkg-config --cflags --libs libxslt')
539 libraries['glib2'] = LibraryInfo()
540 libraries['glib2'].ParseConfig ('pkg-config --cflags --libs glib-2.0')
541 libraries['glib2'].ParseConfig ('pkg-config --cflags --libs gobject-2.0')
542 libraries['glib2'].ParseConfig ('pkg-config --cflags --libs gmodule-2.0')
543 libraries['glib2'].ParseConfig ('pkg-config --cflags --libs gthread-2.0')
545 libraries['gtk2'] = LibraryInfo()
546 libraries['gtk2'].ParseConfig ('pkg-config --cflags --libs gtk+-2.0')
548 libraries['pango'] = LibraryInfo()
549 libraries['pango'].ParseConfig ('pkg-config --cflags --libs pango')
551 libraries['libgnomecanvas2'] = LibraryInfo()
552 libraries['libgnomecanvas2'].ParseConfig ('pkg-config --cflags --libs libgnomecanvas-2.0')
554 #libraries['flowcanvas'] = LibraryInfo(LIBS='flowcanvas', LIBPATH='#/libs/flowcanvas', CPPPATH='#libs/flowcanvas')
556 # The Ardour Control Protocol Library
558 libraries['ardour_cp'] = LibraryInfo (LIBS='ardour_cp', LIBPATH='#libs/surfaces/control_protocol',
559 CPPPATH='#libs/surfaces/control_protocol')
561 # The Ardour backend/engine
563 libraries['ardour'] = LibraryInfo (LIBS='ardour', LIBPATH='#libs/ardour', CPPPATH='#libs/ardour')
564 libraries['midi++2'] = LibraryInfo (LIBS='midi++', LIBPATH='#libs/midi++2', CPPPATH='#libs/midi++2')
565 libraries['pbd'] = LibraryInfo (LIBS='pbd', LIBPATH='#libs/pbd', CPPPATH='#libs/pbd')
566 libraries['gtkmm2ext'] = LibraryInfo (LIBS='gtkmm2ext', LIBPATH='#libs/gtkmm2ext', CPPPATH='#libs/gtkmm2ext')
569 # SCons should really do this for us
571 conf = env.Configure ()
573 have_cxx = conf.TryAction (Action (str(env['CXX']) + ' --version'))
575 print "This system has no functional C++ compiler. You cannot build Ardour from source without one."
578 print "Congratulations, you have a functioning C++ compiler."
584 # Compiler flags and other system-dependent stuff
588 if env['GPROFILE'] == 1:
589 debug_flags = [ '-g', '-pg' ]
591 debug_flags = [ '-g' ]
593 # guess at the platform, used to define compiler flags
595 config_guess = os.popen("tools/config.guess").read()[:-1]
601 config = config_guess.split ("-")
603 print "system triple: " + config_guess
606 if env['DIST_TARGET'] == 'auto':
607 if config[config_arch] == 'apple':
608 # The [.] matches to the dot after the major version, "." would match any character
609 if re.search ("darwin[0-7][.]", config[config_kernel]) != None:
610 env['DIST_TARGET'] = 'panther'
612 env['DIST_TARGET'] = 'tiger'
614 if re.search ("x86_64", config[config_cpu]) != None:
615 env['DIST_TARGET'] = 'x86_64'
616 elif re.search("i[0-5]86", config[config_cpu]) != None:
617 env['DIST_TARGET'] = 'i386'
618 elif re.search("powerpc", config[config_cpu]) != None:
619 env['DIST_TARGET'] = 'powerpc'
621 env['DIST_TARGET'] = 'i686'
622 print "\n*******************************"
623 print "detected DIST_TARGET = " + env['DIST_TARGET']
624 print "*******************************\n"
627 if config[config_cpu] == 'powerpc' and env['DIST_TARGET'] != 'none':
629 # Apple/PowerPC optimization options
631 # -mcpu=7450 does not reliably work with gcc 3.*
633 if env['DIST_TARGET'] == 'panther' or env['DIST_TARGET'] == 'tiger':
634 if config[config_arch] == 'apple':
635 ## opt_flags.extend ([ "-mcpu=7450", "-faltivec"])
636 # to support g3s but still have some optimization for above
637 opt_flags.extend ([ "-mcpu=G3", "-mtune=7450"])
639 opt_flags.extend ([ "-mcpu=7400", "-maltivec", "-mabi=altivec"])
641 opt_flags.extend([ "-mcpu=750", "-mmultiple" ])
642 opt_flags.extend (["-mhard-float", "-mpowerpc-gfxopt"])
643 opt_flags.extend (["-Os"])
645 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':
647 build_host_supports_sse = 0
649 debug_flags.append ("-DARCH_X86")
650 opt_flags.append ("-DARCH_X86")
652 if config[config_kernel] == 'linux' :
654 if env['DIST_TARGET'] != 'i386':
656 flag_line = os.popen ("cat /proc/cpuinfo | grep '^flags'").read()[:-1]
657 x86_flags = flag_line.split (": ")[1:][0].split ()
659 if "mmx" in x86_flags:
660 opt_flags.append ("-mmmx")
661 if "sse" in x86_flags:
662 build_host_supports_sse = 1
663 if "3dnow" in x86_flags:
664 opt_flags.append ("-m3dnow")
666 if config[config_cpu] == "i586":
667 opt_flags.append ("-march=i586")
668 elif config[config_cpu] == "i686":
669 opt_flags.append ("-march=i686")
671 if ((env['DIST_TARGET'] == 'i686') or (env['DIST_TARGET'] == 'x86_64')) and build_host_supports_sse:
672 opt_flags.extend (["-msse", "-mfpmath=sse", "-DUSE_XMMINTRIN"])
673 debug_flags.extend (["-msse", "-mfpmath=sse", "-DUSE_XMMINTRIN"])
674 # end of processor-specific section
676 # optimization section
677 if env['FPU_OPTIMIZATION']:
678 if env['DIST_TARGET'] == 'tiger':
679 opt_flags.append ("-DBUILD_VECLIB_OPTIMIZATIONS")
680 debug_flags.append ("-DBUILD_VECLIB_OPTIMIZATIONS")
681 libraries['core'].Append(LINKFLAGS= '-framework Accelerate')
682 elif env['DIST_TARGET'] == 'i686' or env['DIST_TARGET'] == 'x86_64':
683 opt_flags.append ("-DBUILD_SSE_OPTIMIZATIONS")
684 debug_flags.append ("-DBUILD_SSE_OPTIMIZATIONS")
685 if env['DIST_TARGET'] == 'x86_64':
686 opt_flags.append ("-DUSE_X86_64_ASM")
687 debug_flags.append ("-DUSE_X86_64_ASM")
688 if build_host_supports_sse != 1:
689 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)"
690 # end optimization section
692 # handle x86/x86_64 libdir properly
694 if env['DIST_TARGET'] == 'x86_64':
695 env['LIBDIR']='lib64'
700 # save off guessed arch element in an env
702 env.Append(CONFIG_ARCH=config[config_arch])
706 # ARCH="..." overrides all
709 if env['ARCH'] != '':
710 opt_flags = env['ARCH'].split()
713 # prepend boiler plate optimization flags
718 "-fomit-frame-pointer",
724 if env['DEBUG'] == 1:
725 env.Append(CCFLAGS=" ".join (debug_flags))
726 env.Append(LINKFLAGS=" ".join (debug_flags))
728 env.Append(CCFLAGS=" ".join (opt_flags))
729 env.Append(LINKFLAGS=" ".join (opt_flags))
731 if env['UNIVERSAL'] == 1:
732 env.Append(CCFLAGS="-arch i386 -arch ppc")
733 env.Append(LINKFLAGS="-arch i386 -arch ppc")
739 env.Append(CCFLAGS="-Wall")
740 env.Append(CXXFLAGS="-Woverloaded-virtual")
742 if env['EXTRA_WARN']:
743 env.Append(CCFLAGS="-Wextra -pedantic -ansi")
744 env.Append(CXXFLAGS="-ansi")
745 # env.Append(CFLAGS="-iso")
748 env.Append(CCFLAGS="-DHAVE_LIBLO")
752 # fix scons nitpickiness on APPLE
756 def prep_libcheck(topenv, libinfo):
757 if topenv['DIST_TARGET'] == 'panther' or topenv['DIST_TARGET'] == 'tiger':
759 # rationale: GTK-Quartz uses jhbuild and installs to /opt/gtk by default.
760 # All libraries needed should be built against this location
762 libinfo.Append(CPPPATH="/opt/gtk/include", LIBPATH="/opt/gtk/lib")
763 libinfo.Append(CXXFLAGS="-I/opt/gtk/include", LINKFLAGS="-L/opt/gtk/lib")
764 libinfo.Append(CPPPATH="/opt/local/include", LIBPATH="/opt/local/lib")
765 libinfo.Append(CXXFLAGS="-I/opt/local/include", LINKFLAGS="-L/opt/local/lib")
767 prep_libcheck(env, env)
770 # check for VAMP and rubberband (currently optional)
773 libraries['vamp'] = LibraryInfo()
775 env['RUBBERBAND'] = False
777 #conf = env.Configure (custom_tests = { 'CheckPKGExists' : CheckPKGExists } )
779 #if conf.CheckPKGExists('vamp-sdk'):
781 # libraries['vamp'].ParseConfig('pkg-config --cflags --libs vamp-sdk')
785 #libraries['vamp'] = conf.Finish ()
788 # if os.path.exists ('libs/rubberband/src'):
789 # conf = Configure (libraries['vamp'])
790 # if conf.CheckHeader ('fftw3.h'):
791 # env['RUBBERBAND'] = True
792 # libraries['rubberband'] = LibraryInfo (LIBS='rubberband',
793 # LIBPATH='#libs/rubberband',
794 # CPPPATH='#libs/rubberband',
795 # CCFLAGS='-DUSE_RUBBERBAND')
796 # libraries['vamp'] = conf.Finish ()
801 libraries['usb'] = LibraryInfo ()
802 prep_libcheck(env, libraries['usb'])
804 conf = Configure (libraries['usb'])
805 if conf.CheckLib ('usb', 'usb_interrupt_write'):
810 # check for linux/input.h while we're at it for powermate
811 if conf.CheckHeader('linux/input.h'):
812 have_linux_input = True
814 have_linux_input = False
816 libraries['usb'] = conf.Finish ()
821 libraries['flac'] = LibraryInfo ()
822 prep_libcheck(env, libraries['flac'])
823 libraries['flac'].Append(CPPPATH="/usr/local/include", LIBPATH="/usr/local/lib")
826 # june 1st 2007: look for a function that is in FLAC 1.1.2 and not in later versions
827 # since the version of libsndfile we have internally does not support
828 # the new API that libFLAC has adopted
831 conf = Configure (libraries['flac'])
832 if conf.CheckLib ('FLAC', 'FLAC__seekable_stream_decoder_init', language='CXX'):
833 conf.env.Append(CCFLAGS='-DHAVE_FLAC')
838 libraries['flac'] = conf.Finish ()
840 # or if that fails...
841 #libraries['flac'] = LibraryInfo (LIBS='FLAC')
843 # boost (we don't link against boost, just use some header files)
845 libraries['boost'] = LibraryInfo ()
846 prep_libcheck(env, libraries['boost'])
847 libraries['boost'].Append(CPPPATH="/usr/local/include", LIBPATH="/usr/local/lib")
848 conf = Configure (libraries['boost'])
849 if conf.CheckHeader ('boost/shared_ptr.hpp', language='CXX') == False:
850 print "Boost header files do not appear to be installed."
853 libraries['boost'] = conf.Finish ()
859 libraries['lo'] = LibraryInfo ()
860 prep_libcheck(env, libraries['lo'])
862 conf = Configure (libraries['lo'])
863 if conf.CheckLib ('lo', 'lo_server_new') == False:
864 print "liblo does not appear to be installed."
867 libraries['lo'] = conf.Finish ()
872 libraries['dmalloc'] = LibraryInfo ()
873 prep_libcheck(env, libraries['dmalloc'])
876 # look for the threaded version
879 conf = Configure (libraries['dmalloc'])
880 if conf.CheckLib ('dmallocth', 'dmalloc_shutdown'):
881 have_libdmalloc = True
883 have_libdmalloc = False
885 libraries['dmalloc'] = conf.Finish ()
888 # Audio/MIDI library (needed for MIDI, since audio is all handled via JACK)
891 conf = Configure(env)
893 # ALSA, for engine dialog
894 libraries['asound'] = LibraryInfo ()
896 if conf.CheckCHeader('alsa/asoundlib.h'):
897 libraries['asound'] = LibraryInfo (LIBS='asound')
899 if conf.CheckCHeader('jack/midiport.h'):
900 libraries['sysmidi'] = LibraryInfo (LIBS='jack')
901 env['SYSMIDI'] = 'JACK MIDI'
902 subst_dict['%MIDITAG%'] = "control"
903 subst_dict['%MIDITYPE%'] = "jack"
904 print "Using JACK MIDI"
905 elif conf.CheckCHeader('alsa/asoundlib.h'):
906 libraries['sysmidi'] = LibraryInfo (LIBS='asound')
907 env['SYSMIDI'] = 'ALSA Sequencer'
908 subst_dict['%MIDITAG%'] = "seq"
909 subst_dict['%MIDITYPE%'] = "alsa/sequencer"
910 print "Using ALSA MIDI"
911 elif conf.CheckCHeader('/System/Library/Frameworks/CoreMIDI.framework/Headers/CoreMIDI.h'):
912 # this line is needed because scons can't handle -framework in ParseConfig() yet.
914 # We need Carbon as well as the rest
915 libraries['sysmidi'] = LibraryInfo (
916 LINKFLAGS = ' -framework CoreMIDI -framework CoreFoundation -framework CoreAudio -framework CoreServices -framework AudioUnit -framework AudioToolbox -framework Carbon -bind_at_load' )
918 libraries['sysmidi'] = LibraryInfo (
919 LINKFLAGS = ' -framework CoreMIDI -framework CoreFoundation -framework CoreAudio -framework CoreServices -framework AudioUnit -framework AudioToolbox -bind_at_load' )
920 env['SYSMIDI'] = 'CoreMIDI'
921 subst_dict['%MIDITAG%'] = "ardour"
922 subst_dict['%MIDITYPE%'] = "coremidi"
924 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."
933 'sigc++-2.0' : '2.0',
935 'libgnomecanvasmm-2.6' : '2.12.0'
938 conf = Configure(env, custom_tests = { 'CheckPKGConfig' : CheckPKGConfig,
939 'CheckPKGVersion' : CheckPKGVersion })
941 for pkg, version in syslibdeps.iteritems():
942 if not conf.CheckPKGVersion( pkg, version ):
943 print '%s >= %s not found.' %(pkg, version)
944 DependenciesRequiredMessage()
949 libraries['sigc2'] = LibraryInfo()
950 libraries['sigc2'].ParseConfig('pkg-config --cflags --libs sigc++-2.0')
951 libraries['glibmm2'] = LibraryInfo()
952 libraries['glibmm2'].ParseConfig('pkg-config --cflags --libs glibmm-2.4')
953 libraries['cairo'] = LibraryInfo()
954 libraries['cairo'].ParseConfig('pkg-config --cflags --libs cairo')
955 libraries['cairomm'] = LibraryInfo()
956 libraries['cairomm'].ParseConfig('pkg-config --cflags --libs cairomm-1.0')
957 libraries['gdkmm2'] = LibraryInfo()
958 libraries['gdkmm2'].ParseConfig ('pkg-config --cflags --libs gdkmm-2.4')
959 libraries['gtkmm2'] = LibraryInfo()
960 libraries['gtkmm2'].ParseConfig ('pkg-config --cflags --libs gtkmm-2.4')
961 libraries['atkmm'] = LibraryInfo()
962 libraries['atkmm'].ParseConfig ('pkg-config --cflags --libs atkmm-1.6')
963 libraries['pangomm'] = LibraryInfo()
964 libraries['pangomm'].ParseConfig ('pkg-config --cflags --libs pangomm-1.4')
965 libraries['libgnomecanvasmm'] = LibraryInfo()
966 libraries['libgnomecanvasmm'].ParseConfig ('pkg-config --cflags --libs libgnomecanvasmm-2.6')
969 # cannot use system one for the time being
972 libraries['sndfile-ardour'] = LibraryInfo(LIBS='libsndfile-ardour',
973 LIBPATH='#libs/libsndfile',
974 CPPPATH=['#libs/libsndfile/src'])
976 # libraries['libglademm'] = LibraryInfo()
977 # libraries['libglademm'].ParseConfig ('pkg-config --cflags --libs libglademm-2.4')
979 # libraries['flowcanvas'] = LibraryInfo(LIBS='flowcanvas', LIBPATH='#/libs/flowcanvas', CPPPATH='#libs/flowcanvas')
980 libraries['soundtouch'] = LibraryInfo()
981 #libraries['soundtouch'].ParseConfig ('pkg-config --cflags --libs soundtouch-1.0')
982 # Comment the previous line and uncomment this for Debian:
983 libraries['soundtouch'].ParseConfig ('pkg-config --cflags --libs libSoundTouch')
985 libraries['appleutility'] = LibraryInfo(LIBS='libappleutility',
986 LIBPATH='#libs/appleutility',
987 CPPPATH='#libs/appleutility')
998 # these are unconditionally included but have
999 # tests internally to avoid compilation etc
1003 # this is unconditionally included but has
1004 # tests internally to avoid compilation etc
1005 # if COREAUDIO is not set
1010 # 'libs/flowcanvas',
1017 libraries['cairo'] = LibraryInfo()
1018 libraries['cairo'].ParseConfig('pkg-config --cflags --libs cairo')
1020 libraries['gtk2-unix-print'] = LibraryInfo()
1021 libraries['gtk2-unix-print'].ParseConfig('pkg-config --cflags --libs gtk+-unix-print-2.0')
1023 libraries['sigc2'] = LibraryInfo(LIBS='sigc++2',
1024 LIBPATH='#libs/sigc++2',
1025 CPPPATH='#libs/sigc++2')
1026 libraries['glibmm2'] = LibraryInfo(LIBS='glibmm2',
1027 LIBPATH='#libs/glibmm2',
1028 CPPPATH='#libs/glibmm2/glib')
1029 libraries['pangomm'] = LibraryInfo(LIBS='pangomm',
1030 LIBPATH='#libs/gtkmm2/pango',
1031 CPPPATH='#libs/gtkmm2/pango')
1032 libraries['atkmm'] = LibraryInfo(LIBS='atkmm',
1033 LIBPATH='#libs/gtkmm2/atk',
1034 CPPPATH='#libs/gtkmm2/atk')
1035 libraries['cairomm'] = LibraryInfo(LIBS='cairomm',
1036 LIBPATH='#libs/cairomm',
1037 CPPPATH='#libs/cairomm')
1038 libraries['gdkmm2'] = LibraryInfo(LIBS='gdkmm2',
1039 LIBPATH='#libs/gtkmm2/gdk',
1040 CPPPATH='#libs/gtkmm2/gdk')
1041 libraries['gtkmm2'] = LibraryInfo(LIBS='gtkmm2',
1042 LIBPATH="#libs/gtkmm2/gtk",
1043 CPPPATH='#libs/gtkmm2/gtk/')
1044 libraries['libgnomecanvasmm'] = LibraryInfo(LIBS='libgnomecanvasmm',
1045 LIBPATH='#libs/libgnomecanvasmm',
1046 CPPPATH='#libs/libgnomecanvasmm')
1048 libraries['soundtouch'] = LibraryInfo(LIBS='soundtouch',
1049 LIBPATH='#libs/soundtouch',
1050 CPPPATH=['#libs', '#libs/soundtouch'])
1051 libraries['sndfile-ardour'] = LibraryInfo(LIBS='libsndfile-ardour',
1052 LIBPATH='#libs/libsndfile',
1053 CPPPATH=['#libs/libsndfile', '#libs/libsndfile/src'])
1054 # libraries['libglademm'] = LibraryInfo(LIBS='libglademm',
1055 # LIBPATH='#libs/libglademm',
1056 # CPPPATH='#libs/libglademm')
1057 libraries['appleutility'] = LibraryInfo(LIBS='libappleutility',
1058 LIBPATH='#libs/appleutility',
1059 CPPPATH='#libs/appleutility')
1071 # these are unconditionally included but have
1072 # tests internally to avoid compilation etc
1076 # this is unconditionally included but has
1077 # tests internally to avoid compilation etc
1078 # if COREAUDIO is not set
1084 'libs/gtkmm2/pango',
1088 'libs/libgnomecanvasmm',
1096 # * always build the LGPL control protocol lib, since we link against it from libardour
1097 # * ditto for generic MIDI
1098 # * tranzport checks whether it should build internally, but we need here so that
1099 # its included in the tarball
1102 surface_subdirs = [ 'libs/surfaces/control_protocol',
1103 'libs/surfaces/generic_midi',
1104 'libs/surfaces/tranzport',
1105 'libs/surfaces/mackie',
1106 'libs/surfaces/powermate'
1111 env['TRANZPORT'] = 1
1113 env['TRANZPORT'] = 0
1114 print 'Disabled building Tranzport code because libusb could not be found'
1116 if have_linux_input:
1117 env['POWERMATE'] = 1
1119 env['POWERMATE'] = 0
1120 print 'Disabled building Powermate code because linux/input.h could not be found'
1122 if os.access ('libs/surfaces/sony9pin', os.F_OK):
1123 surface_subdirs += [ 'libs/surfaces/sony9pin' ]
1125 env['POWERMATE'] = 0
1126 env['TRANZPORT'] = 0
1129 # timestretch libraries
1132 timefx_subdirs = ['libs/soundtouch']
1133 #if env['RUBBERBAND']:
1134 # timefx_subdirs += ['libs/rubberband']
1136 opts.Save('scache.conf', env)
1137 Help(opts.GenerateHelpText(env))
1139 final_prefix = '$PREFIX'
1142 install_prefix = '$DESTDIR/$PREFIX'
1144 install_prefix = env['PREFIX']
1146 subst_dict['%INSTALL_PREFIX%'] = install_prefix;
1147 subst_dict['%FINAL_PREFIX%'] = final_prefix;
1148 subst_dict['%PREFIX%'] = final_prefix;
1150 if env['PREFIX'] == '/usr':
1151 final_config_prefix = '/etc'
1153 final_config_prefix = env['PREFIX'] + '/etc'
1155 config_prefix = '$DESTDIR' + final_config_prefix
1158 # everybody needs this
1161 env.Merge ([ libraries['core'] ])
1168 conf = Configure (env)
1170 nls_error = 'This system is not configured for internationalized applications. An english-only version will be built:'
1171 print 'Checking for internationalization support ...'
1172 have_gettext = conf.TryAction(Action('xgettext --version'))
1173 if have_gettext[0] != 1:
1174 nls_error += ' No xgettext command.'
1177 print "Found xgettext"
1179 have_msgmerge = conf.TryAction(Action('msgmerge --version'))
1180 if have_msgmerge[0] != 1:
1181 nls_error += ' No msgmerge command.'
1184 print "Found msgmerge"
1186 if not conf.CheckCHeader('libintl.h'):
1187 nls_error += ' No libintl.h.'
1193 print "International version will be built."
1197 env.Append(CCFLAGS="-DENABLE_NLS")
1199 Export('env install_prefix final_prefix config_prefix final_config_prefix libraries i18n ardour_version subst_dict use_flac')
1202 # the configuration file may be system dependent
1205 conf = env.Configure ()
1207 if conf.CheckCHeader('/System/Library/Frameworks/CoreAudio.framework/Versions/A/Headers/CoreAudio.h'):
1208 subst_dict['%JACK_INPUT%'] = "coreaudio:Built-in Audio:in"
1209 subst_dict['%JACK_OUTPUT%'] = "coreaudio:Built-in Audio:out"
1211 subst_dict['%JACK_INPUT%'] = "alsa_pcm:playback_"
1212 subst_dict['%JACK_OUTPUT%'] = "alsa_pcm:capture_"
1214 # posix_memalign available
1215 if not conf.CheckFunc('posix_memalign'):
1216 print 'Did not find posix_memalign(), using malloc'
1217 env.Append(CCFLAGS='-DNO_POSIX_MEMALIGN')
1222 # generate the per-user and system rc files from the same source
1224 sysrcbuild = env.SubstInFile ('ardour_system.rc','ardour.rc.in', SUBST_DICT = subst_dict)
1226 # add to the substitution dictionary
1228 subst_dict['%VERSION%'] = ardour_version[0:3]
1229 subst_dict['%EXTRA_VERSION%'] = ardour_version[3:]
1230 subst_dict['%REVISION_STRING%'] = ''
1231 if os.path.exists('.svn'):
1232 subst_dict['%REVISION_STRING%'] = '.' + fetch_svn_revision ('.') + 'svn'
1234 # specbuild = env.SubstInFile ('ardour.spec','ardour.spec.in', SUBST_DICT = subst_dict)
1236 the_revision = env.Command ('frobnicatory_decoy', [], create_stored_revision)
1237 remove_ardour = env.Command ('frobnicatory_decoy2', [],
1238 [ Delete ('$PREFIX/etc/ardour2'),
1239 Delete ('$PREFIX/lib/ardour2'),
1240 Delete ('$PREFIX/bin/ardour2')])
1242 env.Alias('revision', the_revision)
1243 env.Alias('install', env.Install(os.path.join(config_prefix, 'ardour2'), 'ardour_system.rc'))
1244 env.Alias('uninstall', remove_ardour)
1246 Default (sysrcbuild)
1250 Precious (env['DISTTREE'])
1252 env.Distribute (env['DISTTREE'],
1253 [ 'SConstruct', 'svn_revision.h',
1254 'COPYING', 'PACKAGER_README', 'README',
1256 'tools/config.guess',
1257 'icons/icon/ardour_icon_mac_mask.png',
1258 'icons/icon/ardour_icon_mac.png',
1259 'icons/icon/ardour_icon_tango_16px_blue.png',
1260 'icons/icon/ardour_icon_tango_16px_red.png',
1261 'icons/icon/ardour_icon_tango_22px_blue.png',
1262 'icons/icon/ardour_icon_tango_22px_red.png',
1263 'icons/icon/ardour_icon_tango_32px_blue.png',
1264 'icons/icon/ardour_icon_tango_32px_red.png',
1265 'icons/icon/ardour_icon_tango_48px_blue.png',
1266 'icons/icon/ardour_icon_tango_48px_red.png'
1268 glob.glob ('DOCUMENTATION/AUTHORS*') +
1269 glob.glob ('DOCUMENTATION/CONTRIBUTORS*') +
1270 glob.glob ('DOCUMENTATION/TRANSLATORS*') +
1271 glob.glob ('DOCUMENTATION/BUILD*') +
1272 glob.glob ('DOCUMENTATION/FAQ*') +
1273 glob.glob ('DOCUMENTATION/README*')
1276 srcdist = env.Tarball(env['TARBALL'], [ env['DISTTREE'], the_revision ])
1277 env.Alias ('srctar', srcdist)
1280 # don't leave the distree around
1283 env.AddPreAction (env['DISTTREE'], Action ('rm -rf ' + str (File (env['DISTTREE']))))
1284 env.AddPostAction (srcdist, Action ('rm -rf ' + str (File (env['DISTTREE']))))
1290 for subdir in coredirs:
1291 SConscript (subdir + '/SConscript')
1293 for sublistdir in [ subdirs, timefx_subdirs, gtk_subdirs, surface_subdirs ]:
1294 for subdir in sublistdir:
1295 SConscript (subdir + '/SConscript')
1298 env.Clean ('scrub', [ 'scache.conf', '.sconf_temp', '.sconsign.dblite', 'config.log'])