root/trunk/libffado/SConstruct

Revision 791, 12.0 kB (checked in by ppalmers, 16 years ago)

try and get some better low-latency performance

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 3 of the License, or
14 # (at your option) any later version.
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 import os
26 import re
27 from string import Template
28
29 build_dir = ARGUMENTS.get('BUILDDIR', "")
30 if build_dir:
31         build_base=build_dir+'/'
32         if not os.path.isdir( build_base ):
33                 os.makedirs( build_base )
34         print "Building into: " + build_base
35 else:
36         build_base=''
37
38 if not os.path.isdir( "cache" ):
39         os.makedirs( "cache" )
40
41 opts = Options( "cache/"+build_base+"options.cache" )
42
43 #
44 # If this is just to display a help-text for the variable used via ARGUMENTS, then its wrong...
45 opts.Add( "BUILDDIR", "Path to place the built files in", "")
46
47 opts.AddOptions(
48         BoolOption( "DEBUG", """\
49 Toggle debug-build. DEBUG means \"-g -Wall\" and more, otherwise we will use
50   \"-O2\" to optimise.""", True ),
51         BoolOption( "PROFILE", "Build with symbols and other profiling info", False ),
52         PathOption( "PREFIX", "The prefix where ffado will be installed to.", "/usr/local", PathOption.PathAccept ),
53         PathOption( "BINDIR", "Overwrite the directory where apps are installed to.", "$PREFIX/bin", PathOption.PathAccept ),
54         PathOption( "LIBDIR", "Overwrite the directory where libs are installed to.", "$PREFIX/lib", PathOption.PathAccept ),
55         PathOption( "INCLUDEDIR", "Overwrite the directory where headers are installed to.", "$PREFIX/include", PathOption.PathAccept ),
56         PathOption( "SHAREDIR", "Overwrite the directory where misc shared files are installed to.", "$PREFIX/share/libffado", PathOption.PathAccept ),
57         BoolOption( "ENABLE_BEBOB", "Enable/Disable the bebob part.", True ),
58         BoolOption( "ENABLE_FIREWORKS", "Enable/Disable the ECHO Audio FireWorks avc part.", True ),
59         BoolOption( "ENABLE_MOTU", "Enable/Disable the Motu part.", True ),
60         BoolOption( "ENABLE_DICE", "Enable/Disable the DICE part.", False ),
61         BoolOption( "ENABLE_METRIC_HALO", "Enable/Disable the Metric Halo part.", False ),
62         BoolOption( "ENABLE_RME", "Enable/Disable the RME part.", False ),
63         BoolOption( "ENABLE_BOUNCE", "Enable/Disable the BOUNCE part.", False ),
64         BoolOption( "ENABLE_GENERICAVC", """\
65 Enable/Disable the the generic avc part (mainly used by apple).
66   Note that disabling this option might be overwritten by other devices needing
67   this code.""", False ),
68         BoolOption( "ENABLE_ALL", "Enable/Disable support for all devices.", False ),
69         BoolOption( "BUILD_TESTS", """\
70 Build the tests in their directory. As some contain quite some functionality,
71   this is on by default.
72   If you just want to use ffado with jack without the tools, you can disable this.\
73 """, True ),
74     BoolOption( "BUILD_STATIC_TOOLS", "Build a statically linked version of the FFADO tools.", False ),
75     EnumOption('DIST_TARGET', 'Build target for cross compiling packagers', 'auto', allowed_values=('auto', 'i386', 'i686', 'x86_64', 'none' ), ignorecase=2),
76     BoolOption( "ENABLE_OPTIMIZATIONS", "Enable optimizations and the use of processor specific extentions (MMX/SSE/...).", False ),
77
78         )
79
80 ## Load the builders in config
81 buildenv={}
82 if os.environ.has_key('PATH'):
83         buildenv['PATH']=os.environ['PATH']
84 else:
85         buildenv['PATH']=''
86
87 if os.environ.has_key('PKG_CONFIG_PATH'):
88         buildenv['PKG_CONFIG_PATH']=os.environ['PKG_CONFIG_PATH']
89 else:
90         buildenv['PKG_CONFIG_PATH']=''
91
92 if os.environ.has_key('LD_LIBRARY_PATH'):
93         buildenv['LD_LIBRARY_PATH']=os.environ['LD_LIBRARY_PATH']
94 else:
95         buildenv['LD_LIBRARY_PATH']=''
96
97
98 env = Environment( tools=['default','scanreplace','pyuic','dbus','doxygen','pkgconfig'], toolpath=['admin'], ENV = buildenv, options=opts )
99
100
101 Help( """
102 For building ffado you can set different options as listed below. You have to
103 specify them only once, scons will save the last value you used and re-use
104 that.
105 To really undo your settings and return to the factory defaults, remove the
106 "cache"-folder and the file ".sconsign.dblite" from this directory.
107 For example with: "rm -Rf .sconsign.dblite cache"
108
109 Note that this is a development version! Don't complain if its not working!
110 See www.ffado.org for stable releases.
111 """ )
112 Help( opts.GenerateHelpText( env ) )
113
114 # make sure the necessary dirs exist
115 if not os.path.isdir( "cache/" + build_base ):
116         os.makedirs( "cache/" + build_base )
117 if not os.path.isdir( 'cache/objects' ):
118         os.makedirs( 'cache/objects' )
119
120 CacheDir( 'cache/objects' )
121
122 opts.Save( 'cache/' + build_base + "options.cache", env )
123
124 def ConfigGuess( context ):
125         context.Message( "Trying to find the system triple: " )
126         ret = os.popen( "admin/config.guess" ).read()[:-1]
127         context.Result( ret )
128         return ret
129
130 tests = { "ConfigGuess" : ConfigGuess }
131 tests.update( env['PKGCONFIG_TESTS'] )
132 tests.update( env['PYUIC_TESTS'] )
133
134 conf = Configure( env,
135         custom_tests = tests,
136         conf_dir = "cache/" + build_base,
137         log_file = "cache/" + build_base + 'config.log' )
138
139 if not env.GetOption('clean'):
140         #
141         # Check if the environment can actually compile c-files by checking for a
142         # header shipped with gcc.
143         #
144         if not conf.CheckHeader( "stdio.h" ):
145                 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."
146                 Exit( 1 )
147
148         #
149         # The following checks are for headers and libs and packages we need.
150         #
151         allpresent = 1;
152         allpresent &= conf.CheckHeader( "expat.h" )
153         allpresent &= conf.CheckLib( 'expat', 'XML_ExpatVersion', '#include <expat.h>' )
154        
155         allpresent &= conf.CheckForPKGConfig();
156
157         pkgs = {
158                 'libraw1394' : '1.3.0',
159                 'libavc1394' : '0.5.3',
160                 'libiec61883' : '1.1.0',
161                 'alsa' : '1.0.0',
162                 'libxml++-2.6' : '2.13.0',
163                 'dbus-1' : '1.0',
164                 }
165         for pkg in pkgs:
166                 name2 = pkg.replace("+","").replace(".","").replace("-","").upper()
167                 env['%s_FLAGS' % name2] = conf.GetPKGFlags( pkg, pkgs[pkg] )
168                 if env['%s_FLAGS'%name2] == 0:
169                         allpresent &= 0
170
171         if not allpresent:
172                 print """
173 (At least) One of the dependencies is missing. I can't go on without it, please
174 install the needed packages (remember to also install the *-devel packages)
175 """
176                 Exit( 1 )
177
178         #
179         # Optional checks follow:
180         #
181         env['ALSA_SEQ_OUTPUT'] = conf.CheckLib( 'asound', symbol='snd_seq_event_output_direct', autoadd=0 )
182
183 if conf.PyQtCheck():
184         env['PYUIC'] = True
185
186 config_guess = conf.ConfigGuess()
187
188 env = conf.Finish()
189
190 if env['DEBUG']:
191         print "Doing a DEBUG build"
192         # -Werror could be added to, which would force the devs to really remove all the warnings :-)
193         env.AppendUnique( CCFLAGS=["-DDEBUG","-Wall","-g"] )
194         env.AppendUnique( CFLAGS=["-DDEBUG","-Wall","-g"] )
195 else:
196         env.AppendUnique( CCFLAGS=["-O2","-DNDEBUG"] )
197         env.AppendUnique( CFLAGS=["-O2","-DNDEBUG"] )
198
199 if env['PROFILE']:
200         print "Doing a PROFILE build"
201         # -Werror could be added to, which would force the devs to really remove all the warnings :-)
202         env.AppendUnique( CCFLAGS=["-Wall","-g"] )
203         env.AppendUnique( CFLAGS=["-Wall","-g"] )
204
205
206 # this is required to indicate that the DBUS version we use has support
207 # for platform dependent threading init functions
208 # this is true for DBUS >= 0.96 or so. Since we require >= 1.0 it is
209 # always true
210 env.AppendUnique( CCFLAGS=["-DDBUS_HAS_THREADS_INIT_DEFAULT"] )
211
212 if env['ENABLE_ALL']:
213         env['ENABLE_BEBOB'] = True
214         env['ENABLE_FIREWORKS'] = True
215         env['ENABLE_MOTU'] = True
216         env['ENABLE_DICE'] = True
217         env['ENABLE_METRIC_HALO'] = True
218         env['ENABLE_RME'] = True
219         env['ENABLE_BOUNCE'] = True
220
221 if env['ENABLE_BEBOB'] or env['ENABLE_DICE'] or env['ENABLE_BOUNCE'] or env['ENABLE_FIREWORKS']:
222         env['ENABLE_GENERICAVC'] = True
223
224 env['BUILD_STATIC_LIB'] = False
225 if env['BUILD_STATIC_TOOLS']:
226     print "Building static versions of the tools..."
227     env['BUILD_STATIC_LIB'] = True
228
229 if build_base:
230         env['build_base']="#/"+build_base
231 else:
232         env['build_base']="#/"
233
234 #
235 # XXX: Maybe we can even drop these lower-case variables and only use the uppercase ones?
236 #
237 env['bindir'] = Template( os.path.join( env['BINDIR'] ) ).safe_substitute( env )
238 env['libdir'] = Template( os.path.join( env['LIBDIR'] ) ).safe_substitute( env )
239 env['includedir'] = Template( os.path.join( env['INCLUDEDIR'] ) ).safe_substitute( env )
240 env['sharedir'] = Template( os.path.join( env['SHAREDIR'] ) ).safe_substitute( env )
241
242 env.Command( target=env['sharedir'], source="", action=Mkdir( env['sharedir'] ) )
243
244 env.Alias( "install", env['libdir'] )
245 env.Alias( "install", env['includedir'] )
246 env.Alias( "install", env['sharedir'] )
247 env.Alias( "install", env['bindir'] )
248
249 #
250 # shamelessly copied from the Ardour scons file
251 #
252
253 opt_flags = []
254 env['USE_SSE'] = 0
255
256 # guess at the platform, used to define compiler flags
257
258 config_cpu = 0
259 config_arch = 1
260 config_kernel = 2
261 config_os = 3
262 config = config_guess.split ("-")
263
264 # Autodetect
265 if env['DIST_TARGET'] == 'auto':
266     if re.search ("x86_64", config[config_cpu]) != None:
267         env['DIST_TARGET'] = 'x86_64'
268     elif re.search("i[0-5]86", config[config_cpu]) != None:
269         env['DIST_TARGET'] = 'i386'
270     else:
271         env['DIST_TARGET'] = 'i686'
272     print "Detected DIST_TARGET = " + env['DIST_TARGET']
273
274 if ((re.search ("i[0-9]86", config[config_cpu]) != None) or (re.search ("x86_64", config[config_cpu]) != None)):
275    
276     build_host_supports_sse = 0
277
278     if config[config_kernel] == 'linux' :
279        
280         if env['DIST_TARGET'] != 'i386':
281            
282             flag_line = os.popen ("cat /proc/cpuinfo | grep '^flags'").read()[:-1]
283             x86_flags = flag_line.split (": ")[1:][0].split ()
284            
285             if "mmx" in x86_flags:
286                 opt_flags.append ("-mmmx")
287             if "sse" in x86_flags:
288                 build_host_supports_sse = 1
289             if "3dnow" in x86_flags:
290                 opt_flags.append ("-m3dnow")
291            
292             if config[config_cpu] == "i586":
293                 opt_flags.append ("-march=i586")
294             elif config[config_cpu] == "i686":
295                 opt_flags.append ("-march=i686")
296    
297     if ((env['DIST_TARGET'] == 'i686') or (env['DIST_TARGET'] == 'x86_64')) \
298        and build_host_supports_sse and env['ENABLE_OPTIMIZATIONS']:
299         opt_flags.extend (["-msse", "-mfpmath=sse"])
300         env['USE_SSE'] = 1
301
302 # end of processor-specific section
303 if env['ENABLE_OPTIMIZATIONS']:
304     opt_flags.extend (["-fomit-frame-pointer","-ffast-math","-funroll-loops"])
305     env.AppendUnique( CCFLAGS=opt_flags )
306     env.AppendUnique( CFLAGS=opt_flags )
307     print "Doing an optimized build..."
308
309
310 env['REVISION'] = os.popen('svnversion .').read()[:-1]
311 # This may be as simple as '89' or as complex as '4123:4184M'.
312 # We'll just use the last bit.
313 env['REVISION'] = env['REVISION'].split(':')[-1]
314
315 if env['REVISION'] == 'exported':
316         env['REVISION'] = ''
317
318 env['FFADO_API_VERSION']="5"
319
320 env['PACKAGE'] = "libffado"
321 env['VERSION'] = "1.999.11"
322 env['LIBVERSION'] = "1.0.0"
323
324 #
325 # To have the top_srcdir as the doxygen-script is used from auto*
326 #
327 env['top_srcdir'] = env.Dir( "." ).abspath
328
329 #
330 # Start building
331 #
332 env.ScanReplace( "config.h.in" )
333 # ensure that the config.h is updated with the version
334 env.Depends( "config.h", "SConstruct" )
335 env.Depends( "config.h", 'cache/' + build_base + "options.cache" )
336
337 pkgconfig = env.ScanReplace( "libffado.pc.in" )
338 env.Install( env['libdir'] + '/pkgconfig', pkgconfig )
339
340 subdirs=['external','src','libffado','tests','support','doc']
341 if build_base:
342         env.SConscript( dirs=subdirs, exports="env", build_dir=build_base+subdir )
343 else:
344         env.SConscript( dirs=subdirs, exports="env" )
345
346 if 'debian' in COMMAND_LINE_TARGETS:
347         env.SConscript("deb/SConscript", exports="env")
348
349 # By default only src is built but all is cleaned
350 if not env.GetOption('clean'):
351     Default( 'external' )
352     Default( 'src' )
353     Default( 'support' )
354     if env['BUILD_TESTS']:
355         Default( 'tests' )
356
Note: See TracBrowser for help on using the browser.