disable (s)LV2 by default until its released
[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.4'
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)', 0),
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 env = conf.Finish ()
523
524 if env['FFT_ANALYSIS']:
525         #
526         # Check for fftw3 header as well as the library
527         #
528
529         conf = Configure(libraries['fftw3'])
530
531         if conf.CheckHeader ('fftw3.h') == False:
532             print ('Ardour cannot be compiled without the FFTW3 headers, which do not seem to be installed')
533             sys.exit (1)            
534         conf.Finish()
535
536 if env['FREESOUND']:
537         #
538         # Check for curl header as well as the library
539         #
540
541         libraries['curl'] = LibraryInfo()
542
543         conf = Configure(libraries['curl'])
544
545         if conf.CheckHeader ('curl/curl.h') == False:
546                 print ('Ardour cannot be compiled without the curl headers, which do not seem to be installed')
547                 sys.exit (1)            
548         else:
549                 libraries['curl'].ParseConfig('pkg-config --cflags --libs libcurl')
550         conf.Finish()
551 else:
552         print 'FREESOUND support is not enabled.  Build with \'scons FREESOUND=1\' to enable.'
553
554 if env['LV2']:
555         conf = env.Configure(custom_tests = { 'CheckPKGExists' : CheckPKGExists })
556         
557         if conf.CheckPKGExists ('\"slv2 >= 0.6.0\"'):
558                 libraries['slv2'] = LibraryInfo()
559                 libraries['slv2'].ParseConfig('pkg-config --cflags --libs slv2')
560                 env.Append (CCFLAGS="-DHAVE_LV2")
561         else:
562                 print 'Building Ardour with LV2 support requires SLV2 >= 0.6.0'
563                 print 'WARNING: SLV2 not found, or too old.  Ardour will be built without LV2 support.'
564                 print 'Until the 2.4 release, Ardour requires SLV2 out of SVN.'
565                 print 'Testing would be very much appreciated!  svn co http://svn.drobilla.net/lad/slv2'
566                 env['LV2'] = 0
567         conf.Finish()
568 else:
569         print 'LV2 support is not enabled.  Build with \'scons LV2=1\' to enable.'
570
571 libraries['jack'] = LibraryInfo()
572 libraries['jack'].ParseConfig('pkg-config --cflags --libs jack')
573
574 libraries['xml'] = LibraryInfo()
575 libraries['xml'].ParseConfig('pkg-config --cflags --libs libxml-2.0')
576
577 libraries['xslt'] = LibraryInfo()
578 libraries['xslt'].ParseConfig('pkg-config --cflags --libs libxslt')
579
580 libraries['glib2'] = LibraryInfo()
581 libraries['glib2'].ParseConfig ('pkg-config --cflags --libs glib-2.0')
582 libraries['glib2'].ParseConfig ('pkg-config --cflags --libs gobject-2.0')
583 libraries['glib2'].ParseConfig ('pkg-config --cflags --libs gmodule-2.0')
584 libraries['glib2'].ParseConfig ('pkg-config --cflags --libs gthread-2.0')
585
586 libraries['freetype2'] = LibraryInfo()
587 libraries['freetype2'].ParseConfig ('pkg-config --cflags --libs freetype2')
588
589 libraries['gtk2'] = LibraryInfo()
590 libraries['gtk2'].ParseConfig ('pkg-config --cflags --libs gtk+-2.0')
591
592 libraries['pango'] = LibraryInfo()
593 libraries['pango'].ParseConfig ('pkg-config --cflags --libs pango')
594
595 libraries['libgnomecanvas2'] = LibraryInfo()
596 libraries['libgnomecanvas2'].ParseConfig ('pkg-config --cflags --libs libgnomecanvas-2.0')
597
598 #libraries['flowcanvas'] = LibraryInfo(LIBS='flowcanvas', LIBPATH='#/libs/flowcanvas', CPPPATH='#libs/flowcanvas')
599
600 # The Ardour Control Protocol Library
601
602 libraries['ardour_cp'] = LibraryInfo (LIBS='ardour_cp', LIBPATH='#libs/surfaces/control_protocol',
603                                       CPPPATH='#libs/surfaces/control_protocol')
604
605 # The Ardour backend/engine
606
607 libraries['ardour'] = LibraryInfo (LIBS='ardour', LIBPATH='#libs/ardour', CPPPATH='#libs/ardour')
608 libraries['midi++2'] = LibraryInfo (LIBS='midi++', LIBPATH='#libs/midi++2', CPPPATH='#libs/midi++2')
609 libraries['pbd']    = LibraryInfo (LIBS='pbd', LIBPATH='#libs/pbd', CPPPATH='#libs/pbd')
610 libraries['gtkmm2ext'] = LibraryInfo (LIBS='gtkmm2ext', LIBPATH='#libs/gtkmm2ext', CPPPATH='#libs/gtkmm2ext')
611
612
613 # SCons should really do this for us
614
615 conf = env.Configure ()
616
617 have_cxx = conf.TryAction (Action (str(env['CXX']) + ' --version'))
618 if have_cxx[0] != 1:
619     print "This system has no functional C++ compiler. You cannot build Ardour from source without one."
620     sys.exit (1)
621 else:
622     print "Congratulations, you have a functioning C++ compiler."
623
624 env = conf.Finish()
625
626
627 #
628 # Compiler flags and other system-dependent stuff
629 #
630
631 opt_flags = []
632 if env['GPROFILE'] == 1:
633     debug_flags = [ '-g', '-pg' ]
634 else:
635     debug_flags = [ '-g' ]
636
637 # guess at the platform, used to define compiler flags
638
639 config_guess = os.popen("tools/config.guess").read()[:-1]
640
641 config_cpu = 0
642 config_arch = 1
643 config_kernel = 2
644 config_os = 3
645 config = config_guess.split ("-")
646
647 print "system triple: " + config_guess
648
649 # Autodetect
650 if env['DIST_TARGET'] == 'auto':
651     if config[config_arch] == 'apple':
652         # The [.] matches to the dot after the major version, "." would match any character
653         if re.search ("darwin[0-7][.]", config[config_kernel]) != None:
654             env['DIST_TARGET'] = 'panther'
655         if re.search ("darwin8[.]", config[config_kernel]) != None:
656             env['DIST_TARGET'] = 'tiger'
657         else:
658             env['DIST_TARGET'] = 'leopard'
659     else:
660         if re.search ("x86_64", config[config_cpu]) != None:
661             env['DIST_TARGET'] = 'x86_64'
662         elif re.search("i[0-5]86", config[config_cpu]) != None:
663             env['DIST_TARGET'] = 'i386'
664         elif re.search("powerpc", config[config_cpu]) != None:
665             env['DIST_TARGET'] = 'powerpc'
666         else:
667             env['DIST_TARGET'] = 'i686'
668     print "\n*******************************"
669     print "detected DIST_TARGET = " + env['DIST_TARGET']
670     print "*******************************\n"
671
672
673 if config[config_cpu] == 'powerpc' and env['DIST_TARGET'] != 'none':
674     #
675     # Apple/PowerPC optimization options
676     #
677     # -mcpu=7450 does not reliably work with gcc 3.*
678     #
679     if env['DIST_TARGET'] == 'panther' or env['DIST_TARGET'] == 'tiger':
680         if config[config_arch] == 'apple':
681             ## opt_flags.extend ([ "-mcpu=7450", "-faltivec"])
682             # to support g3s but still have some optimization for above
683             opt_flags.extend ([ "-mcpu=G3", "-mtune=7450"])
684         else:
685             opt_flags.extend ([ "-mcpu=7400", "-maltivec", "-mabi=altivec"])
686     else:
687         opt_flags.extend([ "-mcpu=750", "-mmultiple" ])
688     opt_flags.extend (["-mhard-float", "-mpowerpc-gfxopt"])
689     opt_flags.extend (["-Os"])
690
691 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':
692     
693     build_host_supports_sse = 0
694     
695     debug_flags.append ("-DARCH_X86")
696     opt_flags.append ("-DARCH_X86")
697     
698     if config[config_kernel] == 'linux' :
699         
700         if env['DIST_TARGET'] != 'i386':
701             
702             flag_line = os.popen ("cat /proc/cpuinfo | grep '^flags'").read()[:-1]
703             x86_flags = flag_line.split (": ")[1:][0].split ()
704             
705             if "mmx" in x86_flags:
706                 opt_flags.append ("-mmmx")
707             if "sse" in x86_flags:
708                 build_host_supports_sse = 1
709             if "3dnow" in x86_flags:
710                 opt_flags.append ("-m3dnow")
711             
712             if config[config_cpu] == "i586":
713                 opt_flags.append ("-march=i586")
714             elif config[config_cpu] == "i686":
715                 opt_flags.append ("-march=i686")
716     
717     if ((env['DIST_TARGET'] == 'i686') or (env['DIST_TARGET'] == 'x86_64')) and build_host_supports_sse:
718         opt_flags.extend (["-msse", "-mfpmath=sse", "-DUSE_XMMINTRIN"])
719         debug_flags.extend (["-msse", "-mfpmath=sse", "-DUSE_XMMINTRIN"])
720 # end of processor-specific section
721
722 # optimization section
723 if env['FPU_OPTIMIZATION']:
724     if env['DIST_TARGET'] == 'tiger' or env['DIST_TARGET'] == 'leopard':
725         opt_flags.append ("-DBUILD_VECLIB_OPTIMIZATIONS");
726         debug_flags.append ("-DBUILD_VECLIB_OPTIMIZATIONS");
727         libraries['core'].Append(LINKFLAGS= '-framework Accelerate')
728     elif env['DIST_TARGET'] == 'i686' or env['DIST_TARGET'] == 'x86_64':
729         opt_flags.append ("-DBUILD_SSE_OPTIMIZATIONS")
730         debug_flags.append ("-DBUILD_SSE_OPTIMIZATIONS")
731         if env['DIST_TARGET'] == 'x86_64':
732             opt_flags.append ("-DUSE_X86_64_ASM")
733             debug_flags.append ("-DUSE_X86_64_ASM")
734         if build_host_supports_sse != 1:
735             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)"
736 # end optimization section
737
738 # handle x86/x86_64 libdir properly
739
740 if env['DIST_TARGET'] == 'x86_64':
741     env['LIBDIR']='lib64'
742 else:
743     env['LIBDIR']='lib'
744
745 #
746 # a single way to test if we're on OS X
747 #
748
749 if env['DIST_TARGET'] in ['panther', 'tiger', 'leopard' ]:
750     env['IS_OSX'] = 1
751     # force tiger or later, to avoid issues on PPC which defaults
752     # back to 10.1 if we don't tell it otherwise.
753     env.Append (CCFLAGS="-DMAC_OS_X_VERSION_MIN_REQUIRED=1040")
754 else:
755     env['IS_OSX'] = 0
756
757 #
758 # save off guessed arch element in an env
759 #
760 env.Append(CONFIG_ARCH=config[config_arch])
761
762
763 #
764 # ARCH="..." overrides all
765 #
766
767 if env['ARCH'] != '':
768     opt_flags = env['ARCH'].split()
769
770 #
771 # prepend boiler plate optimization flags
772 #
773
774 opt_flags[:0] = [
775     "-O3",
776     "-fomit-frame-pointer",
777     "-ffast-math",
778     "-fstrength-reduce",
779     "-pipe"
780     ]
781
782 if env['DEBUG'] == 1:
783     env.Append(CCFLAGS=" ".join (debug_flags))
784     env.Append(LINKFLAGS=" ".join (debug_flags))
785 else:
786     env.Append(CCFLAGS=" ".join (opt_flags))
787     env.Append(LINKFLAGS=" ".join (opt_flags))
788
789 if env['STL_DEBUG'] == 1:
790     env.Append(CXXFLAGS="-D_GLIBCXX_DEBUG")
791
792 if env['UNIVERSAL'] == 1:
793     env.Append(CCFLAGS="-arch i386 -arch ppc")
794     env.Append(LINKFLAGS="-arch i386 -arch ppc")
795
796
797 #
798 # warnings flags
799 #
800
801 env.Append(CCFLAGS="-Wall")
802 env.Append(CXXFLAGS="-Woverloaded-virtual")
803
804 if env['EXTRA_WARN']:
805     env.Append(CCFLAGS="-Wextra -pedantic -ansi")
806     env.Append(CXXFLAGS="-ansi")
807 #    env.Append(CFLAGS="-iso")
808
809 if env['LIBLO']:
810     env.Append(CCFLAGS="-DHAVE_LIBLO")
811
812
813 #
814 # fix scons nitpickiness on APPLE
815 #
816
817
818 def prep_libcheck(topenv, libinfo):
819     if topenv['IS_OSX']:
820         #
821         # rationale: GTK-Quartz uses jhbuild and installs to /opt/gtk by default.
822         #            All libraries needed should be built against this location
823         if topenv['GTKOSX']:
824                 libinfo.Append(CPPPATH="/opt/gtk/include", LIBPATH="/opt/gtk/lib")
825                 libinfo.Append(CXXFLAGS="-I/opt/gtk/include", LINKFLAGS="-L/opt/gtk/lib")
826         libinfo.Append(CPPPATH="/opt/local/include", LIBPATH="/opt/local/lib")
827         libinfo.Append(CXXFLAGS="-I/opt/local/include", LINKFLAGS="-L/opt/local/lib")
828
829 prep_libcheck(env, env)
830
831
832 #
833 # these are part of the Ardour source tree because they are C++
834
835
836 libraries['vamp'] = LibraryInfo (LIBS='vampsdk',
837                                  LIBPATH='#libs/vamp-sdk',
838                                  CPPPATH='#libs/vamp-sdk')
839 libraries['vamphost'] = LibraryInfo (LIBS='vamphostsdk',
840                                  LIBPATH='#libs/vamp-sdk',
841                                  CPPPATH='#libs/vamp-sdk')
842
843 env['RUBBERBAND'] = False
844
845 conf = Configure (env)
846
847 if conf.CheckHeader ('fftw3.h'):
848     env['RUBBERBAND'] = True
849     libraries['rubberband'] = LibraryInfo (LIBS='rubberband',
850                                            LIBPATH='#libs/rubberband',
851                                            CPPPATH='#libs/rubberband',
852                                            CCFLAGS='-DUSE_RUBBERBAND')
853 else:
854     print ""
855     print "-------------------------------------------------------------------------"
856     print "You do not have the FFTW single-precision development package installed."
857     print "This prevents Ardour from using the Rubberband library for timestretching"
858     print "and pitchshifting. It will fall back on SoundTouch for timestretch, and "
859     print "pitchshifting will not be available."
860     print "-------------------------------------------------------------------------"
861     print ""
862
863 conf.Finish()
864
865 #
866 # Check for libusb
867
868 libraries['usb'] = LibraryInfo ()
869 prep_libcheck(env, libraries['usb'])
870
871 conf = Configure (libraries['usb'])
872 if conf.CheckLib ('usb', 'usb_interrupt_write'):
873     have_libusb = True
874 else:
875     have_libusb = False
876
877 # check for linux/input.h while we're at it for powermate
878 if conf.CheckHeader('linux/input.h'):
879     have_linux_input = True
880 else:
881     have_linux_input = False
882
883 libraries['usb'] = conf.Finish ()
884
885 #
886 # Check for FLAC
887
888 libraries['flac'] = LibraryInfo ()
889 prep_libcheck(env, libraries['flac'])
890 libraries['flac'].Append(CPPPATH="/usr/local/include", LIBPATH="/usr/local/lib")
891
892 #
893 # june 1st 2007: look for a function that is in FLAC 1.1.2 and not in later versions
894 #                since the version of libsndfile we have internally does not support
895 #                the new API that libFLAC has adopted
896 #
897
898 conf = Configure (libraries['flac'])
899 if conf.CheckLib ('FLAC', 'FLAC__seekable_stream_decoder_init', language='CXX'):
900     conf.env.Append(CCFLAGS='-DHAVE_FLAC')
901     use_flac = True
902 else:
903     use_flac = False
904     
905 libraries['flac'] = conf.Finish ()
906
907 # or if that fails...
908 #libraries['flac']    = LibraryInfo (LIBS='FLAC')
909
910 # boost (we don't link against boost, just use some header files)
911
912 libraries['boost'] = LibraryInfo ()
913 prep_libcheck(env, libraries['boost'])
914 libraries['boost'].Append(CPPPATH="/usr/local/include", LIBPATH="/usr/local/lib")
915 conf = Configure (libraries['boost'])
916 if conf.CheckHeader ('boost/shared_ptr.hpp', language='CXX') == False:
917         print "Boost header files do not appear to be installed."
918         sys.exit (1)
919     
920 libraries['boost'] = conf.Finish ()
921
922 #
923 # Check for liblo
924
925 if env['LIBLO']:
926     libraries['lo'] = LibraryInfo ()
927     prep_libcheck(env, libraries['lo'])
928
929     conf = Configure (libraries['lo'])
930     if conf.CheckLib ('lo', 'lo_server_new') == False:
931         print "liblo does not appear to be installed."
932         sys.exit (1)
933     
934     libraries['lo'] = conf.Finish ()
935
936 #
937 # Check for dmalloc
938
939 libraries['dmalloc'] = LibraryInfo ()
940 prep_libcheck(env, libraries['dmalloc'])
941
942 #
943 # look for the threaded version
944 #
945
946 conf = Configure (libraries['dmalloc'])
947 if conf.CheckLib ('dmallocth', 'dmalloc_shutdown'):
948     have_libdmalloc = True
949 else:
950     have_libdmalloc = False
951
952 libraries['dmalloc'] = conf.Finish ()
953
954 #
955 # ensure FREEDESKTOP target is doable..
956 #
957
958 conf = env.Configure ()
959 if env['FREEDESKTOP']:
960         have_update_mime_database = conf.TryAction (Action ('update-mime-database -v'))
961         if have_update_mime_database[0] != 1:
962                 print "Warning. You have no update-mime-database command in your PATH. FREEDESKTOP is now disabled."
963                 env['FREEDESKTOP'] = 0
964         have_gtk_update_icon_cache = conf.TryAction (Action ('gtk-update-icon-cache -?'))
965         if have_gtk_update_icon_cache[0] != 1:
966                 print "Warning. You have no gtk-update-icon-cache command in your PATH. FREEDESKTOP is now disabled."
967                 env['FREEDESKTOP'] = 0
968         have_update_desktop_database = conf.TryAction (Action ('update-desktop-database -?'))
969         if have_update_desktop_database[0] != 1:
970                 print "Warning. You have no update-desktop-database command in your PATH. FREEDESKTOP is now disabled."
971                 env['FREEDESKTOP'] = 0
972 env = conf.Finish()
973
974 #
975 # Audio/MIDI library (needed for MIDI, since audio is all handled via JACK)
976 #
977
978 conf = Configure(env)
979
980 if conf.CheckCHeader('alsa/asoundlib.h'):
981     libraries['sysmidi'] = LibraryInfo (LIBS='asound')
982     env['SYSMIDI'] = 'ALSA Sequencer'
983     subst_dict['%MIDITAG%'] = "seq"
984     subst_dict['%MIDITYPE%'] = "alsa/sequencer"
985 elif conf.CheckCHeader('/System/Library/Frameworks/CoreMIDI.framework/Headers/CoreMIDI.h'):
986     # this line is needed because scons can't handle -framework in ParseConfig() yet.
987     if env['GTKOSX']:
988         # We need Carbon as well as the rest
989         libraries['sysmidi'] = LibraryInfo (
990                 LINKFLAGS = ' -framework CoreMIDI -framework CoreFoundation -framework CoreAudio -framework CoreServices -framework AudioUnit -framework AudioToolbox -framework Carbon -bind_at_load' )
991     else:
992         libraries['sysmidi'] = LibraryInfo (
993                 LINKFLAGS = ' -framework CoreMIDI -framework CoreFoundation -framework CoreAudio -framework CoreServices -framework AudioUnit -framework AudioToolbox -bind_at_load' )
994     env['SYSMIDI'] = 'CoreMIDI'
995     subst_dict['%MIDITAG%'] = "ardour"
996     subst_dict['%MIDITYPE%'] = "coremidi"
997 else:
998     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."
999     sys.exit (1)
1000
1001 env = conf.Finish()
1002
1003 if env['SYSLIBS']:
1004
1005     syslibdeps = \
1006     {
1007         'sigc++-2.0'           : '2.0',
1008         'gtkmm-2.4'            : '2.8',
1009         'libgnomecanvasmm-2.6' : '2.12.0'
1010     }
1011
1012     conf = Configure(env, custom_tests = { 'CheckPKGConfig' : CheckPKGConfig,
1013                     'CheckPKGVersion' : CheckPKGVersion })
1014
1015     for pkg, version in syslibdeps.iteritems():
1016         if not conf.CheckPKGVersion( pkg, version ):
1017             print '%s >= %s not found.' %(pkg, version)
1018             DependenciesRequiredMessage()
1019             Exit(1)
1020     
1021     env = conf.Finish()
1022     
1023     libraries['sigc2'] = LibraryInfo()
1024     libraries['sigc2'].ParseConfig('pkg-config --cflags --libs sigc++-2.0')
1025     libraries['glibmm2'] = LibraryInfo()
1026     libraries['glibmm2'].ParseConfig('pkg-config --cflags --libs glibmm-2.4')
1027     libraries['cairomm'] = LibraryInfo()
1028     libraries['cairomm'].ParseConfig('pkg-config --cflags --libs cairomm-1.0')
1029     libraries['gdkmm2'] = LibraryInfo()
1030     libraries['gdkmm2'].ParseConfig ('pkg-config --cflags --libs gdkmm-2.4')
1031     libraries['gtkmm2'] = LibraryInfo()
1032     libraries['gtkmm2'].ParseConfig ('pkg-config --cflags --libs gtkmm-2.4')
1033     libraries['atkmm'] = LibraryInfo()
1034     libraries['atkmm'].ParseConfig ('pkg-config --cflags --libs atkmm-1.6')
1035     libraries['pangomm'] = LibraryInfo()
1036     libraries['pangomm'].ParseConfig ('pkg-config --cflags --libs pangomm-1.4')
1037     libraries['libgnomecanvasmm'] = LibraryInfo()
1038     libraries['libgnomecanvasmm'].ParseConfig ('pkg-config --cflags --libs libgnomecanvasmm-2.6')
1039
1040 #
1041 # cannot use system one for the time being
1042 #
1043     
1044     libraries['sndfile-ardour'] = LibraryInfo(LIBS='libsndfile-ardour',
1045                                     LIBPATH='#libs/libsndfile',
1046                                     CPPPATH=['#libs/libsndfile/src'])
1047
1048 #    libraries['libglademm'] = LibraryInfo()
1049 #    libraries['libglademm'].ParseConfig ('pkg-config --cflags --libs libglademm-2.4')
1050
1051 #    libraries['flowcanvas'] = LibraryInfo(LIBS='flowcanvas', LIBPATH='#/libs/flowcanvas', CPPPATH='#libs/flowcanvas')
1052     libraries['soundtouch'] = LibraryInfo()
1053     #libraries['soundtouch'].ParseConfig ('pkg-config --cflags --libs soundtouch-1.0')
1054     # Comment the previous line and uncomment this for Debian:
1055     libraries['soundtouch'].ParseConfig ('pkg-config --cflags --libs libSoundTouch')
1056
1057     libraries['appleutility'] = LibraryInfo(LIBS='libappleutility',
1058                                             LIBPATH='#libs/appleutility',
1059                                             CPPPATH='#libs/appleutility')
1060     
1061     coredirs = [
1062         'templates'
1063     ]
1064     
1065     subdirs = [
1066         'libs/libsndfile',
1067         'libs/pbd',
1068         'libs/midi++2',
1069         'libs/ardour',
1070         'libs/vamp-sdk',
1071         'libs/vamp-plugins/',
1072     # these are unconditionally included but have
1073     # tests internally to avoid compilation etc
1074     # if VST is not set
1075         'libs/fst',
1076         'vst',
1077     # this is unconditionally included but has
1078     # tests internally to avoid compilation etc
1079     # if COREAUDIO is not set
1080         'libs/appleutility'
1081         ]
1082     
1083     gtk_subdirs = [
1084 #        'libs/flowcanvas',
1085         'libs/gtkmm2ext',
1086         'gtk2_ardour',
1087         'libs/clearlooks'
1088         ]
1089
1090 else:
1091     libraries['sigc2'] = LibraryInfo(LIBS='sigc++2',
1092                                     LIBPATH='#libs/sigc++2',
1093                                     CPPPATH='#libs/sigc++2')
1094     libraries['glibmm2'] = LibraryInfo(LIBS='glibmm2',
1095                                     LIBPATH='#libs/glibmm2',
1096                                     CPPPATH='#libs/glibmm2')
1097     libraries['pangomm'] = LibraryInfo(LIBS='pangomm',
1098                                     LIBPATH='#libs/gtkmm2/pango',
1099                                     CPPPATH='#libs/gtkmm2/pango')
1100     libraries['atkmm'] = LibraryInfo(LIBS='atkmm',
1101                                      LIBPATH='#libs/gtkmm2/atk',
1102                                      CPPPATH='#libs/gtkmm2/atk')
1103     libraries['gdkmm2'] = LibraryInfo(LIBS='gdkmm2',
1104                                       LIBPATH='#libs/gtkmm2/gdk',
1105                                       CPPPATH='#libs/gtkmm2/gdk')
1106     libraries['gtkmm2'] = LibraryInfo(LIBS='gtkmm2',
1107                                      LIBPATH="#libs/gtkmm2/gtk",
1108                                      CPPPATH='#libs/gtkmm2/gtk/')
1109     libraries['libgnomecanvasmm'] = LibraryInfo(LIBS='libgnomecanvasmm',
1110                                                 LIBPATH='#libs/libgnomecanvasmm',
1111                                                 CPPPATH='#libs/libgnomecanvasmm')
1112     
1113     libraries['soundtouch'] = LibraryInfo(LIBS='soundtouch',
1114                                           LIBPATH='#libs/soundtouch',
1115                                           CPPPATH=['#libs', '#libs/soundtouch'])
1116     libraries['sndfile-ardour'] = LibraryInfo(LIBS='libsndfile-ardour',
1117                                     LIBPATH='#libs/libsndfile',
1118                                     CPPPATH=['#libs/libsndfile', '#libs/libsndfile/src'])
1119 #    libraries['libglademm'] = LibraryInfo(LIBS='libglademm',
1120 #                                          LIBPATH='#libs/libglademm',
1121 #                                          CPPPATH='#libs/libglademm')
1122     libraries['appleutility'] = LibraryInfo(LIBS='libappleutility',
1123                                             LIBPATH='#libs/appleutility',
1124                                             CPPPATH='#libs/appleutility')
1125
1126     coredirs = [
1127         'templates'
1128     ]
1129     
1130     subdirs = [
1131         'libs/sigc++2',
1132         'libs/libsndfile',
1133         'libs/pbd',
1134         'libs/midi++2',
1135         'libs/ardour',
1136         'libs/vamp-sdk',
1137         'libs/vamp-plugins/',
1138     # these are unconditionally included but have
1139     # tests internally to avoid compilation etc
1140     # if VST is not set
1141         'libs/fst',
1142         'vst',
1143     # this is unconditionally included but has
1144     # tests internally to avoid compilation etc
1145     # if COREAUDIO is not set
1146         'libs/appleutility'
1147         ]
1148     
1149     gtk_subdirs = [
1150         'libs/glibmm2',
1151         'libs/gtkmm2/pango',
1152         'libs/gtkmm2/atk',
1153         'libs/gtkmm2/gdk',
1154         'libs/gtkmm2/gtk',
1155         'libs/libgnomecanvasmm',
1156         'libs/gtkmm2ext',
1157         'gtk2_ardour',
1158         'libs/clearlooks'
1159         ]
1160
1161 #
1162 # * always build the LGPL control protocol lib, since we link against it from libardour
1163 # * ditto for generic MIDI
1164 # * tranzport checks whether it should build internally, but we need here so that
1165 #   its included in the tarball
1166 #
1167
1168 surface_subdirs = [ 'libs/surfaces/control_protocol',
1169                     'libs/surfaces/generic_midi',
1170                     'libs/surfaces/tranzport',
1171                     'libs/surfaces/mackie',
1172                     'libs/surfaces/powermate'
1173                     ]
1174
1175 if env['SURFACES']:
1176     if have_libusb:
1177         env['TRANZPORT'] = 1
1178     else:
1179         env['TRANZPORT'] = 0
1180         print 'Disabled building Tranzport code because libusb could not be found'
1181
1182     if have_linux_input:
1183         env['POWERMATE'] = 1
1184     else:
1185         env['POWERMATE'] = 0
1186         print 'Disabled building Powermate code because linux/input.h could not be found'
1187
1188     if os.access ('libs/surfaces/sony9pin', os.F_OK):
1189         surface_subdirs += [ 'libs/surfaces/sony9pin' ]
1190 else:
1191     env['POWERMATE'] = 0
1192     env['TRANZPORT'] = 0
1193
1194 #
1195 # timestretch libraries
1196 #
1197
1198 timefx_subdirs = ['libs/soundtouch']
1199 if env['RUBBERBAND']:
1200     timefx_subdirs += ['libs/rubberband']
1201
1202 opts.Save('scache.conf', env)
1203 Help(opts.GenerateHelpText(env))
1204
1205 final_prefix = '$PREFIX'
1206
1207 if env['DESTDIR'] :
1208     install_prefix = '$DESTDIR/$PREFIX'
1209 else:
1210     install_prefix = env['PREFIX']
1211
1212 subst_dict['%INSTALL_PREFIX%'] = install_prefix;
1213 subst_dict['%FINAL_PREFIX%'] = final_prefix;
1214 subst_dict['%PREFIX%'] = final_prefix;
1215
1216 if env['PREFIX'] == '/usr':
1217     final_config_prefix = '/etc'
1218 else:
1219     final_config_prefix = env['PREFIX'] + '/etc'
1220
1221 config_prefix = '$DESTDIR' + final_config_prefix
1222
1223 #
1224 # everybody needs this
1225 #
1226
1227 env.Merge ([ libraries['core'] ])
1228
1229
1230 #
1231 # i18n support
1232 #
1233
1234 conf = Configure (env)
1235 if env['NLS']:
1236     nls_error = 'This system is not configured for internationalized applications.  An english-only version will be built:'
1237     print 'Checking for internationalization support ...'
1238     have_gettext = conf.TryAction(Action('xgettext --version'))
1239     if have_gettext[0] != 1:
1240         nls_error += ' No xgettext command.'
1241         env['NLS'] = 0
1242     else:
1243         print "Found xgettext"
1244     
1245     have_msgmerge = conf.TryAction(Action('msgmerge --version'))
1246     if have_msgmerge[0] != 1:
1247         nls_error += ' No msgmerge command.'
1248         env['NLS'] = 0
1249     else:
1250         print "Found msgmerge"
1251     
1252     if not conf.CheckCHeader('libintl.h'):
1253         nls_error += ' No libintl.h.'
1254         env['NLS'] = 0
1255         
1256     if env['NLS'] == 0:
1257         print nls_error
1258     else:
1259         print "International version will be built."
1260 env = conf.Finish()
1261
1262 if env['NLS'] == 1:
1263     env.Append(CCFLAGS="-DENABLE_NLS")
1264
1265 Export('env install_prefix final_prefix config_prefix final_config_prefix libraries i18n ardour_version subst_dict use_flac')
1266
1267 #
1268 # the configuration file may be system dependent
1269 #
1270
1271 conf = env.Configure ()
1272
1273 if conf.CheckCHeader('/System/Library/Frameworks/CoreAudio.framework/Versions/A/Headers/CoreAudio.h'):
1274     subst_dict['%JACK_INPUT%'] = "coreaudio:Built-in Audio:in"
1275     subst_dict['%JACK_OUTPUT%'] = "coreaudio:Built-in Audio:out"
1276 else:
1277     subst_dict['%JACK_INPUT%'] = "alsa_pcm:playback_"
1278     subst_dict['%JACK_OUTPUT%'] = "alsa_pcm:capture_"
1279
1280 # posix_memalign available
1281 if not conf.CheckFunc('posix_memalign'):
1282     print 'Did not find posix_memalign(), using malloc'
1283     env.Append(CCFLAGS='-DNO_POSIX_MEMALIGN')
1284
1285
1286 env = conf.Finish()
1287
1288 # generate the per-user and system rc files from the same source
1289
1290 sysrcbuild = env.SubstInFile ('ardour_system.rc','ardour.rc.in', SUBST_DICT = subst_dict)
1291
1292 # add to the substitution dictionary
1293
1294 subst_dict['%VERSION%'] = ardour_version[0:3]
1295 subst_dict['%EXTRA_VERSION%'] = ardour_version[3:]
1296 subst_dict['%REVISION_STRING%'] = ''
1297 if os.path.exists('.svn'):
1298     subst_dict['%REVISION_STRING%'] = '.' + fetch_svn_revision ('.') + 'svn'
1299
1300 # specbuild = env.SubstInFile ('ardour.spec','ardour.spec.in', SUBST_DICT = subst_dict)
1301
1302 the_revision = env.Command ('frobnicatory_decoy', [], create_stored_revision)
1303 remove_ardour = env.Command ('frobnicatory_decoy2', [],
1304                              [ Delete ('$PREFIX/etc/ardour2'),
1305                                Delete ('$PREFIX/lib/ardour2'),
1306                                Delete ('$PREFIX/bin/ardour2'),
1307                                Delete ('$PREFIX/share/ardour2')])
1308
1309 env.Alias('revision', the_revision)
1310 env.Alias('install', env.Install(os.path.join(config_prefix, 'ardour2'), 'ardour_system.rc'))
1311 env.Alias('uninstall', remove_ardour)
1312
1313 Default (sysrcbuild)
1314
1315 # source tarball
1316
1317 Precious (env['DISTTREE'])
1318
1319 env.Distribute (env['DISTTREE'],
1320                [ 'SConstruct', 'svn_revision.h',
1321                   'COPYING', 'PACKAGER_README', 'README',
1322                   'ardour.rc.in',
1323                   'tools/config.guess',
1324                   'icons/icon/ardour_icon_mac_mask.png',
1325                   'icons/icon/ardour_icon_mac.png',
1326                   'icons/icon/ardour_icon_tango_16px_blue.png',
1327                   'icons/icon/ardour_icon_tango_16px_red.png',
1328                   'icons/icon/ardour_icon_tango_22px_blue.png',
1329                   'icons/icon/ardour_icon_tango_22px_red.png',
1330                   'icons/icon/ardour_icon_tango_32px_blue.png',
1331                   'icons/icon/ardour_icon_tango_32px_red.png',
1332                   'icons/icon/ardour_icon_tango_48px_blue.png',
1333                   'icons/icon/ardour_icon_tango_48px_red.png'
1334                   ] +
1335                 glob.glob ('DOCUMENTATION/AUTHORS*') +
1336                 glob.glob ('DOCUMENTATION/CONTRIBUTORS*') +
1337                 glob.glob ('DOCUMENTATION/TRANSLATORS*') +
1338                 glob.glob ('DOCUMENTATION/BUILD*') +
1339                 glob.glob ('DOCUMENTATION/FAQ*') +
1340                 glob.glob ('DOCUMENTATION/README*')
1341                 )
1342
1343 srcdist = env.Tarball(env['TARBALL'], [ env['DISTTREE'], the_revision ])
1344 env.Alias ('srctar', srcdist)
1345
1346 #
1347 # don't leave the distree around
1348 #
1349
1350 env.AddPreAction (env['DISTTREE'], Action ('rm -rf ' + str (File (env['DISTTREE']))))
1351 env.AddPostAction (srcdist, Action ('rm -rf ' + str (File (env['DISTTREE']))))
1352
1353 #
1354 # the subdirs
1355 #
1356
1357 for subdir in coredirs:
1358     SConscript (subdir + '/SConscript')
1359
1360 for sublistdir in [ subdirs, timefx_subdirs, gtk_subdirs, surface_subdirs ]:
1361     for subdir in sublistdir:
1362         SConscript (subdir + '/SConscript')
1363
1364 # cleanup
1365 env.Clean ('scrub', [ 'scache.conf', '.sconf_temp', '.sconsign.dblite', 'config.log'])
1366