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