root/trunk/libffado/SConstruct

Revision 855, 15.0 kB (checked in by arnonym, 16 years ago)

move the xdg-stuff to an own distinct dir, so its easier for packagers to recognize:-P

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