remove translation hack, which for some reason is not needed for ardour 2.X
[ardour.git] / SConstruct
1 # -*- python -*-
2
3 #
4 # and there we have it, or do we?
5 #
6
7 import os
8 import os.path
9 import sys
10 import re
11 import shutil
12 import glob
13 import errno
14 import time
15 import platform
16 import string
17 import commands
18 from sets import Set
19 import SCons.Node.FS
20
21 SConsignFile()
22 EnsureSConsVersion(0, 96)
23
24 ardour_version = '2.8.14'
25
26 subst_dict = { }
27
28 #
29 # Command-line options
30 #
31
32 opts = Variables('scache.conf')
33 opts.AddVariables(
34     ('ARCH', 'Set architecture-specific compilation flags by hand (all flags as 1 argument)',''),
35     ('WINDOWS_KEY', 'Set X Modifier (Mod1,Mod2,Mod3,Mod4,Mod5) for "Windows" key', 'Mod4><Super'),
36     ('PROGRAM_NAME', 'Set program name (default is "Ardour")', 'Ardour'),
37     ('DIST_LIBDIR', 'Explicitly set library dir. If not set, Fedora-style defaults are used (typically lib or lib64)', ''),
38     PathVariable('DESTDIR', 'Set the intermediate install "prefix"', '/'),
39     PathVariable('PREFIX', 'Set the install "prefix"', '/usr/local'),
40     EnumVariable('DIST_TARGET', 'Build target for cross compiling packagers', 'auto', 
41           allowed_values=('auto', 'i386', 'i686', 'x86_64', 'powerpc', 'tiger', 'panther', 'leopard', 'none' ), ignorecase=2),
42     BoolVariable('AUDIOUNITS', 'Compile with Apple\'s AudioUnit library. (experimental)', 0),
43     BoolVariable('COREAUDIO', 'Compile with Apple\'s CoreAudio library', 0),
44     BoolVariable('GTKOSX', 'Compile for use with GTK-OSX, not GTK-X11', 0),
45     BoolVariable('OLDFONTS', 'Old school font sizes', 0),
46     BoolVariable('DEBUG', 'Set to build with debugging information and no optimizations', 0),
47     BoolVariable('STL_DEBUG', 'Set to build with Standard Template Library Debugging', 0),
48     BoolVariable('DMALLOC', 'Compile and link using the dmalloc library', 0),
49     BoolVariable('EXTRA_WARN', 'Compile with -Wextra, -ansi, and -pedantic.  Might break compilation.  For pedants', 0),
50     BoolVariable('FFT_ANALYSIS', 'Include FFT analysis window', 1),
51     BoolVariable('FREESOUND', 'Include Freesound database lookup', 1),
52     BoolVariable('FPU_OPTIMIZATION', 'Build runtime checked assembler code', 1),
53     BoolVariable('LIBLO', 'Compile with support for liblo library', 1),
54     BoolVariable('NLS', 'Set to turn on i18n support', 1),
55     BoolVariable('SURFACES', 'Build support for control surfaces', 1),
56     BoolVariable('WIIMOTE', 'Build the wiimote control surface', 0),
57     BoolVariable('SYSLIBS', 'USE AT YOUR OWN RISK: CANCELS ALL SUPPORT FROM ARDOUR AUTHORS: Use existing system versions of various libraries instead of internal ones', 0),
58     BoolVariable('UNIVERSAL', 'Compile as universal binary.  Requires that external libraries are already universal.', 0),
59     BoolVariable('VERSIONED', 'Add revision information to ardour/gtk executable name inside the build directory', 0),
60     BoolVariable('VST', 'Compile with support for VST', 0),
61     BoolVariable('LV2', 'Compile with support for LV2 (if Lilv is available)', 1),
62     BoolVariable('LV2_UI', 'Compile with support for LV2 UIs (if Suil is available)', 1),
63     BoolVariable('GPROFILE', 'Compile with support for gprofile (Developers only)', 0),
64     BoolVariable('FREEDESKTOP', 'Install MIME type, icons and .desktop file as per the freedesktop.org spec (requires xdg-utils and shared-mime-info). "scons uninstall" removes associations in desktop database', 0),
65     BoolVariable('TRANZPORT', 'Compile with support for Frontier Designs (if libusb is available)', 1),
66     BoolVariable('AUBIO', "Use Paul Brossier's aubio library for feature detection", 1),
67     BoolVariable('AUSTATE', "Build with support for AU settings & presets saving/loading", 0),
68     BoolVariable('WITH_CARBON', "Build with support for Carbon AU GUIs", 1),
69 )
70
71 #----------------------------------------------------------------------
72 # a handy helper that provides a way to merge compile/link information
73 # from multiple different "environments"
74 #----------------------------------------------------------------------
75 #
76 class LibraryInfo(Environment):
77     def __init__(self,*args,**kw):
78         Environment.__init__ (self,*args,**kw)
79         self.ENV_update(os.environ)
80     
81     def Merge (self,others):
82         for other in others:
83             self.Append (LIBS = other.get ('LIBS',[]))
84             self.Append (LIBPATH = other.get ('LIBPATH', []))
85             self.Append (CPPPATH = other.get('CPPPATH', []))
86             self.Append (LINKFLAGS = other.get('LINKFLAGS', []))
87             self.Append (CCFLAGS = other.get('CCFLAGS', []))
88         self.Replace(LIBPATH = list(Set(self.get('LIBPATH', []))))
89         self.Replace(CPPPATH = list(Set(self.get('CPPPATH',[]))))
90         #doing LINKFLAGS breaks -framework
91         #doing LIBS break link order dependency
92     
93     def ENV_update(self, src_ENV):
94         for k in src_ENV.keys():
95             if k in self['ENV'].keys() and k in [ 'PATH', 'LD_LIBRARY_PATH',
96                                                   'LIB', 'PKG_CONFIG_PATH', 'INCLUDE' ]:
97                 self['ENV'][k]=SCons.Util.AppendPath(self['ENV'][k], src_ENV[k])
98             else:
99                 self['ENV'][k]=src_ENV[k]
100
101 env = LibraryInfo (options = opts,
102                    CPPPATH = [ '.' ],
103                    VERSION = ardour_version,
104                    TARBALL='ardour-' + ardour_version + '.tar.bz2',
105                    DISTFILES = [ ],
106                    DISTTREE  = '#ardour-' + ardour_version,
107                    DISTCHECKDIR = '#ardour-' + ardour_version + '/check'
108                    )
109
110 env.ENV_update(os.environ)
111
112 #----------------------------------------------------------------------
113 # Builders
114 #----------------------------------------------------------------------
115
116 # Handy subst-in-file builder
117 #
118
119 def do_subst_in_file(targetfile, sourcefile, dict):
120     """Replace all instances of the keys of dict with their values.
121     For example, if dict is {'%VERSION%': '1.2345', '%BASE%': 'MyProg'},
122     then all instances of %VERSION% in the file will be replaced with 1.2345 etc.
123     """
124     try:
125         f = open(sourcefile, 'rb')
126         contents = f.read()
127         f.close()
128     except:
129         raise SCons.Errors.UserError, "Can't read source file %s"%sourcefile
130     for (k,v) in dict.items():
131         contents = re.sub(k, v, contents)
132     try:
133         f = open(targetfile, 'wb')
134         f.write(contents)
135         f.close()
136     except:
137         raise SCons.Errors.UserError, "Can't write target file %s"%targetfile
138     return 0 # success
139
140 def subst_in_file(target, source, env):
141     if not env.has_key('SUBST_DICT'):
142         raise SCons.Errors.UserError, "SubstInFile requires SUBST_DICT to be set."
143     d = dict(env['SUBST_DICT']) # copy it
144     for (k,v) in d.items():
145         if callable(v):
146             d[k] = env.subst(v())
147         elif SCons.Util.is_String(v):
148             d[k]=env.subst(v)
149         else:
150             raise SCons.Errors.UserError, "SubstInFile: key %s: %s must be a string or callable"%(k, repr(v))
151     for (t,s) in zip(target, source):
152         return do_subst_in_file(str(t), str(s), d)
153
154 def subst_in_file_string(target, source, env):
155     """This is what gets printed on the console."""
156     return '\n'.join(['Substituting vars from %s into %s'%(str(s), str(t))
157                       for (t,s) in zip(target, source)])
158
159 def subst_emitter(target, source, env):
160     """Add dependency from substituted SUBST_DICT to target.
161     Returns original target, source tuple unchanged.
162     """
163     d = env['SUBST_DICT'].copy() # copy it
164     for (k,v) in d.items():
165         if callable(v):
166             d[k] = env.subst(v())
167         elif SCons.Util.is_String(v):
168             d[k]=env.subst(v)
169     Depends(target, SCons.Node.Python.Value(d))
170     # Depends(target, source) # this doesn't help the install-sapphire-linux.sh problem
171     return target, source
172
173 subst_action = Action (subst_in_file, subst_in_file_string)
174 env['BUILDERS']['SubstInFile'] = Builder(action=subst_action, emitter=subst_emitter)
175
176 #
177 # internationalization
178 #
179
180 # po_builder: builder function to copy po files to the parent directory while updating them
181 #
182 # first source:  .po file
183 # second source: .pot file
184 #
185
186 def po_builder(target,source,env):
187     os.spawnvp (os.P_WAIT, 'cp', ['cp', str(source[0]), str(target[0])])
188     args = [ 'msgmerge',
189              '--update',
190              str(target[0]),
191              str(source[1])
192              ]
193     print 'Updating ' + str(target[0])
194     return os.spawnvp (os.P_WAIT, 'msgmerge', args)
195
196 po_bld = Builder (action = po_builder)
197 env.Append(BUILDERS = {'PoBuild' : po_bld})
198
199 # mo_builder: builder function for (binary) message catalogs (.mo)
200 #
201 # first source:  .po file
202 #
203
204 def mo_builder(target,source,env):
205     args = [ 'msgfmt',
206              '-c',
207              '-o',
208              target[0].get_path(),
209              source[0].get_path()
210              ]
211     return os.spawnvp (os.P_WAIT, 'msgfmt', args)
212
213 mo_bld = Builder (action = mo_builder)
214 env.Append(BUILDERS = {'MoBuild' : mo_bld})
215
216 # pot_builder: builder function for message templates (.pot)
217 #
218 # source: list of C/C++ etc. files to extract messages from
219 #
220
221 def pot_builder(target,source,env):
222     args = [ 'xgettext',
223              '--keyword=_',
224              '--keyword=N_',
225              '--from-code=UTF-8',
226              '-o', target[0].get_path(),
227              "--default-domain=" + env['PACKAGE'],
228              '--copyright-holder="Paul Davis"' ]
229     args += [ src.get_path() for src in source ]
230     
231     return os.spawnvp (os.P_WAIT, 'xgettext', args)
232
233 pot_bld = Builder (action = pot_builder)
234 env.Append(BUILDERS = {'PotBuild' : pot_bld})
235
236 #
237 # utility function, not a builder
238 #
239
240 def i18n (buildenv, sources, installenv):
241     domain = buildenv['PACKAGE']
242     potfile = buildenv['POTFILE']
243
244     #
245     # on glibc systems, libintl is part of libc. not true on OS X
246     #
247     
248     if re.search ("darwin[0-9]", config[config_kernel]):
249         buildenv.Merge ([ libraries['intl'] ])
250
251     installenv.Alias ('potupdate', buildenv.PotBuild (potfile, sources))
252     
253     p_oze = [ os.path.basename (po) for po in glob.glob ('po/*.po') ]
254     languages = [ po.replace ('.po', '') for po in p_oze ]
255     
256     for po_file in p_oze:
257         buildenv.PoBuild(po_file, ['po/'+po_file, potfile])
258         mo_file = po_file.replace (".po", ".mo")
259         installenv.Alias ('install', buildenv.MoBuild (mo_file, po_file))
260         installenv.Alias ('msgupdate', buildenv.MoBuild (mo_file, po_file))
261     
262     for lang in languages:
263         modir = (os.path.join (install_prefix, 'share/locale/' + lang + '/LC_MESSAGES/'))
264         moname = domain + '.mo'
265         installenv.Alias('install', installenv.InstallAs (os.path.join (modir, moname), lang + '.mo'))
266
267
268 def fetch_svn_revision (path):
269     cmd = "LANG= "
270     cmd += "svn info "
271     cmd += path
272     cmd += " 2>/dev/null | awk '/^Revision:/ { print $2}'"
273     return commands.getoutput (cmd)
274
275 def create_stored_revision (target = None, source = None, env = None):
276     if os.path.exists('.svn'):    
277         rev = fetch_svn_revision ('.');
278         try:
279             text  = "#include <ardour/svn_revision.h>\n"
280             text += "namespace ARDOUR {\n";
281             text += "extern const char* svn_revision = \"" + rev + "\";\n";
282             text += "}\n";
283             print '============> writing svn revision info to libs/ardour/svn_revision.cc\n'
284             o = file ('libs/ardour/svn_revision.cc', 'w')
285             o.write (text)
286             o.close ()
287         except IOError:
288             print "Could not open libs/ardour/svn_revision.cc for writing\n"
289             sys.exit (-1)
290     else:
291         if not os.path.exists('libs/ardour/ardour/svn_revision.h'):    
292             print "This release of ardour is missing libs/ardour/ardour/svn_revision.h. Blame the packager."
293             sys.exit (-1)
294
295 #
296 # A generic builder for version.cc files
297 #
298 # note: requires that DOMAIN, MAJOR, MINOR, MICRO are set in the construction environment
299 # note: assumes one source files, the header that declares the version variables
300 #
301
302 def version_builder (target, source, env):
303
304     text  = "int " + env['DOMAIN'] + "_major_version = " + str (env['MAJOR']) + ";\n"
305     text += "int " + env['DOMAIN'] + "_minor_version = " + str (env['MINOR']) + ";\n"
306     text += "int " + env['DOMAIN'] + "_micro_version = " + str (env['MICRO']) + ";\n"
307     
308     try:
309         o = file (target[0].get_path(), 'w')
310         o.write (text)
311         o.close ()
312     except IOError:
313         print "Could not open", target[0].get_path(), " for writing\n"
314         sys.exit (-1)
315
316     text  = "#ifndef __" + env['DOMAIN'] + "_version_h__\n"
317     text += "#define __" + env['DOMAIN'] + "_version_h__\n"
318     text += "extern const char* " + env['DOMAIN'] + "_revision;\n"
319     text += "extern int " + env['DOMAIN'] + "_major_version;\n"
320     text += "extern int " + env['DOMAIN'] + "_minor_version;\n"
321     text += "extern int " + env['DOMAIN'] + "_micro_version;\n"
322     text += "#endif /* __" + env['DOMAIN'] + "_version_h__ */\n"
323     
324     try:
325         o = file (target[1].get_path(), 'w')
326         o.write (text)
327         o.close ()
328     except IOError:
329         print "Could not open", target[1].get_path(), " for writing\n"
330         sys.exit (-1)
331         
332     return None
333
334 version_bld = Builder (action = version_builder)
335 env.Append (BUILDERS = {'VersionBuild' : version_bld})
336
337 #
338 # a builder that makes a hard link from the 'source' executable to a name with
339 # a "build ID" based on the most recent CVS activity that might be reasonably
340 # related to version activity. this relies on the idea that the SConscript
341 # file that builds the executable is updated with new version info and committed
342 # to the source code repository whenever things change.
343 #
344
345 def versioned_builder(target,source,env):
346     w, r = os.popen2( "LANG= svn info 2>/dev/null | awk '/^Revision:/ { print $2}'")
347     
348     last_revision = r.readline().strip()
349     w.close()
350     r.close()
351     if last_revision == "":
352         print "No SVN info found - versioned executable cannot be built"
353         return -1
354     
355     print "The current build ID is " + last_revision
356     
357     tagged_executable = source[0].get_path() + '-' + last_revision
358     
359     if os.path.exists (tagged_executable):
360         print "Replacing existing executable with the same build tag."
361         os.unlink (tagged_executable)
362     
363     return os.link (source[0].get_path(), tagged_executable)
364
365 verbuild = Builder (action = versioned_builder)
366 env.Append (BUILDERS = {'VersionedExecutable' : verbuild})
367
368 #
369 # source tar file builder
370 #
371
372 def distcopy (target, source, env):
373     treedir = str (target[0])
374     
375     try:
376         os.mkdir (treedir)
377     except OSError, (errnum, strerror):
378         if errnum != errno.EEXIST:
379             print 'mkdir ', treedir, ':', strerror
380     
381     cmd = 'tar cf - '
382     #
383     # we don't know what characters might be in the file names
384     # so quote them all before passing them to the shell
385     #
386     all_files = ([ str(s) for s in source ])
387     cmd += " ".join ([ "'%s'" % quoted for quoted in all_files])
388     cmd += ' | (cd ' + treedir + ' && tar xf -)'
389     p = os.popen (cmd)
390     return p.close ()
391
392 def tarballer (target, source, env):
393     cmd = 'tar -jcf ' + str (target[0]) +  ' ' + str(source[0]) + "  --exclude '*~'" + " --exclude .svn --exclude '.svn/*'"
394     print 'running ', cmd, ' ... '
395     p = os.popen (cmd)
396     return p.close ()
397
398 dist_bld = Builder (action = distcopy,
399                     target_factory = SCons.Node.FS.default_fs.Entry,
400                     source_factory = SCons.Node.FS.default_fs.Entry,
401                     multi = 1)
402
403 tarball_bld = Builder (action = tarballer,
404                        target_factory = SCons.Node.FS.default_fs.Entry,
405                        source_factory = SCons.Node.FS.default_fs.Entry)
406
407 env.Append (BUILDERS = {'Distribute' : dist_bld})
408 env.Append (BUILDERS = {'Tarball' : tarball_bld})
409
410 ####################
411 # push environment
412 ####################
413
414 def pushEnvironment(context):
415     if os.environ.has_key('PATH'):
416         context['ENV']['PATH'] = os.environ['PATH']
417         
418     if os.environ.has_key('PKG_CONFIG_PATH'):
419         context['ENV']['PKG_CONFIG_PATH'] = os.environ['PKG_CONFIG_PATH']
420             
421     if os.environ.has_key('CC'):
422         context['CC'] = os.environ['CC']
423                 
424     if os.environ.has_key('CXX'):
425         context['CXX'] = os.environ['CXX']
426
427     if os.environ.has_key('DISTCC_HOSTS'):
428         context['ENV']['DISTCC_HOSTS'] = os.environ['DISTCC_HOSTS']
429         context['ENV']['HOME'] = os.environ['HOME']
430
431 pushEnvironment (env)
432
433 #######################
434 # Dependency Checking #
435 #######################
436
437 deps = \
438 {
439         'glib-2.0'             : '2.10.1',
440         'gthread-2.0'          : '2.10.1',
441         'gtk+-2.0'             : '2.8.1',
442         'libxml-2.0'           : '2.6.0',
443         'samplerate'           : '0.1.0',
444         'raptor2'              : '2.0.0',
445         'lrdf'                 : '0.4.0',
446         'jack'                 : '0.120.0',
447         'libgnomecanvas-2.0'   : '2.0',
448         'sndfile'              : '1.0.18',
449         'aubio'                : '0.3.0',
450         'liblo'                : '0.24'
451 }
452
453 def DependenciesRequiredMessage():
454         print 'You do not have the necessary dependencies required to build ardour'
455         print 'Please consult http://ardour.org/building for more information'
456
457 def CheckPKGConfig(context, version):
458     context.Message( 'Checking for pkg-config version >= %s... ' %version )
459     ret = context.TryAction('pkg-config --atleast-pkgconfig-version=%s' % version)[0]
460     context.Result( ret )
461     return ret
462
463 def CheckPKGVersion(context, name, version):
464     context.Message( 'Checking for %s... ' % name )
465     ret = context.TryAction('pkg-config --atleast-version=%s %s' %(version,name) )[0]
466     context.Result( ret )
467     return ret
468
469 def CheckPKGExists(context, name):
470     context.Message ('Checking for %s...' % name)
471     ret = context.TryAction('pkg-config --exists %s' % name)[0]
472     context.Result (ret)
473     return ret
474
475 conf = Configure(env, custom_tests = { 'CheckPKGConfig' : CheckPKGConfig,
476                                        'CheckPKGVersion' : CheckPKGVersion })
477
478 # I think a more recent version is needed on win32
479 min_pkg_config_version = '0.8.0'
480
481 if not conf.CheckPKGConfig(min_pkg_config_version):
482      print 'pkg-config >= %s not found.' % min_pkg_config_version
483      Exit(1)
484
485 for pkg, version in deps.iteritems():
486         if not conf.CheckPKGVersion( pkg, version ):
487                 print '%s >= %s not found.' %(pkg, version)
488                 DependenciesRequiredMessage()
489                 Exit(1)
490
491 env = conf.Finish()
492
493 # ----------------------------------------------------------------------
494 # Construction environment setup
495 # ----------------------------------------------------------------------
496
497 libraries = { }
498
499 libraries['core'] = LibraryInfo (CCFLAGS = '-Ilibs')
500
501 conf = env.Configure (custom_tests = { 'CheckPKGExists' : CheckPKGExists,
502                                        'CheckPKGVersion' : CheckPKGVersion }
503                       )
504                       
505
506 if conf.CheckPKGExists ('fftw3f'):
507     libraries['fftw3f'] = LibraryInfo()
508     libraries['fftw3f'].ParseConfig('pkg-config --cflags --libs fftw3f')
509
510 if conf.CheckPKGExists ('fftw3'):
511     libraries['fftw3'] = LibraryInfo()
512     libraries['fftw3'].ParseConfig('pkg-config --cflags --libs fftw3')
513
514 if conf.CheckPKGExists ('aubio'):
515     libraries['aubio'] = LibraryInfo()
516     libraries['aubio'].ParseConfig('pkg-config --cflags --libs aubio')
517
518 env = conf.Finish ()
519
520 if env['FFT_ANALYSIS']:
521         #
522         # Check for fftw3 header as well as the library
523         #
524
525         conf = Configure(libraries['fftw3'])
526
527         if conf.CheckHeader ('fftw3.h') == False:
528             print ('Ardour cannot be compiled without the FFTW3 headers, which do not seem to be installed')
529             sys.exit (1)            
530         conf.Finish()
531
532 if env['FREESOUND']:
533     libraries['curl'] = LibraryInfo()
534     conf = env.Configure(custom_tests = { 'CheckPKGVersion' : CheckPKGVersion})
535
536     if conf.CheckPKGVersion('libcurl', '7.0.0'):
537         libraries['curl'].ParseConfig('pkg-config --cflags --libs libcurl')
538     else:
539         print 'FREESOUND support cannot be built without the development libraries for CURL 7.X.X or later'
540         env['FREESOUND'] = 0;
541
542     conf.Finish ()
543
544 if env['LV2']:
545         conf = env.Configure(custom_tests = { 'CheckPKGVersion' : CheckPKGVersion})
546         
547         if conf.CheckPKGVersion('lilv-0', '0.5.0'):
548                 libraries['lilv'] = LibraryInfo()
549                 libraries['lilv'].ParseConfig('pkg-config --cflags --libs lilv-0')
550                 env.Append (CCFLAGS="-DHAVE_LV2")
551         else:
552                 print 'LV2 support is not enabled (Lilv not found or older than 0.4.0)'
553                 env['LV2'] = 0
554
555         if conf.CheckPKGVersion('lilv-0', '0.14.0'):
556                 env.Append (CCFLAGS="-DHAVE_NEW_LILV")
557
558         if env['LV2_UI']:
559                 if conf.CheckPKGVersion('suil-0', '0.4.0'):
560                         libraries['suil'] = LibraryInfo()
561                         libraries['suil'].ParseConfig('pkg-config --cflags --libs suil-0')
562                         env.Append (CCFLAGS="-DHAVE_SUIL")
563                         env['LV2_UI'] = 1
564                 else:
565                         print 'LV2 UI support is not enabled (Suil not found or older than 0.4.0'
566                         env['LV2_UI'] = 0
567
568         conf.Finish()
569 else:
570         env['LV2_UI'] = 0
571         print 'LV2 support is not enabled.  Build with \'scons LV2=1\' to enable.'
572
573 if not env['WIIMOTE']:
574         print 'WIIMOTE not enabled. Build with \'scons WIIMOTE=1\' to enable support.'
575
576 libraries['jack'] = LibraryInfo()
577 libraries['jack'].ParseConfig('pkg-config --cflags --libs jack')
578
579 libraries['xml'] = LibraryInfo()
580 libraries['xml'].ParseConfig('pkg-config --cflags --libs libxml-2.0')
581
582 libraries['xslt'] = LibraryInfo()
583 libraries['xslt'].ParseConfig('pkg-config --cflags --libs libxslt')
584
585 libraries['lrdf'] = LibraryInfo()
586 libraries['lrdf'].ParseConfig('pkg-config --cflags --libs lrdf')
587
588 libraries['liblo'] = LibraryInfo()
589 libraries['liblo'].ParseConfig('pkg-config --cflags --libs liblo')
590
591 libraries['raptor'] = LibraryInfo()
592 libraries['raptor'].ParseConfig('pkg-config --cflags --libs raptor2')
593
594 libraries['sndfile'] = LibraryInfo()
595 libraries['sndfile'].ParseConfig ('pkg-config --cflags --libs sndfile')
596
597 libraries['samplerate'] = LibraryInfo()
598 libraries['samplerate'].ParseConfig('pkg-config --cflags --libs samplerate')
599
600 libraries['glib2'] = LibraryInfo()
601 libraries['glib2'].ParseConfig ('pkg-config --cflags --libs glib-2.0')
602 libraries['glib2'].ParseConfig ('pkg-config --cflags --libs gobject-2.0')
603 libraries['glib2'].ParseConfig ('pkg-config --cflags --libs gmodule-2.0')
604 libraries['glib2'].ParseConfig ('pkg-config --cflags --libs gthread-2.0')
605
606 libraries['freetype2'] = LibraryInfo()
607 libraries['freetype2'].ParseConfig ('pkg-config --cflags --libs freetype2')
608
609 libraries['gtk2'] = LibraryInfo()
610 libraries['gtk2'].ParseConfig ('pkg-config --cflags --libs gtk+-2.0')
611
612 libraries['pango'] = LibraryInfo()
613 libraries['pango'].ParseConfig ('pkg-config --cflags --libs pango')
614
615 libraries['libgnomecanvas2'] = LibraryInfo()
616 libraries['libgnomecanvas2'].ParseConfig ('pkg-config --cflags --libs libgnomecanvas-2.0')
617
618 #libraries['flowcanvas'] = LibraryInfo(LIBS='flowcanvas', LIBPATH='#/libs/flowcanvas', CPPPATH='#libs/flowcanvas')
619
620 # The Ardour Control Protocol Library
621
622 libraries['ardour_cp'] = LibraryInfo (LIBS='ardour_cp', LIBPATH='#libs/surfaces/control_protocol',
623                                       CPPPATH='#libs/surfaces/control_protocol')
624
625 # The Ardour backend/engine
626
627 libraries['ardour'] = LibraryInfo (LIBS='ardour', LIBPATH='#libs/ardour', CPPPATH='#libs/ardour')
628 libraries['midi++2'] = LibraryInfo (LIBS='midi++', LIBPATH='#libs/midi++2', CPPPATH='#libs/midi++2')
629 libraries['pbd']    = LibraryInfo (LIBS='pbd', LIBPATH='#libs/pbd', CPPPATH='#libs/pbd')
630 libraries['gtkmm2ext'] = LibraryInfo (LIBS='gtkmm2ext', LIBPATH='#libs/gtkmm2ext', CPPPATH='#libs/gtkmm2ext')
631
632
633 # SCons should really do this for us
634
635 conf = env.Configure ()
636
637 have_cxx = conf.TryAction (Action (str(env['CXX']) + ' --version'))
638 if have_cxx[0] != 1:
639     print "This system has no functional C++ compiler. You cannot build Ardour from source without one."
640     sys.exit (1)
641 else:
642     print "Congratulations, you have a functioning C++ compiler."
643
644 env = conf.Finish()
645
646
647 #
648 # Compiler flags and other system-dependent stuff
649 #
650
651 opt_flags = []
652 if env['GPROFILE'] == 1:
653     debug_flags = [ '-g', '-pg' ]
654 else:
655     debug_flags = [ '-g' ]
656
657 # guess at the platform, used to define compiler flags
658
659 config_guess = os.popen("tools/config.guess").read()[:-1]
660
661 config_cpu = 0
662 config_arch = 1
663 config_kernel = 2
664 config_os = 3
665 config = config_guess.split ("-")
666
667 print "system triple: " + config_guess
668
669 # Autodetect
670 print 'dist target: ', env['DIST_TARGET'], '\n'
671 if env['DIST_TARGET'] == 'auto':
672     if config[config_arch] == 'apple':
673         # The [.] matches to the dot after the major version, "." would match any character
674         if re.search ("darwin[0-7][.]", config[config_kernel]) != None:
675             env['DIST_TARGET'] = 'panther'
676         if re.search ("darwin8[.]", config[config_kernel]) != None:
677             env['DIST_TARGET'] = 'tiger'
678         else:
679             env['DIST_TARGET'] = 'leopard'
680     else:
681         if re.search ("x86_64", config[config_cpu]) != None:
682             env['DIST_TARGET'] = 'x86_64'
683         elif re.search("i[0-5]86", config[config_cpu]) != None:
684             env['DIST_TARGET'] = 'i386'
685         elif re.search("powerpc", config[config_cpu]) != None:
686             env['DIST_TARGET'] = 'powerpc'
687         else:
688             env['DIST_TARGET'] = 'i686'
689     print "\n*******************************"
690     print "detected DIST_TARGET = " + env['DIST_TARGET']
691     print "*******************************\n"
692
693 if env['DIST_TARGET'] != 'tiger' and env['DIST_TARGET'] != 'leopard':
694         # make sure this is all disabled for non-OS X builds
695         env['GTKOSX'] = 0
696         env['COREAUDIO'] = 0
697         env['AUDIOUNITS'] = 0
698         env['AUSTATE'] = 0
699         env['WITH_CARBON'] = 0
700
701 if config[config_cpu] == 'powerpc' and env['DIST_TARGET'] != 'none':
702     # Apple/PowerPC optimization options
703     #
704     # -mcpu=7450 does not reliably work with gcc 3.*
705     #
706     if env['DIST_TARGET'] == 'panther' or env['DIST_TARGET'] == 'tiger':
707         if config[config_arch] == 'apple':
708             ## opt_flags.extend ([ "-mcpu=7450", "-faltivec"])
709             # to support g3s but still have some optimization for above
710             opt_flags.extend ([ "-mcpu=G3", "-mtune=7450"])
711         else:
712             opt_flags.extend ([ "-mcpu=7400", "-maltivec", "-mabi=altivec"])
713     else:
714         opt_flags.extend([ "-mcpu=750", "-mmultiple" ])
715     opt_flags.extend (["-mhard-float", "-mpowerpc-gfxopt"])
716     #opt_flags.extend (["-Os"])
717
718 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':
719     print 'Config CPU is', config[config_cpu], '\n'
720     
721     build_host_supports_sse = 0
722     
723     #
724     # ARCH_X86 means anything in the x86 family from i386 to x86_64
725     # USE_X86_64_ASM is used to distingush 32 and 64 bit assembler
726     #
727
728     if (re.search ("(i[0-9]86|x86_64)", config[config_cpu]) != None):
729         debug_flags.append ("-DARCH_X86")
730         opt_flags.append ("-DARCH_X86")
731     
732     if config[config_kernel] == 'linux' :
733         
734         if env['DIST_TARGET'] != 'i386':
735             
736             flag_line = os.popen ("cat /proc/cpuinfo | grep '^flags'").read()[:-1]
737             x86_flags = flag_line.split (": ")[1:][0].split ()
738             
739             if "mmx" in x86_flags:
740                 opt_flags.append ("-mmmx")
741             if "sse" in x86_flags:
742                 build_host_supports_sse = 1
743             if "3dnow" in x86_flags:
744                 opt_flags.append ("-m3dnow")
745             if config[config_cpu] == "i586":
746                 opt_flags.append ("-march=i586")
747             elif config[config_cpu] == "i686":
748                 opt_flags.append ("-march=i686")
749     
750     if ((env['DIST_TARGET'] == 'i686') or (env['DIST_TARGET'] == 'x86_64')) and build_host_supports_sse:
751         opt_flags.extend (["-msse", "-mfpmath=sse", "-DUSE_XMMINTRIN"])
752         debug_flags.extend (["-msse", "-mfpmath=sse", "-DUSE_XMMINTRIN"])
753
754     if config[config_cpu] == "i586":
755         opt_flags.append ("-march=i586")
756     elif config[config_cpu] == "i686" and config[config_arch] != 'apple':
757         opt_flags.append ("-march=i686")
758
759     if (env['VST']):
760         #
761         # everything must be 32 bit for VST (we're not replicating Cakewalk's hack, yet ...)
762         # 
763         opt_flags.extend(["-m32"])
764         debug_flags.extend(["-m32"])
765
766 # end of processor-specific section
767
768 # optimization section
769 if env['FPU_OPTIMIZATION']:
770     if env['DIST_TARGET'] == 'tiger' or env['DIST_TARGET'] == 'leopard':
771         opt_flags.append ("-DBUILD_VECLIB_OPTIMIZATIONS");
772         debug_flags.append ("-DBUILD_VECLIB_OPTIMIZATIONS");
773         libraries['core'].Append(LINKFLAGS= '-framework Accelerate')
774     elif env['DIST_TARGET'] == 'i686' or env['DIST_TARGET'] == 'x86_64':
775         opt_flags.append ("-DBUILD_SSE_OPTIMIZATIONS")
776         debug_flags.append ("-DBUILD_SSE_OPTIMIZATIONS")
777         if env['DIST_TARGET'] == 'x86_64' and not env['VST']:
778             opt_flags.append ("-DUSE_X86_64_ASM")
779             debug_flags.append ("-DUSE_X86_64_ASM")
780         if build_host_supports_sse != 1:
781             print "\nWarning: you are building Ardour with SSE support even though your system does not support these instructions. (This may not be anerror, especially if you are a package maintainer)"
782 # end optimization section
783
784 # handle x86/x86_64 libdir properly
785
786 if env['DIST_LIBDIR'] == '':
787     if env['DIST_TARGET'] == 'x86_64':
788         env['LIBDIR']='lib64'
789     else:
790         env['LIBDIR']='lib'
791 else:
792     env['LIBDIR'] = env['DIST_LIBDIR']
793
794 #
795 # no VST on x86_64
796 #
797
798 if env['DIST_TARGET'] == 'x86_64' and env['VST']:
799     print "\n\n=================================================="
800     print "You cannot use VST plugins with a 64 bit host. Please run scons with VST=0"
801     print "\nIt is theoretically possible to build a 32 bit host on a 64 bit system."
802     print "However, this is tricky and not recommended for beginners."
803     sys.exit (-1)
804
805 #
806 # a single way to test if we're on OS X
807 #
808
809 if env['DIST_TARGET'] in [ 'panther','tiger','leopard' ]:
810     env['IS_OSX'] = 1
811     # force tiger or later, to avoid issues on PPC which defaults
812     # back to 10.1 if we don't tell it otherwise.
813     env.Append (CCFLAGS="-DMAC_OS_X_VERSION_MIN_REQUIRED=1040")
814
815     #if env['DIST_TARGET'] == 'leopard':
816         # need this to really build against the 10.4 SDK when building on leopard
817         # ideally this would be configurable, but lets just do that later when we need it
818         #env.Append(CCFLAGS="-mmacosx-version-min=10.4 -isysroot /Developer/SDKs/MacOSX10.4u.sdk")
819         #env.Append(LINKFLAGS="-mmacosx-version-min=10.4 -isysroot /Developer/SDKs/MacOSX10.4u.sdk")
820
821 else:
822     env['IS_OSX'] = 0
823
824 #
825 # save off guessed arch element in an env
826 #
827 env.Append(CONFIG_ARCH=config[config_arch])
828
829
830 #
831 # ARCH="..." overrides all
832 #
833
834 if env['ARCH'] != '':
835     opt_flags = env['ARCH'].split()
836
837 #
838 # prepend boiler plate optimization flags
839 #
840
841 opt_flags[:0] = [
842     "-O3",
843     "-fomit-frame-pointer",
844     "-ffast-math",
845     "-fstrength-reduce",
846     "-pipe"
847     ]
848
849 if env['DEBUG'] == 1:
850     env.Append(CCFLAGS=" ".join (debug_flags))
851     env.Append(LINKFLAGS=" ".join (debug_flags))
852 else:
853     env.Append(CCFLAGS=" ".join (opt_flags))
854     env.Append(LINKFLAGS=" ".join (opt_flags))
855
856 if env['STL_DEBUG'] == 1:
857     env.Append(CXXFLAGS="-D_GLIBCXX_DEBUG")
858
859 if env['UNIVERSAL'] == 1:
860     env.Append(CCFLAGS="-arch i386 -arch ppc")
861     env.Append(LINKFLAGS="-arch i386 -arch ppc")
862
863
864 #
865 # warnings flags
866 #
867
868 env.Append(CCFLAGS="-Wall")
869 env.Append(CXXFLAGS="-Woverloaded-virtual")
870
871 if env['EXTRA_WARN']:
872     env.Append(CCFLAGS="-Wextra -pedantic -ansi")
873     env.Append(CXXFLAGS="-ansi")
874 #    env.Append(CFLAGS="-iso")
875
876 if env['LIBLO']:
877     env.Append(CCFLAGS="-DHAVE_LIBLO")
878
879
880 # It appears that SCons propagates CCFLAGS into CXXFLAGS so 
881 # we need only set these once.
882 #
883 # the program name is defined everywhere
884 #
885 env.Append(CCFLAGS='-DPROGRAM_NAME=\\"' + env['PROGRAM_NAME'] + '\\"')
886
887 #
888 # we deal with threads and big files
889 #
890 env.Append(CCFLAGS="-D_REENTRANT -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64")
891
892 #
893 # we use inttypes.h format macros anywhere we want
894 #
895 env.Append(CCFLAGS="-D__STDC_FORMAT_MACROS")
896
897 #
898 # fix scons nitpickiness on APPLE
899 #
900
901 def prep_libcheck(topenv, libinfo):
902     if os.path.exists (os.path.expanduser ('~/gtk/inst')):
903         #
904         # build-gtk-stack puts the GTK stack under ~/gtk/inst
905         # build-ardour-stack puts other Ardour deps under ~/a3/inst
906         #
907         # things need to build with this in mind
908         #
909         GTKROOT = os.path.expanduser ('~/gtk/inst')
910         libinfo.Append(CPPPATH= GTKROOT + "/include", LIBPATH= GTKROOT + "/lib")
911         libinfo.Append(CXXFLAGS="-I" + GTKROOT + "/include", LINKFLAGS="-L" + GTKROOT + "/lib")
912         ARDOURDEP_ROOT = os.path.expanduser ('~/a3/inst')
913         libinfo.Append(CPPPATH= ARDOURDEP_ROOT + "/include", LIBPATH= ARDOURDEP_ROOT + "/lib")
914         libinfo.Append(CXXFLAGS="-I" + ARDOURDEP_ROOT + "/include", LINKFLAGS="-L" + ARDOURDEP_ROOT + "/lib")
915             
916 prep_libcheck(env, env)
917
918
919 #
920 # these are part of the Ardour source tree because they are C++
921
922
923 libraries['vamp'] = LibraryInfo (LIBS='vampsdk',
924                                  LIBPATH='#libs/vamp-sdk',
925                                  CPPPATH='#libs/vamp-sdk')
926 libraries['vamphost'] = LibraryInfo (LIBS='vamphostsdk',
927                                  LIBPATH='#libs/vamp-sdk',
928                                  CPPPATH='#libs/vamp-sdk')
929
930 env['RUBBERBAND'] = False
931
932 conf = Configure (env)
933
934 if conf.CheckHeader ('fftw3.h'):
935     env['RUBBERBAND'] = True
936     libraries['rubberband'] = LibraryInfo (LIBS='rubberband',
937                                            LIBPATH='#libs/rubberband',
938                                            CPPPATH='#libs/rubberband',
939                                            CCFLAGS='-DUSE_RUBBERBAND')
940 else:
941     print ""
942     print "-------------------------------------------------------------------------"
943     print "You do not have the FFTW single-precision development package installed."
944     print "This prevents Ardour from using the Rubberband library for timestretching"
945     print "and pitchshifting. It will fall back on SoundTouch for timestretch, and "
946     print "pitchshifting will not be available."
947     print "-------------------------------------------------------------------------"
948     print ""
949
950 conf.Finish()
951
952 #
953 # Check for libusb
954
955 libraries['usb'] = LibraryInfo ()
956 prep_libcheck(env, libraries['usb'])
957
958 conf = Configure (libraries['usb'])
959 if conf.CheckLib ('usb', 'usb_interrupt_write'):
960     have_libusb = True
961 else:
962     have_libusb = False
963
964 # check for linux/input.h while we're at it for powermate
965 if conf.CheckHeader('linux/input.h'):
966     have_linux_input = True
967 else:
968     have_linux_input = False
969
970 libraries['usb'] = conf.Finish ()
971
972 #
973 # Check for wiimote dependencies
974
975 if env['WIIMOTE']:
976     wiimoteConf = env.Configure ( )
977     if not wiimoteConf.CheckHeader('cwiid.h'):
978         print 'WIIMOTE configured but you are missing libcwiid!'
979         sys.exit(1)
980     if not wiimoteConf.CheckHeader('bluetooth/bluetooth.h'):
981         print 'WIIMOTE configured but you are missing the libbluetooth headers which you need to compile wiimote support!'
982         sys.exit(1)
983     wiimoteConf.Finish()
984
985
986 #
987 # need a way to see if the installed version of libsndfile supports
988 # FLAC ....
989
990
991 # boost (we don't link against boost, just use some header files)
992
993 libraries['boost'] = LibraryInfo ()
994 prep_libcheck(env, libraries['boost'])
995 libraries['boost'].Append(CPPPATH="/usr/local/include", LIBPATH="/usr/local/lib")
996 conf = Configure (libraries['boost'])
997 if conf.CheckHeader ('boost/shared_ptr.hpp', language='CXX') == False:
998         print "Boost header files do not appear to be installed. You also might be running a buggy version of scons. Try scons 0.97 if you can."
999         sys.exit (1)
1000     
1001 libraries['boost'] = conf.Finish ()
1002
1003 #
1004 # Check for dmalloc
1005
1006 libraries['dmalloc'] = LibraryInfo ()
1007 prep_libcheck(env, libraries['dmalloc'])
1008
1009 #
1010 # look for the threaded version
1011 #
1012
1013 conf = Configure (libraries['dmalloc'])
1014 if conf.CheckLib ('dmallocth', 'dmalloc_shutdown'):
1015     have_libdmalloc = True
1016 else:
1017     have_libdmalloc = False
1018
1019 libraries['dmalloc'] = conf.Finish ()
1020
1021 #
1022 # ensure FREEDESKTOP target is doable..
1023 #
1024
1025 conf = env.Configure ()
1026 if env['FREEDESKTOP']:
1027         have_update_mime_database = conf.TryAction (Action ('update-mime-database -v'))
1028         if have_update_mime_database[0] != 1:
1029                 print "Warning. You have no update-mime-database command in your PATH. FREEDESKTOP is now disabled."
1030                 env['FREEDESKTOP'] = 0
1031         have_gtk_update_icon_cache = conf.TryAction (Action ('gtk-update-icon-cache -?'))
1032         if have_gtk_update_icon_cache[0] != 1:
1033                 print "Warning. You have no gtk-update-icon-cache command in your PATH. FREEDESKTOP is now disabled."
1034                 env['FREEDESKTOP'] = 0
1035         have_update_desktop_database = conf.TryAction (Action ('update-desktop-database -?'))
1036         if have_update_desktop_database[0] != 1:
1037                 print "Warning. You have no update-desktop-database command in your PATH. FREEDESKTOP is now disabled."
1038                 env['FREEDESKTOP'] = 0
1039 env = conf.Finish()
1040
1041 #
1042 # Audio/MIDI library (needed for MIDI, since audio is all handled via JACK)
1043 #
1044
1045 conf = Configure(env)
1046
1047 if conf.CheckCHeader('alsa/asoundlib.h'):
1048     libraries['sysmidi'] = LibraryInfo (LIBS='asound')
1049     env['SYSMIDI'] = 'ALSA Sequencer'
1050     subst_dict['%MIDITAG%'] = "seq"
1051     subst_dict['%MIDITYPE%'] = "alsa/sequencer"
1052 elif conf.CheckCHeader('/System/Library/Frameworks/CoreMIDI.framework/Headers/CoreMIDI.h'):
1053     # this line is needed because scons can't handle -framework in ParseConfig() yet.
1054     if env['GTKOSX']:
1055         # We need Carbon as well as the rest
1056         libraries['sysmidi'] = LibraryInfo (
1057                 LINKFLAGS = ' -framework CoreMIDI -framework CoreFoundation -framework CoreAudio -framework CoreServices -framework AudioUnit -framework AudioToolbox -framework Carbon -bind_at_load' )
1058     else:
1059         libraries['sysmidi'] = LibraryInfo (
1060                 LINKFLAGS = ' -framework CoreMIDI -framework CoreFoundation -framework CoreAudio -framework CoreServices -framework AudioUnit -framework AudioToolbox -bind_at_load' )
1061     env['SYSMIDI'] = 'CoreMIDI'
1062     subst_dict['%MIDITAG%'] = "ardour"
1063     subst_dict['%MIDITYPE%'] = "coremidi"
1064 else:
1065     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."
1066     sys.exit (1)
1067
1068 pname = env['PROGRAM_NAME']
1069 subst_dict['%MIDI_DEVICE_NAME%'] = pname.lower()
1070
1071 env = conf.Finish()
1072
1073 if env['GTKOSX']:
1074     clearlooks_version = 'libs/clearlooks-newer'
1075 else:
1076     clearlooks_version = 'libs/clearlooks-newer'
1077
1078 if env['SYSLIBS']:
1079
1080     syslibdeps = \
1081     {
1082         'sigc++-2.0'           : '2.0',
1083         'gtkmm-2.4'            : '2.8',
1084         'libgnomecanvasmm-2.6' : '2.12.0'
1085     }
1086
1087     conf = Configure(env, custom_tests = { 'CheckPKGConfig' : CheckPKGConfig,
1088                     'CheckPKGVersion' : CheckPKGVersion })
1089
1090     for pkg, version in syslibdeps.iteritems():
1091         if not conf.CheckPKGVersion( pkg, version ):
1092             print '%s >= %s not found.' %(pkg, version)
1093             DependenciesRequiredMessage()
1094             Exit(1)
1095     
1096     env = conf.Finish()
1097     
1098     libraries['sigc2'] = LibraryInfo()
1099     libraries['sigc2'].ParseConfig('pkg-config --cflags --libs sigc++-2.0')
1100     libraries['glibmm2'] = LibraryInfo()
1101     libraries['glibmm2'].ParseConfig('pkg-config --cflags --libs glibmm-2.4')
1102     libraries['cairomm'] = LibraryInfo()
1103     libraries['cairomm'].ParseConfig('pkg-config --cflags --libs cairomm-1.0')
1104     libraries['gdkmm2'] = LibraryInfo()
1105     libraries['gdkmm2'].ParseConfig ('pkg-config --cflags --libs gdkmm-2.4')
1106     libraries['gtkmm2'] = LibraryInfo()
1107     libraries['gtkmm2'].ParseConfig ('pkg-config --cflags --libs gtkmm-2.4')
1108     libraries['atkmm'] = LibraryInfo()
1109     libraries['atkmm'].ParseConfig ('pkg-config --cflags --libs atkmm-1.6')
1110     libraries['pangomm'] = LibraryInfo()
1111     libraries['pangomm'].ParseConfig ('pkg-config --cflags --libs pangomm-1.4')
1112     libraries['libgnomecanvasmm'] = LibraryInfo()
1113     libraries['libgnomecanvasmm'].ParseConfig ('pkg-config --cflags --libs libgnomecanvasmm-2.6')
1114
1115 #    libraries['libglademm'] = LibraryInfo()
1116 #    libraries['libglademm'].ParseConfig ('pkg-config --cflags --libs libglademm-2.4')
1117
1118 #    libraries['flowcanvas'] = LibraryInfo(LIBS='flowcanvas', LIBPATH='#/libs/flowcanvas', CPPPATH='#libs/flowcanvas')
1119
1120     libraries['appleutility'] = LibraryInfo(LIBS='libappleutility',
1121                                             LIBPATH='#libs/appleutility',
1122                                             CPPPATH='#libs/appleutility')
1123     
1124     coredirs = [
1125         'templates',
1126         'manual'
1127     ]
1128     
1129     subdirs = [
1130         'libs/pbd',
1131         'libs/midi++2',
1132         'libs/ardour',
1133         'libs/vamp-sdk',
1134         'libs/vamp-plugins/',
1135     # these are unconditionally included but have
1136     # tests internally to avoid compilation etc
1137     # if VST is not set
1138         'libs/fst',
1139         'vst',
1140     # this is unconditionally included but has
1141     # tests internally to avoid compilation etc
1142     # if COREAUDIO is not set
1143         'libs/appleutility'
1144         ]
1145     
1146     gtk_subdirs = [
1147 #        'libs/flowcanvas',
1148         'libs/gtkmm2ext',
1149         'gtk2_ardour',
1150         clearlooks_version
1151         ]
1152
1153 else:
1154     libraries['sigc2'] = LibraryInfo(LIBS='sigc++2',
1155                                     LIBPATH='#libs/sigc++2',
1156                                     CPPPATH='#libs/sigc++2')
1157     libraries['glibmm2'] = LibraryInfo(LIBS='glibmm2',
1158                                     LIBPATH='#libs/glibmm2',
1159                                     CPPPATH='#libs/glibmm2')
1160     libraries['pangomm'] = LibraryInfo(LIBS='pangomm',
1161                                     LIBPATH='#libs/gtkmm2/pango',
1162                                     CPPPATH='#libs/gtkmm2/pango')
1163     libraries['cairomm'] = LibraryInfo(LIBS='cairomm',
1164                                     LIBPATH='#libs/cairomm',
1165                                     CPPPATH='#libs/cairomm')
1166     libraries['atkmm'] = LibraryInfo(LIBS='atkmm',
1167                                      LIBPATH='#libs/gtkmm2/atk',
1168                                      CPPPATH='#libs/gtkmm2/atk')
1169     libraries['gdkmm2'] = LibraryInfo(LIBS='gdkmm2',
1170                                       LIBPATH='#libs/gtkmm2/gdk',
1171                                       CPPPATH='#libs/gtkmm2/gdk')
1172     libraries['gtkmm2'] = LibraryInfo(LIBS='gtkmm2',
1173                                      LIBPATH="#libs/gtkmm2/gtk",
1174                                      CPPPATH='#libs/gtkmm2/gtk/')
1175     libraries['libgnomecanvasmm'] = LibraryInfo(LIBS='libgnomecanvasmm',
1176                                                 LIBPATH='#libs/libgnomecanvasmm',
1177                                                 CPPPATH='#libs/libgnomecanvasmm')
1178     
1179 #    libraries['libglademm'] = LibraryInfo(LIBS='libglademm',
1180 #                                          LIBPATH='#libs/libglademm',
1181 #                                          CPPPATH='#libs/libglademm')
1182     libraries['appleutility'] = LibraryInfo(LIBS='libappleutility',
1183                                             LIBPATH='#libs/appleutility',
1184                                             CPPPATH='#libs/appleutility')
1185
1186     coredirs = [
1187         'templates',
1188         'manual'
1189     ]
1190     
1191     subdirs = [
1192         'libs/sigc++2',
1193         'libs/pbd',
1194         'libs/midi++2',
1195         'libs/ardour',
1196         'libs/vamp-sdk',
1197         'libs/vamp-plugins/',
1198     # these are unconditionally included but have
1199     # tests internally to avoid compilation etc
1200     # if VST is not set
1201         'libs/fst',
1202         'vst',
1203     # this is unconditionally included but has
1204     # tests internally to avoid compilation etc
1205     # if COREAUDIO is not set
1206         'libs/appleutility'
1207         ]
1208     
1209     gtk_subdirs = [
1210         'libs/glibmm2',
1211         'libs/gtkmm2/pango',
1212         'libs/gtkmm2/atk',
1213         'libs/gtkmm2/gdk',
1214         'libs/gtkmm2/gtk',
1215         'libs/libgnomecanvasmm',
1216         'libs/gtkmm2ext',
1217         'gtk2_ardour',
1218         clearlooks_version
1219         ]
1220
1221 #
1222 # * always build the LGPL control protocol lib, since we link against it from libardour
1223 # * ditto for generic MIDI
1224 # * tranzport & wiimote check whether they should build internally, but we need them here
1225 #   so that they are included in the tarball
1226 #
1227
1228 surface_subdirs = [ 'libs/surfaces/control_protocol',
1229                     'libs/surfaces/generic_midi',
1230                     'libs/surfaces/tranzport',
1231                     'libs/surfaces/mackie',
1232                     'libs/surfaces/powermate',
1233                     'libs/surfaces/wiimote'
1234                     ]
1235
1236 if env['SURFACES']:
1237     if have_libusb:
1238         env['TRANZPORT'] = 1
1239     else:
1240         env['TRANZPORT'] = 0
1241         print 'Disabled building Tranzport code because libusb could not be found'
1242
1243     if have_linux_input:
1244         env['POWERMATE'] = 1
1245     else:
1246         env['POWERMATE'] = 0
1247         print 'Disabled building Powermate code because linux/input.h could not be found'
1248
1249     if os.access ('libs/surfaces/sony9pin', os.F_OK):
1250         surface_subdirs += [ 'libs/surfaces/sony9pin' ]
1251 else:
1252     env['POWERMATE'] = 0
1253     env['TRANZPORT'] = 0
1254
1255 #
1256 # timestretch libraries
1257 #
1258
1259 timefx_subdirs = []
1260 if env['RUBBERBAND']:
1261     timefx_subdirs += ['libs/rubberband']
1262
1263 #
1264 # Tools
1265 #
1266 if env['IS_OSX'] == 0 :
1267         tools_subdirs = [ 'tools/sanity_check' ]
1268 else:
1269         tools_subdirs = [ ]
1270
1271
1272 opts.Save('scache.conf', env)
1273 Help(opts.GenerateHelpText(env))
1274
1275 final_prefix = '$PREFIX'
1276
1277 if env['DESTDIR'] :
1278     install_prefix = '$DESTDIR/$PREFIX'
1279 else:
1280     install_prefix = env['PREFIX']
1281
1282 subst_dict['%INSTALL_PREFIX%'] = install_prefix;
1283 subst_dict['%FINAL_PREFIX%'] = final_prefix;
1284 subst_dict['%PREFIX%'] = final_prefix;
1285
1286 if env['PREFIX'] == '/usr':
1287     final_config_prefix = '/etc'
1288 else:
1289     final_config_prefix = env['PREFIX'] + '/etc'
1290
1291 config_prefix = '$DESTDIR' + final_config_prefix
1292
1293 #
1294 # everybody needs this
1295 #
1296
1297 env.Merge ([ libraries['core'] ])
1298
1299
1300 #
1301 # i18n support
1302 #
1303
1304 conf = Configure (env)
1305 if env['NLS']:
1306     nls_error = 'This system is not configured for internationalized applications.  An english-only version will be built:'
1307     print 'Checking for internationalization support ...'
1308     have_gettext = conf.TryAction(Action('xgettext --version'))
1309     if have_gettext[0] != 1:
1310         nls_error += ' No xgettext command.'
1311         env['NLS'] = 0
1312     else:
1313         print "Found xgettext"
1314     
1315     have_msgmerge = conf.TryAction(Action('msgmerge --version'))
1316     if have_msgmerge[0] != 1:
1317         nls_error += ' No msgmerge command.'
1318         env['NLS'] = 0
1319     else:
1320         print "Found msgmerge"
1321     
1322     if not conf.CheckCHeader('libintl.h'):
1323         nls_error += ' No libintl.h.'
1324         env['NLS'] = 0
1325         
1326     if env['NLS'] == 0:
1327         print nls_error
1328     else:
1329         if config[config_arch] == 'apple':
1330            libraries['intl'] = LibraryInfo (LIBS='intl')
1331         else:
1332            libraries['intl'] = LibraryInfo ()
1333         print "International version will be built."
1334
1335 env = conf.Finish()
1336
1337 if env['NLS'] == 1:
1338     env.Append(CCFLAGS="-DENABLE_NLS")
1339
1340 Export('env install_prefix final_prefix config_prefix final_config_prefix libraries i18n ardour_version subst_dict')
1341
1342 #
1343 # the configuration file may be system dependent
1344 #
1345
1346 conf = env.Configure ()
1347
1348 if conf.CheckCHeader('/System/Library/Frameworks/CoreAudio.framework/Versions/A/Headers/CoreAudio.h'):
1349     subst_dict['%JACK_INPUT%'] = "coreaudio:Built-in Audio:in"
1350     subst_dict['%JACK_OUTPUT%'] = "coreaudio:Built-in Audio:out"
1351 else:
1352     subst_dict['%JACK_INPUT%'] = "alsa_pcm:playback_"
1353     subst_dict['%JACK_OUTPUT%'] = "alsa_pcm:capture_"
1354
1355 # posix_memalign available
1356 if not conf.CheckFunc('posix_memalign'):
1357     print 'Did not find posix_memalign(), using malloc'
1358     env.Append(CCFLAGS='-DNO_POSIX_MEMALIGN')
1359
1360
1361 env = conf.Finish()
1362
1363 # Which GTK tooltips API
1364
1365 gtktestenv = env.Clone ()
1366 gtktestenv.Merge ([
1367         libraries['gtk2']
1368         ])
1369
1370 conf = gtktestenv.Configure ()
1371
1372 if conf.CheckFunc('gtk_widget_set_tooltip_text'):
1373     env.Append (CXXFLAGS='-DGTK_NEW_TOOLTIP_API')
1374
1375 conf.Finish ()
1376
1377
1378 # generate the per-user and system rc files from the same source
1379
1380 sysrcbuild = env.SubstInFile ('ardour_system.rc','ardour.rc.in', SUBST_DICT = subst_dict)
1381
1382 # add to the substitution dictionary
1383
1384 subst_dict['%VERSION%'] = ardour_version[0:3]
1385 subst_dict['%EXTRA_VERSION%'] = ardour_version[3:]
1386 subst_dict['%REVISION_STRING%'] = ''
1387 if os.path.exists('.svn'):
1388     subst_dict['%REVISION_STRING%'] = '.' + fetch_svn_revision ('.') + 'svn'
1389
1390 # specbuild = env.SubstInFile ('ardour.spec','ardour.spec.in', SUBST_DICT = subst_dict)
1391
1392 the_revision = env.Command ('frobnicatory_decoy', [], create_stored_revision)
1393 remove_ardour = env.Command ('frobnicatory_decoy2', [],
1394                              [ Delete ('$PREFIX/etc/ardour2'),
1395                                Delete ('$PREFIX/lib/ardour2'),
1396                                Delete ('$PREFIX/bin/ardour2'),
1397                                Delete ('$PREFIX/share/ardour2')])
1398
1399 env.Alias('revision', the_revision)
1400 env.Alias('install', env.Install(os.path.join(config_prefix, 'ardour2'), 'ardour_system.rc'))
1401 env.Alias('uninstall', remove_ardour)
1402
1403 Default (sysrcbuild)
1404
1405 # source tarball
1406
1407 Precious (env['DISTTREE'])
1408
1409 env.Distribute (env['DISTTREE'],
1410                [ 'SConstruct', 
1411                   'COPYING', 'PACKAGER_README', 'README',
1412                   'ardour.rc.in',
1413                   'tools/config.guess',
1414                   'icons/icon/ardour_icon_mac_mask.png',
1415                   'icons/icon/ardour_icon_mac.png',
1416                   'icons/icon/ardour_icon_tango_16px_blue.png',
1417                   'icons/icon/ardour_icon_tango_16px_red.png',
1418                   'icons/icon/ardour_icon_tango_22px_blue.png',
1419                   'icons/icon/ardour_icon_tango_22px_red.png',
1420                   'icons/icon/ardour_icon_tango_32px_blue.png',
1421                   'icons/icon/ardour_icon_tango_32px_red.png',
1422                   'icons/icon/ardour_icon_tango_48px_blue.png',
1423                   'icons/icon/ardour_icon_tango_48px_red.png'
1424                   ] +
1425                 glob.glob ('ardour.1*') +
1426                 glob.glob ('libs/clearlooks-newer/*.c') +
1427                 glob.glob ('libs/clearlooks-newer/*.h') +
1428                 glob.glob ('libs/clearlooks-newer/SConscript')
1429                 )
1430
1431 srcdist = env.Tarball(env['TARBALL'], [ env['DISTTREE'], the_revision ])
1432 env.Alias ('srctar', srcdist)
1433
1434 #
1435 # don't leave the distree around
1436 #
1437
1438 env.AddPreAction (env['DISTTREE'], Action ('rm -rf ' + str (File (env['DISTTREE']))))
1439 env.AddPostAction (srcdist, Action ('rm -rf ' + str (File (env['DISTTREE']))))
1440
1441 #
1442 # Update revision info before going into subdirs
1443 #
1444
1445 create_stored_revision()
1446
1447 #
1448 # the subdirs
1449 #
1450
1451 for subdir in coredirs:
1452     SConscript (subdir + '/SConscript')
1453
1454 for sublistdir in [ subdirs, timefx_subdirs, gtk_subdirs, surface_subdirs, tools_subdirs ]:
1455     for subdir in sublistdir:
1456         SConscript (subdir + '/SConscript')
1457
1458 # cleanup
1459 env.Clean ('scrub', [ 'scache.conf', '.sconf_temp', '.sconsign.dblite', 'config.log'])
1460