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