root/trunk/libffado/SConstruct

Revision 847, 13.3 kB (checked in by ppalmers, 16 years ago)

use SSE2 for byteswaps (20% faster than ntohl())

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 if os.environ.has_key('XDG_CONFIG_DIRS'):
98         buildenv['XDG_CONFIG_DIRS']=os.environ['XDG_CONFIG_DIRS']
99 if os.environ.has_key('XDG_DATA_DIRS'):
100         buildenv['XDG_DATA_DIRS']=os.environ['XDG_DATA_DIRS']
101 if os.environ.has_key('HOME'):
102         buildenv['HOME']=os.environ['HOME']
103
104 env = Environment( tools=['default','scanreplace','pyuic','dbus','doxygen','pkgconfig'], toolpath=['admin'], ENV = buildenv, options=opts )
105
106
107 Help( """
108 For building ffado you can set different options as listed below. You have to
109 specify them only once, scons will save the last value you used and re-use
110 that.
111 To really undo your settings and return to the factory defaults, remove the
112 "cache"-folder and the file ".sconsign.dblite" from this directory.
113 For example with: "rm -Rf .sconsign.dblite cache"
114
115 Note that this is a development version! Don't complain if its not working!
116 See www.ffado.org for stable releases.
117 """ )
118 Help( opts.GenerateHelpText( env ) )
119
120 # make sure the necessary dirs exist
121 if not os.path.isdir( "cache/" + build_base ):
122         os.makedirs( "cache/" + build_base )
123 if not os.path.isdir( 'cache/objects' ):
124         os.makedirs( 'cache/objects' )
125
126 CacheDir( 'cache/objects' )
127
128 opts.Save( 'cache/' + build_base + "options.cache", env )
129
130 def ConfigGuess( context ):
131         context.Message( "Trying to find the system triple: " )
132         ret = os.popen( "admin/config.guess" ).read()[:-1]
133         context.Result( ret )
134         return ret
135
136 def CheckForApp( context, app ):
137         context.Message( "Checking wether '" + app + "' executes " )
138         ret = context.TryAction( app )
139         context.Result( ret[0] )
140         return ret[0]
141
142 tests = { "ConfigGuess" : ConfigGuess, "CheckForApp" : CheckForApp }
143 tests.update( env['PKGCONFIG_TESTS'] )
144 tests.update( env['PYUIC_TESTS'] )
145
146 conf = Configure( env,
147         custom_tests = tests,
148         conf_dir = "cache/" + build_base,
149         log_file = "cache/" + build_base + 'config.log' )
150
151 if not env.GetOption('clean'):
152         #
153         # Check if the environment can actually compile c-files by checking for a
154         # header shipped with gcc.
155         #
156         if not conf.CheckHeader( "stdio.h" ):
157                 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."
158                 Exit( 1 )
159
160         #
161         # The following checks are for headers and libs and packages we need.
162         #
163         allpresent = 1;
164         allpresent &= conf.CheckHeader( "expat.h" )
165         allpresent &= conf.CheckLib( 'expat', 'XML_ExpatVersion', '#include <expat.h>' )
166        
167         allpresent &= conf.CheckForPKGConfig();
168
169         pkgs = {
170                 'libraw1394' : '1.3.0',
171                 'libavc1394' : '0.5.3',
172                 'libiec61883' : '1.1.0',
173                 'alsa' : '1.0.0',
174                 'libxml++-2.6' : '2.13.0',
175                 'dbus-1' : '1.0',
176                 }
177         for pkg in pkgs:
178                 name2 = pkg.replace("+","").replace(".","").replace("-","").upper()
179                 env['%s_FLAGS' % name2] = conf.GetPKGFlags( pkg, pkgs[pkg] )
180                 if env['%s_FLAGS'%name2] == 0:
181                         allpresent &= 0
182
183         if not allpresent:
184                 print """
185 (At least) One of the dependencies is missing. I can't go on without it, please
186 install the needed packages (remember to also install the *-devel packages)
187 """
188                 Exit( 1 )
189
190         #
191         # Optional checks follow:
192         #
193         env['ALSA_SEQ_OUTPUT'] = conf.CheckLib( 'asound', symbol='snd_seq_event_output_direct', autoadd=0 )
194
195 if conf.CheckForApp( "which pyuic" ):
196         env['PYUIC'] = True
197
198 if conf.CheckForApp( "xdg-desktop-menu --help" ):
199         env['XDG_TOOLS'] = True
200
201 config_guess = conf.ConfigGuess()
202
203 env = conf.Finish()
204
205 if env['DEBUG']:
206         print "Doing a DEBUG build"
207         # -Werror could be added to, which would force the devs to really remove all the warnings :-)
208         env.AppendUnique( CCFLAGS=["-DDEBUG","-Wall","-g"] )
209         env.AppendUnique( CFLAGS=["-DDEBUG","-Wall","-g"] )
210 else:
211         env.AppendUnique( CCFLAGS=["-O2","-DNDEBUG"] )
212         env.AppendUnique( CFLAGS=["-O2","-DNDEBUG"] )
213
214 if env['PROFILE']:
215         print "Doing a PROFILE build"
216         # -Werror could be added to, which would force the devs to really remove all the warnings :-)
217         env.AppendUnique( CCFLAGS=["-Wall","-g"] )
218         env.AppendUnique( CFLAGS=["-Wall","-g"] )
219
220
221 # this is required to indicate that the DBUS version we use has support
222 # for platform dependent threading init functions
223 # this is true for DBUS >= 0.96 or so. Since we require >= 1.0 it is
224 # always true
225 env.AppendUnique( CCFLAGS=["-DDBUS_HAS_THREADS_INIT_DEFAULT"] )
226
227 if env['ENABLE_ALL']:
228         env['ENABLE_BEBOB'] = True
229         env['ENABLE_FIREWORKS'] = True
230         env['ENABLE_MOTU'] = True
231         env['ENABLE_DICE'] = True
232         env['ENABLE_METRIC_HALO'] = True
233         env['ENABLE_RME'] = True
234         env['ENABLE_BOUNCE'] = True
235
236 if env['ENABLE_BEBOB'] or env['ENABLE_DICE'] or env['ENABLE_BOUNCE'] or env['ENABLE_FIREWORKS']:
237         env['ENABLE_GENERICAVC'] = True
238
239 env['BUILD_STATIC_LIB'] = False
240 if env['BUILD_STATIC_TOOLS']:
241     print "Building static versions of the tools..."
242     env['BUILD_STATIC_LIB'] = True
243
244 if build_base:
245         env['build_base']="#/"+build_base
246 else:
247         env['build_base']="#/"
248
249 #
250 # XXX: Maybe we can even drop these lower-case variables and only use the uppercase ones?
251 #
252 env['bindir'] = Template( os.path.join( env['BINDIR'] ) ).safe_substitute( env )
253 env['libdir'] = Template( os.path.join( env['LIBDIR'] ) ).safe_substitute( env )
254 env['includedir'] = Template( os.path.join( env['INCLUDEDIR'] ) ).safe_substitute( env )
255 env['sharedir'] = Template( os.path.join( env['SHAREDIR'] ) ).safe_substitute( env )
256
257 env.Command( target=env['sharedir'], source="", action=Mkdir( env['sharedir'] ) )
258
259 env.Alias( "install", env['libdir'] )
260 env.Alias( "install", env['includedir'] )
261 env.Alias( "install", env['sharedir'] )
262 env.Alias( "install", env['bindir'] )
263
264 #
265 # shamelessly copied from the Ardour scons file
266 #
267
268 opt_flags = []
269 env['USE_SSE'] = 0
270
271 # guess at the platform, used to define compiler flags
272
273 config_cpu = 0
274 config_arch = 1
275 config_kernel = 2
276 config_os = 3
277 config = config_guess.split ("-")
278
279 # Autodetect
280 if env['DIST_TARGET'] == 'auto':
281     if re.search ("x86_64", config[config_cpu]) != None:
282         env['DIST_TARGET'] = 'x86_64'
283     elif re.search("i[0-5]86", config[config_cpu]) != None:
284         env['DIST_TARGET'] = 'i386'
285     else:
286         env['DIST_TARGET'] = 'i686'
287     print "Detected DIST_TARGET = " + env['DIST_TARGET']
288
289 if ((re.search ("i[0-9]86", config[config_cpu]) != None) or (re.search ("x86_64", config[config_cpu]) != None)):
290    
291     build_host_supports_sse = 0
292     build_host_supports_sse2 = 0
293
294     if config[config_kernel] == 'linux' :
295        
296         if env['DIST_TARGET'] != 'i386':
297            
298             flag_line = os.popen ("cat /proc/cpuinfo | grep '^flags'").read()[:-1]
299             x86_flags = flag_line.split (": ")[1:][0].split ()
300            
301             if "mmx" in x86_flags:
302                 opt_flags.append ("-mmmx")
303             if "sse" in x86_flags:
304                 build_host_supports_sse = 1
305             if "sse2" in x86_flags:
306                 build_host_supports_sse2 = 1
307             if "3dnow" in x86_flags:
308                 opt_flags.append ("-m3dnow")
309            
310             if config[config_cpu] == "i586":
311                 opt_flags.append ("-march=i586")
312             elif config[config_cpu] == "i686":
313                 opt_flags.append ("-march=i686")
314    
315     if ((env['DIST_TARGET'] == 'i686') or (env['DIST_TARGET'] == 'x86_64')) \
316        and build_host_supports_sse and env['ENABLE_OPTIMIZATIONS']:
317         opt_flags.extend (["-msse", "-mfpmath=sse"])
318         env['USE_SSE'] = 1
319
320     if ((env['DIST_TARGET'] == 'i686') or (env['DIST_TARGET'] == 'x86_64')) \
321        and build_host_supports_sse2 and env['ENABLE_OPTIMIZATIONS']:
322         opt_flags.extend (["-msse2"])
323         env['USE_SSE2'] = 1
324
325 # end of processor-specific section
326 if env['ENABLE_OPTIMIZATIONS']:
327     opt_flags.extend (["-fomit-frame-pointer","-ffast-math","-funroll-loops"])
328     env.AppendUnique( CCFLAGS=opt_flags )
329     env.AppendUnique( CFLAGS=opt_flags )
330     print "Doing an optimized build..."
331
332
333 env['REVISION'] = os.popen('svnversion .').read()[:-1]
334 # This may be as simple as '89' or as complex as '4123:4184M'.
335 # We'll just use the last bit.
336 env['REVISION'] = env['REVISION'].split(':')[-1]
337
338 if env['REVISION'] == 'exported':
339         env['REVISION'] = ''
340
341 env['FFADO_API_VERSION']="7"
342
343 env['PACKAGE'] = "libffado"
344 env['VERSION'] = "1.999.14"
345 env['LIBVERSION'] = "1.0.0"
346
347 #
348 # To have the top_srcdir as the doxygen-script is used from auto*
349 #
350 env['top_srcdir'] = env.Dir( "." ).abspath
351
352 #
353 # Start building
354 #
355 env.ScanReplace( "config.h.in" )
356 # ensure that the config.h is updated with the version
357 env.Depends( "config.h", "SConstruct" )
358 env.Depends( "config.h", 'cache/' + build_base + "options.cache" )
359
360 env.Depends( "libffado.pc", "SConstruct" )
361 pkgconfig = env.ScanReplace( "libffado.pc.in" )
362 env.Install( env['libdir'] + '/pkgconfig', pkgconfig )
363
364 subdirs=['external','src','libffado','tests','support','doc']
365 if build_base:
366         env.SConscript( dirs=subdirs, exports="env", build_dir=build_base+subdir )
367 else:
368         env.SConscript( dirs=subdirs, exports="env" )
369
370 if 'debian' in COMMAND_LINE_TARGETS:
371         env.SConscript("deb/SConscript", exports="env")
372
373 # By default only src is built but all is cleaned
374 if not env.GetOption('clean'):
375     Default( 'src' )
376     Default( 'support' )
377     if env['BUILD_TESTS']:
378         Default( 'tests' )
379 #
380 # Create a tags-file for easier emacs/vim-source-browsing
381 #  I don't know if the dependency is right...
382 #
383 findcommand = "find . \( -path \"*.h\" -o -path \"*.cpp\" -o -path \"*.c\" \) \! -path \"*.svn*\" \! -path \"./doc*\" \! -path \"./cache*\""
384 env.Command( "tags", "", findcommand + " |xargs ctags" )
385 env.Command( "TAGS", "", findcommand + " |xargs etags" )
386 env.AlwaysBuild( "tags", "TAGS" )
387 env.NoCache( "tags", "TAGS" )
388
Note: See TracBrowser for help on using the browser.