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