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