root/trunk/libffado/SConstruct

Revision 903, 15.0 kB (checked in by ppalmers, 16 years ago)

init env with shell env

Line 
1 #! /usr/bin/python
2 #
3 # Copyright (C) 2007 Arnold Krille
4 # Copyright (C) 2007 Pieter Palmers
5 #
6 # This file is part of FFADO
7 # FFADO = Free Firewire (pro-)audio drivers for linux
8 #
9 # FFADO is based upon FreeBoB.
10 #
11 # This program is free software: you can redistribute it and/or modify
12 # it under the terms of the GNU General Public License as published by
13 # the Free Software Foundation, either version 2 of the License, or
14 # (at your option) version 3 of the License.
15 #
16 # This program is distributed in the hope that it will be useful,
17 # but WITHOUT ANY WARRANTY; without even the implied warranty of
18 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19 # GNU General Public License for more details.
20 #
21 # You should have received a copy of the GNU General Public License
22 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
23 #
24
25 FFADO_API_VERSION="7"
26 FFADO_VERSION="1.999.16"
27
28 import os
29 import re
30 from string import Template
31 import imp
32
33 build_dir = ARGUMENTS.get('BUILDDIR', "")
34 if build_dir:
35         build_base=build_dir+'/'
36         if not os.path.isdir( build_base ):
37                 os.makedirs( build_base )
38         print "Building into: " + build_base
39 else:
40         build_base=''
41
42 destdir = ARGUMENTS.get( 'DESTDIR', "" )
43
44 if not os.path.isdir( "cache" ):
45         os.makedirs( "cache" )
46
47 opts = Options( "cache/"+build_base+"options.cache" )
48
49 #
50 # If this is just to display a help-text for the variable used via ARGUMENTS, then its wrong...
51 opts.Add( "BUILDDIR", "Path to place the built files in", "")
52
53 opts.AddOptions(
54         BoolOption( "DEBUG", """\
55 Toggle debug-build. DEBUG means \"-g -Wall\" and more, otherwise we will use
56   \"-O2\" to optimise.""", True ),
57         BoolOption( "PROFILE", "Build with symbols and other profiling info", False ),
58         PathOption( "PREFIX", "The prefix where ffado will be installed to.", "/usr/local", PathOption.PathAccept ),
59         PathOption( "BINDIR", "Overwrite the directory where apps are installed to.", "$PREFIX/bin", PathOption.PathAccept ),
60         PathOption( "LIBDIR", "Overwrite the directory where libs are installed to.", "$PREFIX/lib", PathOption.PathAccept ),
61         PathOption( "INCLUDEDIR", "Overwrite the directory where headers are installed to.", "$PREFIX/include", PathOption.PathAccept ),
62         PathOption( "SHAREDIR", "Overwrite the directory where misc shared files are installed to.", "$PREFIX/share/libffado", PathOption.PathAccept ),
63         BoolOption( "ENABLE_BEBOB", "Enable/Disable the bebob part.", True ),
64         BoolOption( "ENABLE_FIREWORKS", "Enable/Disable the ECHO Audio FireWorks avc part.", True ),
65         BoolOption( "ENABLE_MOTU", "Enable/Disable the Motu part.", True ),
66         BoolOption( "ENABLE_DICE", "Enable/Disable the DICE part.", False ),
67         BoolOption( "ENABLE_METRIC_HALO", "Enable/Disable the Metric Halo part.", False ),
68         BoolOption( "ENABLE_RME", "Enable/Disable the RME part.", False ),
69         BoolOption( "ENABLE_BOUNCE", "Enable/Disable the BOUNCE part.", False ),
70         BoolOption( "ENABLE_GENERICAVC", """\
71 Enable/Disable the the generic avc part (mainly used by apple).
72   Note that disabling this option might be overwritten by other devices needing
73   this code.""", False ),
74         BoolOption( "ENABLE_ALL", "Enable/Disable support for all devices.", False ),
75         BoolOption( "BUILD_TESTS", """\
76 Build the tests in their directory. As some contain quite some functionality,
77   this is on by default.
78   If you just want to use ffado with jack without the tools, you can disable this.\
79 """, True ),
80     BoolOption( "BUILD_STATIC_TOOLS", "Build a statically linked version of the FFADO tools.", False ),
81     EnumOption('DIST_TARGET', 'Build target for cross compiling packagers', 'auto', allowed_values=('auto', 'i386', 'i686', 'x86_64', 'none' ), ignorecase=2),
82     BoolOption( "ENABLE_OPTIMIZATIONS", "Enable optimizations and the use of processor specific extentions (MMX/SSE/...).", False ),
83
84         )
85
86 ## Load the builders in config
87 buildenv=os.environ
88 vars_to_check = [
89         'PATH',
90         'PKG_CONFIG_PATH',
91         'LD_LIBRARY_PATH',
92         'XDG_CONFIG_DIRS',
93         'XDG_DATA_DIRS',
94         'HOME',
95 ]
96 for var in vars_to_check:
97         if os.environ.has_key(var):
98                 buildenv[var]=os.environ[var]
99         else:
100                 buildenv[var]=''
101
102 env = Environment( tools=['default','scanreplace','pyuic','dbus','doxygen','pkgconfig'], toolpath=['admin'], ENV = buildenv, options=opts )
103
104
105 Help( """
106 For building ffado you can set different options as listed below. You have to
107 specify them only once, scons will save the last value you used and re-use
108 that.
109 To really undo your settings and return to the factory defaults, remove the
110 "cache"-folder and the file ".sconsign.dblite" from this directory.
111 For example with: "rm -Rf .sconsign.dblite cache"
112
113 Note that this is a development version! Don't complain if its not working!
114 See www.ffado.org for stable releases.
115 """ )
116 Help( opts.GenerateHelpText( env ) )
117
118 # make sure the necessary dirs exist
119 if not os.path.isdir( "cache/" + build_base ):
120         os.makedirs( "cache/" + build_base )
121 if not os.path.isdir( 'cache/objects' ):
122         os.makedirs( 'cache/objects' )
123
124 CacheDir( 'cache/objects' )
125
126 opts.Save( 'cache/' + build_base + "options.cache", env )
127
128 def ConfigGuess( context ):
129         context.Message( "Trying to find the system triple: " )
130         ret = os.popen( "admin/config.guess" ).read()[:-1]
131         context.Result( ret )
132         return ret
133
134 def CheckForApp( context, app ):
135         context.Message( "Checking wether '" + app + "' executes " )
136         ret = context.TryAction( app )
137         context.Result( ret[0] )
138         return ret[0]
139
140 def CheckForPyModule( context, module ):
141         context.Message( "Checking for the python module '" + module + "' " )
142         ret = True
143         try:
144                 imp.find_module( module )
145         except ImportError:
146                 ret = False
147         context.Result( ret )
148         return ret
149
150 tests = {
151         "ConfigGuess" : ConfigGuess,
152         "CheckForApp" : CheckForApp,
153         "CheckForPyModule": CheckForPyModule,
154 }
155 tests.update( env['PKGCONFIG_TESTS'] )
156 tests.update( env['PYUIC_TESTS'] )
157
158 conf = Configure( env,
159         custom_tests = tests,
160         conf_dir = "cache/" + build_base,
161         log_file = "cache/" + build_base + 'config.log' )
162
163 if not env.GetOption('clean'):
164         #
165         # Check if the environment can actually compile c-files by checking for a
166         # header shipped with gcc.
167         #
168         if not conf.CheckHeader( "stdio.h", language="C" ):
169                 print "It seems as if stdio.h is missing. This probably means that your build environment is broken, please make sure you have a working c-compiler and libstdc installed and usable."
170                 Exit( 1 )
171         #
172         # ... and do the same with a c++-header. Because some distributions have
173         # distinct packages for gcc and g++.
174         #
175         if not conf.CheckHeader( "iostream", language="C++" ):
176                 print "It seems as if iostream is missing. This probably means that your build environment is broken, please make sure you have a working c++-compiler installed and usable."
177                 Exit( 1 )
178
179         #
180         # The following checks are for headers and libs and packages we need.
181         #
182         allpresent = 1;
183         allpresent &= conf.CheckHeader( "expat.h" )
184         allpresent &= conf.CheckLib( 'expat', 'XML_ExpatVersion', '#include <expat.h>' )
185        
186         allpresent &= conf.CheckForPKGConfig();
187
188         pkgs = {
189                 'libraw1394' : '1.3.0',
190                 'libavc1394' : '0.5.3',
191                 'libiec61883' : '1.1.0',
192                 'alsa' : '1.0.0',
193                 'libxml++-2.6' : '2.13.0',
194                 'dbus-1' : '1.0',
195                 }
196         for pkg in pkgs:
197                 name2 = pkg.replace("+","").replace(".","").replace("-","").upper()
198                 env['%s_FLAGS' % name2] = conf.GetPKGFlags( pkg, pkgs[pkg] )
199                 if env['%s_FLAGS'%name2] == 0:
200                         allpresent &= 0
201
202         if not allpresent:
203                 print """
204 (At least) One of the dependencies is missing. I can't go on without it, please
205 install the needed packages for each of the lines saying "no".
206 (Remember to also install the *-devel packages!)
207 """
208                 Exit( 1 )
209
210         #
211         # Optional checks follow:
212         #
213         env['ALSA_SEQ_OUTPUT'] = conf.CheckLib( 'asound', symbol='snd_seq_event_output_direct', autoadd=0 )
214
215 if conf.CheckForApp( "which pyuic" ) and conf.CheckForPyModule( 'dbus' ) and conf.CheckForPyModule( 'qt' ):
216         env['PYUIC'] = True
217
218 if conf.CheckForApp( "xdg-desktop-menu --help" ):
219         env['XDG_TOOLS'] = True
220
221 config_guess = conf.ConfigGuess()
222
223 env = conf.Finish()
224
225 if env['DEBUG']:
226         print "Doing a DEBUG build"
227         # -Werror could be added to, which would force the devs to really remove all the warnings :-)
228         env.AppendUnique( CCFLAGS=["-DDEBUG","-Wall","-g"] )
229         env.AppendUnique( CFLAGS=["-DDEBUG","-Wall","-g"] )
230 else:
231         env.AppendUnique( CCFLAGS=["-O2","-DNDEBUG"] )
232         env.AppendUnique( CFLAGS=["-O2","-DNDEBUG"] )
233
234 if env['PROFILE']:
235         print "Doing a PROFILE build"
236         # -Werror could be added to, which would force the devs to really remove all the warnings :-)
237         env.AppendUnique( CCFLAGS=["-Wall","-g"] )
238         env.AppendUnique( CFLAGS=["-Wall","-g"] )
239
240
241 # this is required to indicate that the DBUS version we use has support
242 # for platform dependent threading init functions
243 # this is true for DBUS >= 0.96 or so. Since we require >= 1.0 it is
244 # always true
245 env.AppendUnique( CCFLAGS=["-DDBUS_HAS_THREADS_INIT_DEFAULT"] )
246
247 if env['ENABLE_ALL']:
248         env['ENABLE_BEBOB'] = True
249         env['ENABLE_FIREWORKS'] = True
250         env['ENABLE_MOTU'] = True
251         env['ENABLE_DICE'] = True
252         env['ENABLE_METRIC_HALO'] = True
253         env['ENABLE_RME'] = True
254         env['ENABLE_BOUNCE'] = True
255
256 if env['ENABLE_BEBOB'] or env['ENABLE_DICE'] or env['ENABLE_BOUNCE'] or env['ENABLE_FIREWORKS']:
257         env['ENABLE_GENERICAVC'] = True
258
259 env['BUILD_STATIC_LIB'] = False
260 if env['BUILD_STATIC_TOOLS']:
261     print "Building static versions of the tools..."
262     env['BUILD_STATIC_LIB'] = True
263
264 if build_base:
265         env['build_base']="#/"+build_base
266 else:
267         env['build_base']="#/"
268
269 #
270 # Uppercase variables are for usage in code, lowercase versions for usage in
271 # scons-files for installing.
272 #
273 env['BINDIR'] = Template( env['BINDIR'] ).safe_substitute( env )
274 env['LIBDIR'] = Template( env['LIBDIR'] ).safe_substitute( env )
275 env['INCLUDEDIR'] = Template( env['INCLUDEDIR'] ).safe_substitute( env )
276 env['SHAREDIR'] = Template( env['SHAREDIR'] ).safe_substitute( env )
277 env['bindir'] = Template( destdir + env['BINDIR'] ).safe_substitute( env )
278 env['libdir'] = Template( destdir + env['LIBDIR'] ).safe_substitute( env )
279 env['includedir'] = Template( destdir + env['INCLUDEDIR'] ).safe_substitute( env )
280 env['sharedir'] = Template( destdir + env['SHAREDIR'] ).safe_substitute( env )
281
282 env.Command( target=env['sharedir'], source="", action=Mkdir( env['sharedir'] ) )
283
284 env.Alias( "install", env['libdir'] )
285 env.Alias( "install", env['includedir'] )
286 env.Alias( "install", env['sharedir'] )
287 env.Alias( "install", env['bindir'] )
288
289 #
290 # shamelessly copied from the Ardour scons file
291 #
292
293 opt_flags = []
294 env['USE_SSE'] = 0
295
296 # guess at the platform, used to define compiler flags
297
298 config_cpu = 0
299 config_arch = 1
300 config_kernel = 2
301 config_os = 3
302 config = config_guess.split ("-")
303
304 # Autodetect
305 if env['DIST_TARGET'] == 'auto':
306     if re.search ("x86_64", config[config_cpu]) != None:
307         env['DIST_TARGET'] = 'x86_64'
308     elif re.search("i[0-5]86", config[config_cpu]) != None:
309         env['DIST_TARGET'] = 'i386'
310     else:
311         env['DIST_TARGET'] = 'i686'
312     print "Detected DIST_TARGET = " + env['DIST_TARGET']
313
314 if ((re.search ("i[0-9]86", config[config_cpu]) != None) or (re.search ("x86_64", config[config_cpu]) != None)):
315    
316     build_host_supports_sse = 0
317     build_host_supports_sse2 = 0
318
319     if config[config_kernel] == 'linux' :
320        
321         if env['DIST_TARGET'] != 'i386':
322            
323             flag_line = os.popen ("cat /proc/cpuinfo | grep '^flags'").read()[:-1]
324             x86_flags = flag_line.split (": ")[1:][0].split ()
325            
326             if "mmx" in x86_flags:
327                 opt_flags.append ("-mmmx")
328             if "sse" in x86_flags:
329                 build_host_supports_sse = 1
330             if "sse2" in x86_flags:
331                 build_host_supports_sse2 = 1
332             if "3dnow" in x86_flags:
333                 opt_flags.append ("-m3dnow")
334            
335             if config[config_cpu] == "i586":
336                 opt_flags.append ("-march=i586")
337             elif config[config_cpu] == "i686":
338                 opt_flags.append ("-march=i686")
339    
340     if ((env['DIST_TARGET'] == 'i686') or (env['DIST_TARGET'] == 'x86_64')) \
341        and build_host_supports_sse and env['ENABLE_OPTIMIZATIONS']:
342         opt_flags.extend (["-msse", "-mfpmath=sse"])
343         env['USE_SSE'] = 1
344
345     if ((env['DIST_TARGET'] == 'i686') or (env['DIST_TARGET'] == 'x86_64')) \
346        and build_host_supports_sse2 and env['ENABLE_OPTIMIZATIONS']:
347         opt_flags.extend (["-msse2"])
348         env['USE_SSE2'] = 1
349
350 # end of processor-specific section
351 if env['ENABLE_OPTIMIZATIONS']:
352     opt_flags.extend (["-fomit-frame-pointer","-ffast-math","-funroll-loops"])
353     env.AppendUnique( CCFLAGS=opt_flags )
354     env.AppendUnique( CFLAGS=opt_flags )
355     print "Doing an optimized build..."
356
357 env['REVISION'] = os.popen('svnversion .').read()[:-1]
358 # This may be as simple as '89' or as complex as '4123:4184M'.
359 # We'll just use the last bit.
360 env['REVISION'] = env['REVISION'].split(':')[-1]
361
362 if env['REVISION'] == 'exported':
363         env['REVISION'] = ''
364
365 env['FFADO_API_VERSION']=FFADO_API_VERSION
366
367 env['PACKAGE'] = "libffado"
368 env['VERSION'] = FFADO_VERSION
369 env['LIBVERSION'] = "1.0.0"
370
371 #
372 # To have the top_srcdir as the doxygen-script is used from auto*
373 #
374 env['top_srcdir'] = env.Dir( "." ).abspath
375
376 #
377 # Start building
378 #
379 env.ScanReplace( "config.h.in" )
380 # ensure that the config.h is updated with the version
381 env.Depends( "config.h", "SConstruct" )
382 env.Depends( "config.h", 'cache/' + build_base + "options.cache" )
383
384 env.Depends( "libffado.pc", "SConstruct" )
385 pkgconfig = env.ScanReplace( "libffado.pc.in" )
386 env.Install( env['libdir'] + '/pkgconfig', pkgconfig )
387
388 subdirs=['external','src','libffado','tests','support','doc']
389 if build_base:
390         env.SConscript( dirs=subdirs, exports="env", build_dir=build_base+subdir )
391 else:
392         env.SConscript( dirs=subdirs, exports="env" )
393
394 if 'debian' in COMMAND_LINE_TARGETS:
395         env.SConscript("deb/SConscript", exports="env")
396
397 # By default only src is built but all is cleaned
398 if not env.GetOption('clean'):
399     Default( 'src' )
400     Default( 'support' )
401     if env['BUILD_TESTS']:
402         Default( 'tests' )
403
404 #
405 # Deal with the DESTDIR vs. xdg-tools conflict (which is basicely that the xdg-tools can't deal with DESTDIR, so the packagers have to deal with this their own :-)
406 #
407 if len(destdir) > 0:
408         if not len( ARGUMENTS.get( "WILL_DEAL_WITH_XDG_MYSELF", "" ) ) > 0:
409                 print """
410 WARNING!
411 You are usin the (packagers) option DESTDIR to install this package to a
412 different place than the real prefix. As the xdg-tools can't cope with
413 that, the .desktop-files are not installed by this build, you have to
414 deal with them your own.
415 (And you have to look into the SConstruct to learn how to disable this
416 message.)
417 """
418 else:
419         if env.has_key( 'XDG_TOOLS' ) and env.has_key( 'PYUIC' ):
420                 env.Command( "support/xdg/.ffado.org-ffadomixer.desktop", "support/xdg/ffado.org-ffadomixer.desktop", "xdg-desktop-menu install $SOURCES && touch $TARGET" )
421                 env.NoCache( "support/xdg/.ffado.org-ffadomixer.desktop" )
422                 env.Alias( "install", "support/xdg/.ffado.org-ffadomixer.desktop" )
423
424 #
425 # Create a tags-file for easier emacs/vim-source-browsing
426 #  I don't know if the dependency is right...
427 #
428 findcommand = "find . \( -path \"*.h\" -o -path \"*.cpp\" -o -path \"*.c\" \) \! -path \"*.svn*\" \! -path \"./doc*\" \! -path \"./cache*\""
429 env.Command( "tags", "", findcommand + " |xargs ctags" )
430 env.Command( "TAGS", "", findcommand + " |xargs etags" )
431 env.AlwaysBuild( "tags", "TAGS" )
432 env.NoCache( "tags", "TAGS" )
433
Note: See TracBrowser for help on using the browser.