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('OLDFONTS', 'Old school font sizes', 0),
35 BoolOption('DEBUG', 'Set to build with debugging information and no optimizations', 0),
36 PathOption('DESTDIR', 'Set the intermediate install "prefix"', '/'),
37 EnumOption('DIST_TARGET', 'Build target for cross compiling packagers', 'auto', allowed_values=('auto', 'i386', 'i686', 'x86_64', 'powerpc', 'tiger', 'panther', 'leopard', 'none' ), ignorecase=2),
38 BoolOption('DMALLOC', 'Compile and link using the dmalloc library', 0),
39 BoolOption('EXTRA_WARN', 'Compile with -Wextra, -ansi, and -pedantic. Might break compilation. For pedants', 0),
40 BoolOption('FFT_ANALYSIS', 'Include FFT analysis window', 0),
41 BoolOption('FPU_OPTIMIZATION', 'Build runtime checked assembler code', 1),
42 BoolOption('LIBLO', 'Compile with support for liblo library', 1),
43 BoolOption('NLS', 'Set to turn on i18n support', 1),
44 PathOption('PREFIX', 'Set the install "prefix"', '/usr/local'),
45 BoolOption('SURFACES', 'Build support for control surfaces', 1),
46 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),
47 BoolOption('UNIVERSAL', 'Compile as universal binary. Requires that external libraries are already universal.', 0),
48 BoolOption('VERSIONED', 'Add revision information to ardour/gtk executable name inside the build directory', 0),
49 BoolOption('VST', 'Compile with support for VST', 0),
50 BoolOption('LV2', 'Compile with support for LV2 (if slv2 is available)', 1),
51 BoolOption('GPROFILE', 'Compile with support for gprofile (Developers only)', 0),
52 BoolOption('TRANZPORT', 'Compile with support for Frontier Designs (if libusb is available)', 1)
55 #----------------------------------------------------------------------
56 # a handy helper that provides a way to merge compile/link information
57 # from multiple different "environments"
58 #----------------------------------------------------------------------
60 class LibraryInfo(Environment):
61 def __init__(self,*args,**kw):
62 Environment.__init__ (self,*args,**kw)
64 def Merge (self,others):
66 self.Append (LIBS = other.get ('LIBS',[]))
67 self.Append (LIBPATH = other.get ('LIBPATH', []))
68 self.Append (CPPPATH = other.get('CPPPATH', []))
69 self.Append (LINKFLAGS = other.get('LINKFLAGS', []))
70 self.Append (CCFLAGS = other.get('CCFLAGS', []))
71 self.Replace(LIBPATH = list(Set(self.get('LIBPATH', []))))
72 self.Replace(CPPPATH = list(Set(self.get('CPPPATH',[]))))
73 #doing LINKFLAGS breaks -framework
74 #doing LIBS break link order dependency
76 def ENV_update(self, src_ENV):
77 for k in src_ENV.keys():
78 if k in self['ENV'].keys() and k in [ 'PATH', 'LD_LIBRARY_PATH',
80 self['ENV'][k]=SCons.Util.AppendPath(self['ENV'][k], src_ENV[k])
82 self['ENV'][k]=src_ENV[k]
84 env = LibraryInfo (options = opts,
86 VERSION = ardour_version,
87 TARBALL='ardour-' + ardour_version + '.tar.bz2',
89 DISTTREE = '#ardour-' + ardour_version,
90 DISTCHECKDIR = '#ardour-' + ardour_version + '/check'
93 env.ENV_update(os.environ)
95 #----------------------------------------------------------------------
97 #----------------------------------------------------------------------
99 # Handy subst-in-file builder
102 def do_subst_in_file(targetfile, sourcefile, dict):
103 """Replace all instances of the keys of dict with their values.
104 For example, if dict is {'%VERSION%': '1.2345', '%BASE%': 'MyProg'},
105 then all instances of %VERSION% in the file will be replaced with 1.2345 etc.
108 f = open(sourcefile, 'rb')
112 raise SCons.Errors.UserError, "Can't read source file %s"%sourcefile
113 for (k,v) in dict.items():
114 contents = re.sub(k, v, contents)
116 f = open(targetfile, 'wb')
120 raise SCons.Errors.UserError, "Can't write target file %s"%targetfile
123 def subst_in_file(target, source, env):
124 if not env.has_key('SUBST_DICT'):
125 raise SCons.Errors.UserError, "SubstInFile requires SUBST_DICT to be set."
126 d = dict(env['SUBST_DICT']) # copy it
127 for (k,v) in d.items():
129 d[k] = env.subst(v())
130 elif SCons.Util.is_String(v):
133 raise SCons.Errors.UserError, "SubstInFile: key %s: %s must be a string or callable"%(k, repr(v))
134 for (t,s) in zip(target, source):
135 return do_subst_in_file(str(t), str(s), d)
137 def subst_in_file_string(target, source, env):
138 """This is what gets printed on the console."""
139 return '\n'.join(['Substituting vars from %s into %s'%(str(s), str(t))
140 for (t,s) in zip(target, source)])
142 def subst_emitter(target, source, env):
143 """Add dependency from substituted SUBST_DICT to target.
144 Returns original target, source tuple unchanged.
146 d = env['SUBST_DICT'].copy() # copy it
147 for (k,v) in d.items():
149 d[k] = env.subst(v())
150 elif SCons.Util.is_String(v):
152 Depends(target, SCons.Node.Python.Value(d))
153 # Depends(target, source) # this doesn't help the install-sapphire-linux.sh problem
154 return target, source
156 subst_action = Action (subst_in_file, subst_in_file_string)
157 env['BUILDERS']['SubstInFile'] = Builder(action=subst_action, emitter=subst_emitter)
160 # internationalization
163 # po_builder: builder function to copy po files to the parent directory while updating them
165 # first source: .po file
166 # second source: .pot file
169 def po_builder(target,source,env):
170 os.spawnvp (os.P_WAIT, 'cp', ['cp', str(source[0]), str(target[0])])
176 print 'Updating ' + str(target[0])
177 return os.spawnvp (os.P_WAIT, 'msgmerge', args)
179 po_bld = Builder (action = po_builder)
180 env.Append(BUILDERS = {'PoBuild' : po_bld})
182 # mo_builder: builder function for (binary) message catalogs (.mo)
184 # first source: .po file
187 def mo_builder(target,source,env):
191 target[0].get_path(),
194 return os.spawnvp (os.P_WAIT, 'msgfmt', args)
196 mo_bld = Builder (action = mo_builder)
197 env.Append(BUILDERS = {'MoBuild' : mo_bld})
199 # pot_builder: builder function for message templates (.pot)
201 # source: list of C/C++ etc. files to extract messages from
204 def pot_builder(target,source,env):
209 '-o', target[0].get_path(),
210 "--default-domain=" + env['PACKAGE'],
211 '--copyright-holder="Paul Davis"' ]
212 args += [ src.get_path() for src in source ]
214 return os.spawnvp (os.P_WAIT, 'xgettext', args)
216 pot_bld = Builder (action = pot_builder)
217 env.Append(BUILDERS = {'PotBuild' : pot_bld})
220 # utility function, not a builder
223 def i18n (buildenv, sources, installenv):
224 domain = buildenv['PACKAGE']
225 potfile = buildenv['POTFILE']
227 installenv.Alias ('potupdate', buildenv.PotBuild (potfile, sources))
229 p_oze = [ os.path.basename (po) for po in glob.glob ('po/*.po') ]
230 languages = [ po.replace ('.po', '') for po in p_oze ]
232 for po_file in p_oze:
233 buildenv.PoBuild(po_file, ['po/'+po_file, potfile])
234 mo_file = po_file.replace (".po", ".mo")
235 installenv.Alias ('install', buildenv.MoBuild (mo_file, po_file))
236 installenv.Alias ('msgupdate', buildenv.MoBuild (mo_file, po_file))
238 for lang in languages:
239 modir = (os.path.join (install_prefix, 'share/locale/' + lang + '/LC_MESSAGES/'))
240 moname = domain + '.mo'
241 installenv.Alias('install', installenv.InstallAs (os.path.join (modir, moname), lang + '.mo'))
244 def fetch_svn_revision (path):
248 cmd += " | awk '/^Revision:/ { print $2}'"
249 return commands.getoutput (cmd)
251 def create_stored_revision (target = None, source = None, env = None):
252 if os.path.exists('.svn'):
253 rev = fetch_svn_revision ('.');
255 text = "#ifndef __ardour_svn_revision_h__\n"
256 text += "#define __ardour_svn_revision_h__\n"
257 text += "static const char* ardour_svn_revision = \"" + rev + "\";\n";
259 print '============> writing svn revision info to svn_revision.h\n'
260 o = file ('svn_revision.h', 'w')
264 print "Could not open svn_revision.h for writing\n"
267 print "You cannot use \"scons revision\" on without using a checked out"
268 print "copy of the Ardour source code repository"
272 # A generic builder for version.cc files
274 # note: requires that DOMAIN, MAJOR, MINOR, MICRO are set in the construction environment
275 # note: assumes one source files, the header that declares the version variables
278 def version_builder (target, source, env):
280 text = "int " + env['DOMAIN'] + "_major_version = " + str (env['MAJOR']) + ";\n"
281 text += "int " + env['DOMAIN'] + "_minor_version = " + str (env['MINOR']) + ";\n"
282 text += "int " + env['DOMAIN'] + "_micro_version = " + str (env['MICRO']) + ";\n"
285 o = file (target[0].get_path(), 'w')
289 print "Could not open", target[0].get_path(), " for writing\n"
292 text = "#ifndef __" + env['DOMAIN'] + "_version_h__\n"
293 text += "#define __" + env['DOMAIN'] + "_version_h__\n"
294 text += "extern const char* " + env['DOMAIN'] + "_revision;\n"
295 text += "extern int " + env['DOMAIN'] + "_major_version;\n"
296 text += "extern int " + env['DOMAIN'] + "_minor_version;\n"
297 text += "extern int " + env['DOMAIN'] + "_micro_version;\n"
298 text += "#endif /* __" + env['DOMAIN'] + "_version_h__ */\n"
301 o = file (target[1].get_path(), 'w')
305 print "Could not open", target[1].get_path(), " for writing\n"
310 version_bld = Builder (action = version_builder)
311 env.Append (BUILDERS = {'VersionBuild' : version_bld})
314 # a builder that makes a hard link from the 'source' executable to a name with
315 # a "build ID" based on the most recent CVS activity that might be reasonably
316 # related to version activity. this relies on the idea that the SConscript
317 # file that builds the executable is updated with new version info and committed
318 # to the source code repository whenever things change.
321 def versioned_builder(target,source,env):
322 w, r = os.popen2( "LANG= svn info | awk '/^Revision:/ { print $2}'")
324 last_revision = r.readline().strip()
327 if last_revision == "":
328 print "No SVN info found - versioned executable cannot be built"
331 print "The current build ID is " + last_revision
333 tagged_executable = source[0].get_path() + '-' + last_revision
335 if os.path.exists (tagged_executable):
336 print "Replacing existing executable with the same build tag."
337 os.unlink (tagged_executable)
339 return os.link (source[0].get_path(), tagged_executable)
341 verbuild = Builder (action = versioned_builder)
342 env.Append (BUILDERS = {'VersionedExecutable' : verbuild})
345 # source tar file builder
348 def distcopy (target, source, env):
349 treedir = str (target[0])
353 except OSError, (errnum, strerror):
354 if errnum != errno.EEXIST:
355 print 'mkdir ', treedir, ':', strerror
359 # we don't know what characters might be in the file names
360 # so quote them all before passing them to the shell
362 all_files = ([ str(s) for s in source ])
363 cmd += " ".join ([ "'%s'" % quoted for quoted in all_files])
364 cmd += ' | (cd ' + treedir + ' && tar xf -)'
368 def tarballer (target, source, env):
369 cmd = 'tar -jcf ' + str (target[0]) + ' ' + str(source[0]) + " --exclude '*~'" + " --exclude .svn --exclude '.svn/*'"
370 print 'running ', cmd, ' ... '
374 dist_bld = Builder (action = distcopy,
375 target_factory = SCons.Node.FS.default_fs.Entry,
376 source_factory = SCons.Node.FS.default_fs.Entry,
379 tarball_bld = Builder (action = tarballer,
380 target_factory = SCons.Node.FS.default_fs.Entry,
381 source_factory = SCons.Node.FS.default_fs.Entry)
383 env.Append (BUILDERS = {'Distribute' : dist_bld})
384 env.Append (BUILDERS = {'Tarball' : tarball_bld})
387 # Make sure they know what they are doing
391 if os.path.isfile('.personal_use_only'):
392 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."
394 sys.stdout.write ("Are you building Ardour for personal use (rather than distribution to others)? [no]: ")
395 answer = sys.stdin.readline ()
396 answer = answer.rstrip().strip()
397 if answer == "yes" or answer == "y":
398 fh = open('.personal_use_only', 'w')
400 print "OK, VST support will be enabled"
402 print 'You cannot build Ardour with VST support for distribution to others.\nIt is a violation of several different licenses. Build with VST=false.'
405 if os.path.isfile('.personal_use_only'):
406 os.remove('.personal_use_only')
412 def pushEnvironment(context):
413 if os.environ.has_key('PATH'):
414 context.Append(PATH = os.environ['PATH'])
416 if os.environ.has_key('PKG_CONFIG_PATH'):
417 context.Append(PKG_CONFIG_PATH = os.environ['PKG_CONFIG_PATH'])
419 if os.environ.has_key('CC'):
420 context['CC'] = os.environ['CC']
422 if os.environ.has_key('CXX'):
423 context['CXX'] = os.environ['CXX']
425 if os.environ.has_key('DISTCC_HOSTS'):
426 context['ENV']['DISTCC_HOSTS'] = os.environ['DISTCC_HOSTS']
427 context['ENV']['HOME'] = os.environ['HOME']
429 pushEnvironment (env)
431 #######################
432 # Dependency Checking #
433 #######################
437 'glib-2.0' : '2.10.1',
438 'gthread-2.0' : '2.10.1',
439 'gtk+-2.0' : '2.8.1',
440 'libxml-2.0' : '2.6.0',
441 'samplerate' : '0.1.0',
445 'libgnomecanvas-2.0' : '2.0'
448 def DependenciesRequiredMessage():
449 print 'You do not have the necessary dependencies required to build ardour'
450 print 'Please consult http://ardour.org/building for more information'
452 def CheckPKGConfig(context, version):
453 context.Message( 'Checking for pkg-config version >= %s... ' %version )
454 ret = context.TryAction('pkg-config --atleast-pkgconfig-version=%s' % version)[0]
455 context.Result( ret )
458 def CheckPKGVersion(context, name, version):
459 context.Message( 'Checking for %s... ' % name )
460 ret = context.TryAction('pkg-config --atleast-version=%s %s' %(version,name) )[0]
461 context.Result( ret )
464 def CheckPKGExists(context, name):
465 context.Message ('Checking for %s...' % name)
466 ret = context.TryAction('pkg-config --exists %s' % name)[0]
470 conf = Configure(env, custom_tests = { 'CheckPKGConfig' : CheckPKGConfig,
471 'CheckPKGVersion' : CheckPKGVersion })
473 # I think a more recent version is needed on win32
474 min_pkg_config_version = '0.8.0'
476 if not conf.CheckPKGConfig(min_pkg_config_version):
477 print 'pkg-config >= %s not found.' % min_pkg_config_version
480 for pkg, version in deps.iteritems():
481 if not conf.CheckPKGVersion( pkg, version ):
482 print '%s >= %s not found.' %(pkg, version)
483 DependenciesRequiredMessage()
488 # ----------------------------------------------------------------------
489 # Construction environment setup
490 # ----------------------------------------------------------------------
494 libraries['core'] = LibraryInfo (CCFLAGS = '-Ilibs')
496 #libraries['sndfile'] = LibraryInfo()
497 #libraries['sndfile'].ParseConfig('pkg-config --cflags --libs sndfile')
499 libraries['lrdf'] = LibraryInfo()
500 libraries['lrdf'].ParseConfig('pkg-config --cflags --libs lrdf')
502 libraries['raptor'] = LibraryInfo()
503 libraries['raptor'].ParseConfig('pkg-config --cflags --libs raptor')
505 libraries['samplerate'] = LibraryInfo()
506 libraries['samplerate'].ParseConfig('pkg-config --cflags --libs samplerate')
508 conf = env.Configure (custom_tests = { 'CheckPKGExists' : CheckPKGExists } )
510 if conf.CheckPKGExists ('fftw3f'):
511 libraries['fftw3f'] = LibraryInfo()
512 libraries['fftw3f'].ParseConfig('pkg-config --cflags --libs fftw3f')
514 if conf.CheckPKGExists ('fftw3'):
515 libraries['fftw3'] = LibraryInfo()
516 libraries['fftw3'].ParseConfig('pkg-config --cflags --libs fftw3')
520 if env['FFT_ANALYSIS']:
522 # Check for fftw3 header as well as the library
525 conf = Configure(libraries['fftw3'])
527 if conf.CheckHeader ('fftw3.h') == False:
528 print ('FFT Analysis cannot be compiled without the FFTW3 headers, which do not seem to be installed')
533 conf = env.Configure(custom_tests = { 'CheckPKGExists' : CheckPKGExists })
535 if conf.CheckPKGExists ('\"slv2 >= 0.6.0\"'):
536 libraries['slv2'] = LibraryInfo()
537 libraries['slv2'].ParseConfig('pkg-config --cflags --libs slv2')
538 env.Append (CCFLAGS="-DHAVE_LV2")
540 print 'Building Ardour with LV2 support requires SLV2 >= 0.6.0'
541 print 'WARNING: SLV2 not found, or too old. Ardour will be built without LV2 support.'
542 print 'Until the 2.4 release, Ardour requires SLV2 out of SVN.'
543 print 'Testing would be very much appreciated! svn co http://svn.drobilla.net/lad/slv2'
547 print 'LV2 support is not enabled. Build with \'scons LV2=1\' to enable.'
549 libraries['jack'] = LibraryInfo()
550 libraries['jack'].ParseConfig('pkg-config --cflags --libs jack')
552 libraries['xml'] = LibraryInfo()
553 libraries['xml'].ParseConfig('pkg-config --cflags --libs libxml-2.0')
555 libraries['xslt'] = LibraryInfo()
556 libraries['xslt'].ParseConfig('pkg-config --cflags --libs libxslt')
558 libraries['glib2'] = LibraryInfo()
559 libraries['glib2'].ParseConfig ('pkg-config --cflags --libs glib-2.0')
560 libraries['glib2'].ParseConfig ('pkg-config --cflags --libs gobject-2.0')
561 libraries['glib2'].ParseConfig ('pkg-config --cflags --libs gmodule-2.0')
562 libraries['glib2'].ParseConfig ('pkg-config --cflags --libs gthread-2.0')
564 libraries['gtk2'] = LibraryInfo()
565 libraries['gtk2'].ParseConfig ('pkg-config --cflags --libs gtk+-2.0')
567 libraries['pango'] = LibraryInfo()
568 libraries['pango'].ParseConfig ('pkg-config --cflags --libs pango')
570 libraries['libgnomecanvas2'] = LibraryInfo()
571 libraries['libgnomecanvas2'].ParseConfig ('pkg-config --cflags --libs libgnomecanvas-2.0')
573 #libraries['flowcanvas'] = LibraryInfo(LIBS='flowcanvas', LIBPATH='#/libs/flowcanvas', CPPPATH='#libs/flowcanvas')
575 # The Ardour Control Protocol Library
577 libraries['ardour_cp'] = LibraryInfo (LIBS='ardour_cp', LIBPATH='#libs/surfaces/control_protocol',
578 CPPPATH='#libs/surfaces/control_protocol')
580 # The Ardour backend/engine
582 libraries['ardour'] = LibraryInfo (LIBS='ardour', LIBPATH='#libs/ardour', CPPPATH='#libs/ardour')
583 libraries['midi++2'] = LibraryInfo (LIBS='midi++', LIBPATH='#libs/midi++2', CPPPATH='#libs/midi++2')
584 libraries['pbd'] = LibraryInfo (LIBS='pbd', LIBPATH='#libs/pbd', CPPPATH='#libs/pbd')
585 libraries['gtkmm2ext'] = LibraryInfo (LIBS='gtkmm2ext', LIBPATH='#libs/gtkmm2ext', CPPPATH='#libs/gtkmm2ext')
588 # SCons should really do this for us
590 conf = env.Configure ()
592 have_cxx = conf.TryAction (Action (str(env['CXX']) + ' --version'))
594 print "This system has no functional C++ compiler. You cannot build Ardour from source without one."
597 print "Congratulations, you have a functioning C++ compiler."
603 # Compiler flags and other system-dependent stuff
607 if env['GPROFILE'] == 1:
608 debug_flags = [ '-g', '-pg' ]
610 debug_flags = [ '-g' ]
612 # guess at the platform, used to define compiler flags
614 config_guess = os.popen("tools/config.guess").read()[:-1]
620 config = config_guess.split ("-")
622 print "system triple: " + config_guess
625 if env['DIST_TARGET'] == 'auto':
626 if config[config_arch] == 'apple':
627 # The [.] matches to the dot after the major version, "." would match any character
628 if re.search ("darwin[0-7][.]", config[config_kernel]) != None:
629 env['DIST_TARGET'] = 'panther'
630 if re.search ("darwin8[.]", config[config_kernel]) != None:
631 env['DIST_TARGET'] = 'tiger'
633 env['DIST_TARGET'] = 'leopard'
635 if re.search ("x86_64", config[config_cpu]) != None:
636 env['DIST_TARGET'] = 'x86_64'
637 elif re.search("i[0-5]86", config[config_cpu]) != None:
638 env['DIST_TARGET'] = 'i386'
639 elif re.search("powerpc", config[config_cpu]) != None:
640 env['DIST_TARGET'] = 'powerpc'
642 env['DIST_TARGET'] = 'i686'
643 print "\n*******************************"
644 print "detected DIST_TARGET = " + env['DIST_TARGET']
645 print "*******************************\n"
648 if config[config_cpu] == 'powerpc' and env['DIST_TARGET'] != 'none':
650 # Apple/PowerPC optimization options
652 # -mcpu=7450 does not reliably work with gcc 3.*
654 if env['DIST_TARGET'] == 'panther' or env['DIST_TARGET'] == 'tiger':
655 if config[config_arch] == 'apple':
656 ## opt_flags.extend ([ "-mcpu=7450", "-faltivec"])
657 # to support g3s but still have some optimization for above
658 opt_flags.extend ([ "-mcpu=G3", "-mtune=7450"])
660 opt_flags.extend ([ "-mcpu=7400", "-maltivec", "-mabi=altivec"])
662 opt_flags.extend([ "-mcpu=750", "-mmultiple" ])
663 opt_flags.extend (["-mhard-float", "-mpowerpc-gfxopt"])
664 opt_flags.extend (["-Os"])
666 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':
668 build_host_supports_sse = 0
670 debug_flags.append ("-DARCH_X86")
671 opt_flags.append ("-DARCH_X86")
673 if config[config_kernel] == 'linux' :
675 if env['DIST_TARGET'] != 'i386':
677 flag_line = os.popen ("cat /proc/cpuinfo | grep '^flags'").read()[:-1]
678 x86_flags = flag_line.split (": ")[1:][0].split ()
680 if "mmx" in x86_flags:
681 opt_flags.append ("-mmmx")
682 if "sse" in x86_flags:
683 build_host_supports_sse = 1
684 if "3dnow" in x86_flags:
685 opt_flags.append ("-m3dnow")
687 if config[config_cpu] == "i586":
688 opt_flags.append ("-march=i586")
689 elif config[config_cpu] == "i686":
690 opt_flags.append ("-march=i686")
692 if ((env['DIST_TARGET'] == 'i686') or (env['DIST_TARGET'] == 'x86_64')) and build_host_supports_sse:
693 opt_flags.extend (["-msse", "-mfpmath=sse", "-DUSE_XMMINTRIN"])
694 debug_flags.extend (["-msse", "-mfpmath=sse", "-DUSE_XMMINTRIN"])
695 # end of processor-specific section
697 # optimization section
698 if env['FPU_OPTIMIZATION']:
699 if env['DIST_TARGET'] == 'tiger' or env['DIST_TARGET'] == 'leopard':
700 opt_flags.append ("-DBUILD_VECLIB_OPTIMIZATIONS");
701 debug_flags.append ("-DBUILD_VECLIB_OPTIMIZATIONS");
702 libraries['core'].Append(LINKFLAGS= '-framework Accelerate')
703 elif env['DIST_TARGET'] == 'i686' or env['DIST_TARGET'] == 'x86_64':
704 opt_flags.append ("-DBUILD_SSE_OPTIMIZATIONS")
705 debug_flags.append ("-DBUILD_SSE_OPTIMIZATIONS")
706 if env['DIST_TARGET'] == 'x86_64':
707 opt_flags.append ("-DUSE_X86_64_ASM")
708 debug_flags.append ("-DUSE_X86_64_ASM")
709 if build_host_supports_sse != 1:
710 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)"
711 # end optimization section
713 # handle x86/x86_64 libdir properly
715 if env['DIST_TARGET'] == 'x86_64':
716 env['LIBDIR']='lib64'
721 # a single way to test if we're on OS X
724 if env['DIST_TARGET'] in ['panther', 'tiger', 'leopard' ]:
726 # force tiger or later, to avoid issues on PPC which defaults
727 # back to 10.1 if we don't tell it otherwise.
728 env.Append (CCFLAGS="-DMAC_OS_X_VERSION_MIN_REQUIRED=1040")
733 # save off guessed arch element in an env
735 env.Append(CONFIG_ARCH=config[config_arch])
739 # ARCH="..." overrides all
742 if env['ARCH'] != '':
743 opt_flags = env['ARCH'].split()
746 # prepend boiler plate optimization flags
751 "-fomit-frame-pointer",
757 if env['DEBUG'] == 1:
758 env.Append(CCFLAGS=" ".join (debug_flags))
759 env.Append(LINKFLAGS=" ".join (debug_flags))
761 env.Append(CCFLAGS=" ".join (opt_flags))
762 env.Append(LINKFLAGS=" ".join (opt_flags))
764 if env['UNIVERSAL'] == 1:
765 env.Append(CCFLAGS="-arch i386 -arch ppc")
766 env.Append(LINKFLAGS="-arch i386 -arch ppc")
772 env.Append(CCFLAGS="-Wall")
773 env.Append(CXXFLAGS="-Woverloaded-virtual")
775 if env['EXTRA_WARN']:
776 env.Append(CCFLAGS="-Wextra -pedantic -ansi")
777 env.Append(CXXFLAGS="-ansi")
778 # env.Append(CFLAGS="-iso")
781 env.Append(CCFLAGS="-DHAVE_LIBLO")
785 # fix scons nitpickiness on APPLE
789 def prep_libcheck(topenv, libinfo):
792 # rationale: GTK-Quartz uses jhbuild and installs to /opt/gtk by default.
793 # All libraries needed should be built against this location
795 libinfo.Append(CPPPATH="/opt/gtk/include", LIBPATH="/opt/gtk/lib")
796 libinfo.Append(CXXFLAGS="-I/opt/gtk/include", LINKFLAGS="-L/opt/gtk/lib")
797 libinfo.Append(CPPPATH="/opt/local/include", LIBPATH="/opt/local/lib")
798 libinfo.Append(CXXFLAGS="-I/opt/local/include", LINKFLAGS="-L/opt/local/lib")
800 prep_libcheck(env, env)
804 # these are part of the Ardour source tree because they are C++
807 libraries['vamp'] = LibraryInfo (LIBS='vampsdk',
808 LIBPATH='#libs/vamp-sdk',
809 CPPPATH='#libs/vamp-sdk')
810 libraries['vamphost'] = LibraryInfo (LIBS='vamphostsdk',
811 LIBPATH='#libs/vamp-sdk',
812 CPPPATH='#libs/vamp-sdk')
814 env['RUBBERBAND'] = False
816 #conf = Configure (env)
818 #if conf.CheckHeader ('fftw3.h'):
819 # env['RUBBERBAND'] = True
820 # libraries['rubberband'] = LibraryInfo (LIBS='rubberband',
821 # LIBPATH='#libs/rubberband',
822 # CPPPATH='#libs/rubberband',
823 # CCFLAGS='-DUSE_RUBBERBAND')
826 # print "-------------------------------------------------------------------------"
827 # print "You do not have the FFTW single-precision development package installed."
828 # print "This prevents Ardour from using the Rubberband library for timestretching"
829 # print "and pitchshifting. It will fall back on SoundTouch for timestretch, and "
830 # print "pitchshifting will not be available."
831 # print "-------------------------------------------------------------------------"
839 libraries['usb'] = LibraryInfo ()
840 prep_libcheck(env, libraries['usb'])
842 conf = Configure (libraries['usb'])
843 if conf.CheckLib ('usb', 'usb_interrupt_write'):
848 # check for linux/input.h while we're at it for powermate
849 if conf.CheckHeader('linux/input.h'):
850 have_linux_input = True
852 have_linux_input = False
854 libraries['usb'] = conf.Finish ()
859 libraries['flac'] = LibraryInfo ()
860 prep_libcheck(env, libraries['flac'])
861 libraries['flac'].Append(CPPPATH="/usr/local/include", LIBPATH="/usr/local/lib")
864 # june 1st 2007: look for a function that is in FLAC 1.1.2 and not in later versions
865 # since the version of libsndfile we have internally does not support
866 # the new API that libFLAC has adopted
869 conf = Configure (libraries['flac'])
870 if conf.CheckLib ('FLAC', 'FLAC__seekable_stream_decoder_init', language='CXX'):
871 conf.env.Append(CCFLAGS='-DHAVE_FLAC')
876 libraries['flac'] = conf.Finish ()
878 # or if that fails...
879 #libraries['flac'] = LibraryInfo (LIBS='FLAC')
881 # boost (we don't link against boost, just use some header files)
883 libraries['boost'] = LibraryInfo ()
884 prep_libcheck(env, libraries['boost'])
885 libraries['boost'].Append(CPPPATH="/usr/local/include", LIBPATH="/usr/local/lib")
886 conf = Configure (libraries['boost'])
887 if conf.CheckHeader ('boost/shared_ptr.hpp', language='CXX') == False:
888 print "Boost header files do not appear to be installed."
891 libraries['boost'] = conf.Finish ()
897 libraries['lo'] = LibraryInfo ()
898 prep_libcheck(env, libraries['lo'])
900 conf = Configure (libraries['lo'])
901 if conf.CheckLib ('lo', 'lo_server_new') == False:
902 print "liblo does not appear to be installed."
905 libraries['lo'] = conf.Finish ()
910 libraries['dmalloc'] = LibraryInfo ()
911 prep_libcheck(env, libraries['dmalloc'])
914 # look for the threaded version
917 conf = Configure (libraries['dmalloc'])
918 if conf.CheckLib ('dmallocth', 'dmalloc_shutdown'):
919 have_libdmalloc = True
921 have_libdmalloc = False
923 libraries['dmalloc'] = conf.Finish ()
926 # Audio/MIDI library (needed for MIDI, since audio is all handled via JACK)
929 conf = Configure(env)
931 # ALSA, for engine dialog
932 libraries['asound'] = LibraryInfo ()
934 if conf.CheckCHeader('alsa/asoundlib.h'):
935 libraries['asound'] = LibraryInfo (LIBS='asound')
937 if conf.CheckCHeader('jack/midiport.h'):
938 libraries['sysmidi'] = LibraryInfo (LIBS='jack')
939 env['SYSMIDI'] = 'JACK MIDI'
940 subst_dict['%MIDITAG%'] = "control"
941 subst_dict['%MIDITYPE%'] = "jack"
942 print "Using JACK MIDI"
943 elif conf.CheckCHeader('alsa/asoundlib.h'):
944 libraries['sysmidi'] = LibraryInfo (LIBS='asound')
945 env['SYSMIDI'] = 'ALSA Sequencer'
946 subst_dict['%MIDITAG%'] = "seq"
947 subst_dict['%MIDITYPE%'] = "alsa/sequencer"
948 print "Using ALSA MIDI"
949 elif conf.CheckCHeader('/System/Library/Frameworks/CoreMIDI.framework/Headers/CoreMIDI.h'):
950 # this line is needed because scons can't handle -framework in ParseConfig() yet.
952 # We need Carbon as well as the rest
953 libraries['sysmidi'] = LibraryInfo (
954 LINKFLAGS = ' -framework CoreMIDI -framework CoreFoundation -framework CoreAudio -framework CoreServices -framework AudioUnit -framework AudioToolbox -framework Carbon -bind_at_load' )
956 libraries['sysmidi'] = LibraryInfo (
957 LINKFLAGS = ' -framework CoreMIDI -framework CoreFoundation -framework CoreAudio -framework CoreServices -framework AudioUnit -framework AudioToolbox -bind_at_load' )
958 env['SYSMIDI'] = 'CoreMIDI'
959 subst_dict['%MIDITAG%'] = "ardour"
960 subst_dict['%MIDITYPE%'] = "coremidi"
962 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."
971 'sigc++-2.0' : '2.0',
973 'libgnomecanvasmm-2.6' : '2.12.0'
976 conf = Configure(env, custom_tests = { 'CheckPKGConfig' : CheckPKGConfig,
977 'CheckPKGVersion' : CheckPKGVersion })
979 for pkg, version in syslibdeps.iteritems():
980 if not conf.CheckPKGVersion( pkg, version ):
981 print '%s >= %s not found.' %(pkg, version)
982 DependenciesRequiredMessage()
987 libraries['sigc2'] = LibraryInfo()
988 libraries['sigc2'].ParseConfig('pkg-config --cflags --libs sigc++-2.0')
989 libraries['glibmm2'] = LibraryInfo()
990 libraries['glibmm2'].ParseConfig('pkg-config --cflags --libs glibmm-2.4')
991 libraries['cairo'] = LibraryInfo()
992 libraries['cairo'].ParseConfig('pkg-config --cflags --libs cairo')
993 libraries['cairomm'] = LibraryInfo()
994 libraries['cairomm'].ParseConfig('pkg-config --cflags --libs cairomm-1.0')
995 libraries['gdkmm2'] = LibraryInfo()
996 libraries['gdkmm2'].ParseConfig ('pkg-config --cflags --libs gdkmm-2.4')
997 libraries['gtkmm2'] = LibraryInfo()
998 libraries['gtkmm2'].ParseConfig ('pkg-config --cflags --libs gtkmm-2.4')
999 libraries['atkmm'] = LibraryInfo()
1000 libraries['atkmm'].ParseConfig ('pkg-config --cflags --libs atkmm-1.6')
1001 libraries['pangomm'] = LibraryInfo()
1002 libraries['pangomm'].ParseConfig ('pkg-config --cflags --libs pangomm-1.4')
1003 libraries['libgnomecanvasmm'] = LibraryInfo()
1004 libraries['libgnomecanvasmm'].ParseConfig ('pkg-config --cflags --libs libgnomecanvasmm-2.6')
1007 # cannot use system one for the time being
1010 libraries['sndfile-ardour'] = LibraryInfo(LIBS='libsndfile-ardour',
1011 LIBPATH='#libs/libsndfile',
1012 CPPPATH=['#libs/libsndfile/src'])
1014 # libraries['libglademm'] = LibraryInfo()
1015 # libraries['libglademm'].ParseConfig ('pkg-config --cflags --libs libglademm-2.4')
1017 # libraries['flowcanvas'] = LibraryInfo(LIBS='flowcanvas', LIBPATH='#/libs/flowcanvas', CPPPATH='#libs/flowcanvas')
1018 libraries['soundtouch'] = LibraryInfo()
1019 #libraries['soundtouch'].ParseConfig ('pkg-config --cflags --libs soundtouch-1.0')
1020 # Comment the previous line and uncomment this for Debian:
1021 libraries['soundtouch'].ParseConfig ('pkg-config --cflags --libs libSoundTouch')
1023 libraries['appleutility'] = LibraryInfo(LIBS='libappleutility',
1024 LIBPATH='#libs/appleutility',
1025 CPPPATH='#libs/appleutility')
1037 'libs/vamp-plugins/',
1038 # these are unconditionally included but have
1039 # tests internally to avoid compilation etc
1043 # this is unconditionally included but has
1044 # tests internally to avoid compilation etc
1045 # if COREAUDIO is not set
1050 # 'libs/flowcanvas',
1057 libraries['cairo'] = LibraryInfo()
1058 libraries['cairo'].ParseConfig('pkg-config --cflags --libs cairo')
1060 libraries['gtk2-unix-print'] = LibraryInfo()
1061 libraries['gtk2-unix-print'].ParseConfig('pkg-config --cflags --libs gtk+-unix-print-2.0')
1063 libraries['sigc2'] = LibraryInfo(LIBS='sigc++2',
1064 LIBPATH='#libs/sigc++2',
1065 CPPPATH='#libs/sigc++2')
1066 libraries['glibmm2'] = LibraryInfo(LIBS='glibmm2',
1067 LIBPATH='#libs/glibmm2',
1068 CPPPATH='#libs/glibmm2/glib')
1069 libraries['pangomm'] = LibraryInfo(LIBS='pangomm',
1070 LIBPATH='#libs/gtkmm2/pango',
1071 CPPPATH='#libs/gtkmm2/pango')
1072 libraries['atkmm'] = LibraryInfo(LIBS='atkmm',
1073 LIBPATH='#libs/gtkmm2/atk',
1074 CPPPATH='#libs/gtkmm2/atk')
1075 libraries['cairomm'] = LibraryInfo(LIBS='cairomm',
1076 LIBPATH='#libs/cairomm',
1077 CPPPATH='#libs/cairomm')
1078 libraries['gdkmm2'] = LibraryInfo(LIBS='gdkmm2',
1079 LIBPATH='#libs/gtkmm2/gdk',
1080 CPPPATH='#libs/gtkmm2/gdk')
1081 libraries['gtkmm2'] = LibraryInfo(LIBS='gtkmm2',
1082 LIBPATH="#libs/gtkmm2/gtk",
1083 CPPPATH='#libs/gtkmm2/gtk/')
1084 libraries['libgnomecanvasmm'] = LibraryInfo(LIBS='libgnomecanvasmm',
1085 LIBPATH='#libs/libgnomecanvasmm',
1086 CPPPATH='#libs/libgnomecanvasmm')
1088 libraries['soundtouch'] = LibraryInfo(LIBS='soundtouch',
1089 LIBPATH='#libs/soundtouch',
1090 CPPPATH=['#libs', '#libs/soundtouch'])
1091 libraries['sndfile-ardour'] = LibraryInfo(LIBS='libsndfile-ardour',
1092 LIBPATH='#libs/libsndfile',
1093 CPPPATH=['#libs/libsndfile', '#libs/libsndfile/src'])
1094 # libraries['libglademm'] = LibraryInfo(LIBS='libglademm',
1095 # LIBPATH='#libs/libglademm',
1096 # CPPPATH='#libs/libglademm')
1097 libraries['appleutility'] = LibraryInfo(LIBS='libappleutility',
1098 LIBPATH='#libs/appleutility',
1099 CPPPATH='#libs/appleutility')
1112 'libs/vamp-plugins/',
1113 # these are unconditionally included but have
1114 # tests internally to avoid compilation etc
1118 # this is unconditionally included but has
1119 # tests internally to avoid compilation etc
1120 # if COREAUDIO is not set
1126 'libs/gtkmm2/pango',
1130 'libs/libgnomecanvasmm',
1138 # * always build the LGPL control protocol lib, since we link against it from libardour
1139 # * ditto for generic MIDI
1140 # * tranzport checks whether it should build internally, but we need here so that
1141 # its included in the tarball
1144 surface_subdirs = [ 'libs/surfaces/control_protocol',
1145 'libs/surfaces/generic_midi',
1146 'libs/surfaces/tranzport',
1147 'libs/surfaces/mackie',
1148 'libs/surfaces/powermate'
1153 env['TRANZPORT'] = 1
1155 env['TRANZPORT'] = 0
1156 print 'Disabled building Tranzport code because libusb could not be found'
1158 if have_linux_input:
1159 env['POWERMATE'] = 1
1161 env['POWERMATE'] = 0
1162 print 'Disabled building Powermate code because linux/input.h could not be found'
1164 if os.access ('libs/surfaces/sony9pin', os.F_OK):
1165 surface_subdirs += [ 'libs/surfaces/sony9pin' ]
1167 env['POWERMATE'] = 0
1168 env['TRANZPORT'] = 0
1171 # timestretch libraries
1174 timefx_subdirs = ['libs/soundtouch']
1175 #if env['RUBBERBAND']:
1176 # timefx_subdirs += ['libs/rubberband']
1178 opts.Save('scache.conf', env)
1179 Help(opts.GenerateHelpText(env))
1181 final_prefix = '$PREFIX'
1184 install_prefix = '$DESTDIR/$PREFIX'
1186 install_prefix = env['PREFIX']
1188 subst_dict['%INSTALL_PREFIX%'] = install_prefix;
1189 subst_dict['%FINAL_PREFIX%'] = final_prefix;
1190 subst_dict['%PREFIX%'] = final_prefix;
1192 if env['PREFIX'] == '/usr':
1193 final_config_prefix = '/etc'
1195 final_config_prefix = env['PREFIX'] + '/etc'
1197 config_prefix = '$DESTDIR' + final_config_prefix
1200 # everybody needs this
1203 env.Merge ([ libraries['core'] ])
1210 conf = Configure (env)
1212 nls_error = 'This system is not configured for internationalized applications. An english-only version will be built:'
1213 print 'Checking for internationalization support ...'
1214 have_gettext = conf.TryAction(Action('xgettext --version'))
1215 if have_gettext[0] != 1:
1216 nls_error += ' No xgettext command.'
1219 print "Found xgettext"
1221 have_msgmerge = conf.TryAction(Action('msgmerge --version'))
1222 if have_msgmerge[0] != 1:
1223 nls_error += ' No msgmerge command.'
1226 print "Found msgmerge"
1228 if not conf.CheckCHeader('libintl.h'):
1229 nls_error += ' No libintl.h.'
1235 print "International version will be built."
1239 env.Append(CCFLAGS="-DENABLE_NLS")
1241 Export('env install_prefix final_prefix config_prefix final_config_prefix libraries i18n ardour_version subst_dict use_flac')
1244 # the configuration file may be system dependent
1247 conf = env.Configure ()
1249 if conf.CheckCHeader('/System/Library/Frameworks/CoreAudio.framework/Versions/A/Headers/CoreAudio.h'):
1250 subst_dict['%JACK_INPUT%'] = "coreaudio:Built-in Audio:in"
1251 subst_dict['%JACK_OUTPUT%'] = "coreaudio:Built-in Audio:out"
1253 subst_dict['%JACK_INPUT%'] = "alsa_pcm:playback_"
1254 subst_dict['%JACK_OUTPUT%'] = "alsa_pcm:capture_"
1256 # posix_memalign available
1257 if not conf.CheckFunc('posix_memalign'):
1258 print 'Did not find posix_memalign(), using malloc'
1259 env.Append(CCFLAGS='-DNO_POSIX_MEMALIGN')
1264 # generate the per-user and system rc files from the same source
1266 sysrcbuild = env.SubstInFile ('ardour_system.rc','ardour.rc.in', SUBST_DICT = subst_dict)
1268 # add to the substitution dictionary
1270 subst_dict['%VERSION%'] = ardour_version[0:3]
1271 subst_dict['%EXTRA_VERSION%'] = ardour_version[3:]
1272 subst_dict['%REVISION_STRING%'] = ''
1273 if os.path.exists('.svn'):
1274 subst_dict['%REVISION_STRING%'] = '.' + fetch_svn_revision ('.') + 'svn'
1276 # specbuild = env.SubstInFile ('ardour.spec','ardour.spec.in', SUBST_DICT = subst_dict)
1278 the_revision = env.Command ('frobnicatory_decoy', [], create_stored_revision)
1279 remove_ardour = env.Command ('frobnicatory_decoy2', [],
1280 [ Delete ('$PREFIX/etc/ardour3'),
1281 Delete ('$PREFIX/lib/ardour3'),
1282 Delete ('$PREFIX/bin/ardour3')])
1284 env.Alias('revision', the_revision)
1285 env.Alias('install', env.Install(os.path.join(config_prefix, 'ardour3'), 'ardour_system.rc'))
1286 env.Alias('uninstall', remove_ardour)
1288 Default (sysrcbuild)
1292 Precious (env['DISTTREE'])
1294 env.Distribute (env['DISTTREE'],
1295 [ 'SConstruct', 'svn_revision.h',
1296 'COPYING', 'PACKAGER_README', 'README',
1298 'tools/config.guess',
1299 'icons/icon/ardour_icon_mac_mask.png',
1300 'icons/icon/ardour_icon_mac.png',
1301 'icons/icon/ardour_icon_tango_16px_blue.png',
1302 'icons/icon/ardour_icon_tango_16px_red.png',
1303 'icons/icon/ardour_icon_tango_22px_blue.png',
1304 'icons/icon/ardour_icon_tango_22px_red.png',
1305 'icons/icon/ardour_icon_tango_32px_blue.png',
1306 'icons/icon/ardour_icon_tango_32px_red.png',
1307 'icons/icon/ardour_icon_tango_48px_blue.png',
1308 'icons/icon/ardour_icon_tango_48px_red.png'
1310 glob.glob ('DOCUMENTATION/AUTHORS*') +
1311 glob.glob ('DOCUMENTATION/CONTRIBUTORS*') +
1312 glob.glob ('DOCUMENTATION/TRANSLATORS*') +
1313 glob.glob ('DOCUMENTATION/BUILD*') +
1314 glob.glob ('DOCUMENTATION/FAQ*') +
1315 glob.glob ('DOCUMENTATION/README*')
1318 srcdist = env.Tarball(env['TARBALL'], [ env['DISTTREE'], the_revision ])
1319 env.Alias ('srctar', srcdist)
1322 # don't leave the distree around
1325 env.AddPreAction (env['DISTTREE'], Action ('rm -rf ' + str (File (env['DISTTREE']))))
1326 env.AddPostAction (srcdist, Action ('rm -rf ' + str (File (env['DISTTREE']))))
1332 for subdir in coredirs:
1333 SConscript (subdir + '/SConscript')
1335 for sublistdir in [ subdirs, timefx_subdirs, gtk_subdirs, surface_subdirs ]:
1336 for subdir in sublistdir:
1337 SConscript (subdir + '/SConscript')
1340 env.Clean ('scrub', [ 'scache.conf', '.sconf_temp', '.sconsign.dblite', 'config.log'])