root/branches/libffado-2.0/SConstruct

Revision 1854, 19.6 kB (checked in by arnonym, 13 years ago)

If I understand it correctly, this should be everything that is needed to change the version-number.

Line 
1 #! /usr/bin/python
2 # -*- coding: utf-8 -*-
3 #
4 # Copyright (C) 2007, 2008, 2010 Arnold Krille
5 # Copyright (C) 2007, 2008 Pieter Palmers
6 # Copyright (C) 2008 Jonathan Woithe
7 #
8 # This file is part of FFADO
9 # FFADO = Free Firewire (pro-)audio drivers for linux
10 #
11 # FFADO is based upon FreeBoB.
12 #
13 # This program is free software: you can redistribute it and/or modify
14 # it under the terms of the GNU General Public License as published by
15 # the Free Software Foundation, either version 2 of the License, or
16 # (at your option) version 3 of the License.
17 #
18 # This program is distributed in the hope that it will be useful,
19 # but WITHOUT ANY WARRANTY; without even the implied warranty of
20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21 # GNU General Public License for more details.
22 #
23 # You should have received a copy of the GNU General Public License
24 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
25 #
26
27 FFADO_API_VERSION = "8"
28 FFADO_VERSION = "2.0.1"
29
30 import os
31 import re
32 from string import Template
33 import imp
34
35 if not os.path.isdir( "cache" ):
36         os.makedirs( "cache" )
37
38 opts = Options( "cache/options.cache" )
39
40 opts.AddOptions(
41         BoolOption( "DEBUG", """\
42 Toggle debug-build. DEBUG means \"-g -Wall\" and more, otherwise we will use
43   \"-O2\" to optimize.""", False ),
44         BoolOption( "PROFILE", "Build with symbols and other profiling info", False ),
45         PathOption( "PREFIX", "The prefix where ffado will be installed to.", "/usr/local", PathOption.PathAccept ),
46         PathOption( "BINDIR", "Overwrite the directory where apps are installed to.", "$PREFIX/bin", PathOption.PathAccept ),
47         PathOption( "LIBDIR", "Overwrite the directory where libs are installed to.", "$PREFIX/lib", PathOption.PathAccept ),
48         PathOption( "INCLUDEDIR", "Overwrite the directory where headers are installed to.", "$PREFIX/include", PathOption.PathAccept ),
49         PathOption( "SHAREDIR", "Overwrite the directory where misc shared files are installed to.", "$PREFIX/share/libffado", PathOption.PathAccept ),
50         BoolOption( "ENABLE_BEBOB", "Enable/Disable the bebob part.", True ),
51         BoolOption( "ENABLE_FIREWORKS", "Enable/Disable the ECHO Audio FireWorks AV/C part.", True ),
52         BoolOption( "ENABLE_MOTU", "Enable/Disable the MOTU part.", True ),
53         BoolOption( "ENABLE_GENERICAVC", """\
54 Enable/Disable the the generic avc part (mainly used by apple).
55   Note that disabling this option might be overwritten by other devices needing
56   this code.""", False ),
57         BoolOption( "ENABLE_ALL", "Enable/Disable support for all devices.", False ),
58         BoolOption( "SERIALIZE_USE_EXPAT", "Use libexpat for XML serialization.", False ),
59         BoolOption( "BUILD_TESTS", """\
60 Build the tests in their directory. As some contain quite some functionality,
61   this is on by default.
62   If you just want to use ffado with jack without the tools, you can disable this.\
63 """, True ),
64         BoolOption( "BUILD_STATIC_TOOLS", "Build a statically linked version of the FFADO tools.", False ),
65         EnumOption('DIST_TARGET', 'Build target for cross compiling packagers', 'auto', allowed_values=('auto', 'i386', 'i686', 'x86_64', 'powerpc', 'powerpc64', 'none' ), ignorecase=2),
66         BoolOption( "ENABLE_OPTIMIZATIONS", "Enable optimizations and the use of processor specific extentions (MMX/SSE/...).", False ),
67         BoolOption( "PEDANTIC", "Enable -Werror and more pedantic options during compile.", False ),
68         ( "COMPILE_FLAGS", "Add additional flags to the environment.\nOnly meant for distributors and gentoo-users who want to over-optimize their built.\n Using this is not supported by the ffado-devs!" ),
69
70         )
71
72 ## Load the builders in config
73 buildenv=os.environ
74
75 env = Environment( tools=['default','scanreplace','pyuic','pyuic4','dbus','doxygen','pkgconfig'], toolpath=['admin'], ENV = buildenv, options=opts )
76
77 if env.has_key('COMPILE_FLAGS') and len(env['COMPILE_FLAGS']) > 0:
78         print '''
79  * Usage of additional flags is not supported by the ffado-devs.
80  * Use at own risk!
81  *
82  * Currentl value is '%s'
83  ''' % env['COMPILE_FLAGS']
84         env.MergeFlags(env['COMPILE_FLAGS'])
85
86 Help( """
87 For building ffado you can set different options as listed below. You have to
88 specify them only once, scons will save the last value you used and re-use
89 that.
90 To really undo your settings and return to the factory defaults, remove the
91 "cache"-folder and the file ".sconsign.dblite" from this directory.
92 For example with: "rm -Rf .sconsign.dblite cache"
93
94 Note that this is a development version! Don't complain if its not working!
95 See www.ffado.org for stable releases.
96 """ )
97 Help( opts.GenerateHelpText( env ) )
98
99 # make sure the necessary dirs exist
100 if not os.path.isdir( "cache" ):
101         os.makedirs( "cache" )
102 if not os.path.isdir( 'cache/objects' ):
103         os.makedirs( 'cache/objects' )
104
105 CacheDir( 'cache/objects' )
106
107 opts.Save( 'cache/options.cache', env )
108
109 def ConfigGuess( context ):
110         context.Message( "Trying to find the system triple: " )
111         ret = os.popen( "admin/config.guess" ).read()[:-1]
112         context.Result( ret )
113         return ret
114
115 def CheckForApp( context, app ):
116         context.Message( "Checking whether '" + app + "' executes " )
117         ret = context.TryAction( app )
118         context.Result( ret[0] )
119         return ret[0]
120
121 def CheckForPyModule( context, module ):
122         context.Message( "Checking for the python module '" + module + "' " )
123         ret = context.TryAction( "python $SOURCE", "import %s" % module, ".py" )
124         context.Result( ret[0] )
125         return ret[0]
126
127 def CompilerCheck( context ):
128         context.Message( "Checking for a working C-compiler " )
129         ret = context.TryRun( """
130 #include <stdio.h>
131
132 int main() {
133         printf( "Hello World!" );
134         return 0;
135 }""", '.c' )[0]
136         context.Result( ret )
137         if ret == 0:
138                 return False;
139         context.Message( "Checking for a working C++-compiler " )
140         ret = context.TryRun( """
141 #include <iostream>
142
143 int main() {
144         std::cout << "Hello World!" << std::endl;
145         return 0;
146 }""", ".cpp" )[0]
147         context.Result( ret )
148         return ret
149
150 tests = {
151         "ConfigGuess" : ConfigGuess,
152         "CheckForApp" : CheckForApp,
153         "CheckForPyModule": CheckForPyModule,
154         "CompilerCheck" : CompilerCheck,
155 }
156 tests.update( env['PKGCONFIG_TESTS'] )
157 tests.update( env['PYUIC_TESTS'] )
158 tests.update( env['PYUIC4_TESTS'] )
159
160 conf = Configure( env,
161         custom_tests = tests,
162         conf_dir = "cache/",
163         log_file = 'cache/config.log' )
164
165 if env['SERIALIZE_USE_EXPAT']:
166         env['SERIALIZE_USE_EXPAT']=1
167 else:
168         env['SERIALIZE_USE_EXPAT']=0
169
170 if not env.GetOption('clean'):
171         #
172         # Check for working gcc and g++ compilers and their environment.
173         #
174         if not conf.CompilerCheck():
175                 print "\nIt seems as if your system isn't even able to compile any C-/C++-programs. Probably you don't have gcc and g++ installed. Compiling a package from source without a working compiler is very hard to do, please install the needed packages.\nHint: on *ubuntu you need both gcc- and g++-packages installed, easiest solution is to install build-essential which depends on gcc and g++."
176                 Exit( 1 )
177
178         # Check for pkg-config before using pkg-config to check for other dependencies.
179         if not conf.CheckForPKGConfig():
180                 print "\nThe program 'pkg-config' could not be found.\nEither you have to install the corresponding package first or make sure that PATH points to the right directions."
181                 Exit( 1 )
182
183         #
184         # The following checks are for headers and libs and packages we need.
185         #
186         allpresent = 1;
187         # for DBUS C++ bindings
188         allpresent &= conf.CheckHeader( "expat.h" )
189         allpresent &= conf.CheckLib( 'expat', 'XML_ExpatVersion', '#include <expat.h>' )
190        
191         pkgs = {
192                 'libraw1394' : '1.3.0',
193                 'libiec61883' : '1.1.0',
194                 'dbus-1' : '1.0',
195                 }
196         if not env['SERIALIZE_USE_EXPAT']:
197                 pkgs['libxml++-2.6'] = '2.13.0'
198
199         for pkg in pkgs:
200                 name2 = pkg.replace("+","").replace(".","").replace("-","").upper()
201                 env['%s_FLAGS' % name2] = conf.GetPKGFlags( pkg, pkgs[pkg] )
202                 if env['%s_FLAGS'%name2] == 0:
203                         allpresent &= 0
204
205         if not allpresent:
206                 print """
207 (At least) One of the dependencies is missing. I can't go on without it, please
208 install the needed packages for each of the lines saying "no".
209 (Remember to also install the *-devel packages!)
210
211 And remember to remove the cache with "rm -Rf .sconsign.dblite cache" so the
212 results above get rechecked.
213 """
214                 Exit( 1 )
215
216         # Check for C99 lrint() and lrintf() functions used to convert from
217         # float to integer more efficiently via float_cast.h.  If not
218         # present the standard slower methods will be used instead.  This
219         # might not be the best way of testing for these but it's the only
220         # way which seems to work properly.  CheckFunc() fails due to
221         # argument count problems.
222         if env.has_key( 'CFLAGS' ):
223                 oldcf = env['CFLAGS']
224         else:
225                 oldcf = ""
226         oldcf = env.Append(CFLAGS = '-std=c99')
227         if conf.CheckLibWithHeader( "m", "math.h", "c", "lrint(3.2);" ):
228                 HAVE_LRINT = 1
229         else:
230                 HAVE_LRINT = 0
231         if conf.CheckLibWithHeader( "m", "math.h", "c", "lrintf(3.2);" ):
232                 HAVE_LRINTF = 1
233         else:
234                 HAVE_LRINTF = 0
235         env['HAVE_LRINT'] = HAVE_LRINT;
236         env['HAVE_LRINTF'] = HAVE_LRINTF;
237         env.Replace(CFLAGS=oldcf)
238
239 #
240 # Optional checks follow:
241 #
242
243 # PyQT checks
244 build_mixer = False
245 if conf.CheckForApp( 'which pyuic4' ) and conf.CheckForPyModule( 'dbus' ) and conf.CheckForPyModule( 'PyQt4' ) and conf.CheckForPyModule( 'dbus.mainloop.qt' ):
246         env['PYUIC4'] = True
247         build_mixer = True
248
249 if conf.CheckForApp( 'which pyuic' ) and conf.CheckForPyModule( 'dbus' ) and conf.CheckForPyModule( 'qt' ):
250         env['PYUIC'] = True
251         build_mixer = True
252
253 if conf.CheckForApp( 'xdg-desktop-menu --help' ):
254         env['XDG_TOOLS'] = True
255 else:
256         print """
257 I couldn't find the program 'xdg-desktop-menu'. Together with xdg-icon-resource
258 this is needed to add the fancy entry to your menu. But the mixer will be installed, you can start it by executing "ffado-mixer".
259 """
260
261 if not build_mixer and not env.GetOption('clean'):
262         print """
263 I couldn't find all the prerequisites ('pyuic' / 'pyuic4' and the python-modules 'dbus' and
264 'qt' / 'PyQt4', the packages could be named like dbus-python and PyQt) to build the mixer.
265 Therefor neither the qt3 nor the qt4 mixer will get installed.
266 """
267
268 config_guess = conf.ConfigGuess()
269
270 env = conf.Finish()
271
272 if env['DEBUG']:
273         print "Doing a DEBUG build"
274         env.MergeFlags( "-DDEBUG -Wall -g" )
275 else:
276         env.MergeFlags( "-O2 -DNDEBUG" )
277
278 if env['PROFILE']:
279         print "Doing a PROFILE build"
280         env.MergeFlags( "-Wall -g" )
281
282
283 # this is required to indicate that the DBUS version we use has support
284 # for platform dependent threading init functions
285 # this is true for DBUS >= 0.96 or so. Since we require >= 1.0 it is
286 # always true
287 env.MergeFlags( "-DDBUS_HAS_THREADS_INIT_DEFAULT" )
288
289 if env['ENABLE_ALL']:
290         env['ENABLE_BEBOB'] = True
291         env['ENABLE_FIREWORKS'] = True
292         env['ENABLE_MOTU'] = True
293
294 if env['ENABLE_BEBOB'] or env['ENABLE_FIREWORKS']:
295         env['ENABLE_GENERICAVC'] = True
296
297 env['BUILD_STATIC_LIB'] = False
298 if env['BUILD_STATIC_TOOLS']:
299     print "Building static versions of the tools..."
300     env['BUILD_STATIC_LIB'] = True
301
302 env['build_base']="#/"
303
304 #
305 # Get the DESTDIR (if wanted) from the commandline
306 #
307 env.destdir = ARGUMENTS.get( 'DESTDIR', "" )
308
309 #
310 # Uppercase variables are for usage in code, lowercase versions for usage in
311 # scons-files for installing.
312 #
313 env['BINDIR'] = Template( env['BINDIR'] ).safe_substitute( env )
314 env['LIBDIR'] = Template( env['LIBDIR'] ).safe_substitute( env )
315 env['INCLUDEDIR'] = Template( env['INCLUDEDIR'] ).safe_substitute( env )
316 env['SHAREDIR'] = Template( env['SHAREDIR'] ).safe_substitute( env )
317 env['bindir'] = Template( env.destdir + env['BINDIR'] ).safe_substitute( env )
318 env['libdir'] = Template( env.destdir + env['LIBDIR'] ).safe_substitute( env )
319 env['includedir'] = Template( env.destdir + env['INCLUDEDIR'] ).safe_substitute( env )
320 env['sharedir'] = Template( env.destdir + env['SHAREDIR'] ).safe_substitute( env )
321
322 env.Command( target=env['sharedir'], source="", action=Mkdir( env['sharedir'] ) )
323
324 env.Alias( "install", env['libdir'] )
325 env.Alias( "install", env['includedir'] )
326 env.Alias( "install", env['sharedir'] )
327 env.Alias( "install", env['bindir'] )
328
329 #
330 # shamelessly copied from the Ardour scons file
331 #
332
333 opt_flags = []
334 env['USE_SSE'] = 0
335
336 # guess at the platform, used to define compiler flags
337
338 config_cpu = 0
339 config_arch = 1
340 config_kernel = 2
341 config_os = 3
342 config = config_guess.split ("-")
343
344 needs_fPIC = False
345
346 # Autodetect
347 if env['DIST_TARGET'] == 'auto':
348     if re.search ("x86_64", config[config_cpu]) != None:
349         env['DIST_TARGET'] = 'x86_64'
350     elif re.search("i[0-5]86", config[config_cpu]) != None:
351         env['DIST_TARGET'] = 'i386'
352     elif re.search("i686", config[config_cpu]) != None:
353         env['DIST_TARGET'] = 'i686'
354     elif re.search("powerpc64", config[config_cpu]) != None:
355         env['DIST_TARGET'] = 'powerpc64'
356     elif re.search("powerpc", config[config_cpu]) != None:
357         env['DIST_TARGET'] = 'powerpc'
358     else:
359         env['DIST_TARGET'] = config[config_cpu]
360     print "Detected DIST_TARGET = " + env['DIST_TARGET']
361
362 if ((re.search ("i[0-9]86", config[config_cpu]) != None) or (re.search ("x86_64", config[config_cpu]) != None) or (re.search ("powerpc", config[config_cpu]) != None)):
363    
364     build_host_supports_sse = 0
365     build_host_supports_sse2 = 0
366     build_host_supports_sse3 = 0
367
368     if config[config_kernel] == 'linux' :
369        
370         if (env['DIST_TARGET'] == 'i686') or (env['DIST_TARGET'] == 'x86_64'):
371            
372             flag_line = os.popen ("cat /proc/cpuinfo | grep '^flags'").read()[:-1]
373             x86_flags = flag_line.split (": ")[1:][0].split ()
374            
375             if "mmx" in x86_flags:
376                 opt_flags.append ("-mmmx")
377             if "sse" in x86_flags:
378                 build_host_supports_sse = 1
379             if "sse2" in x86_flags:
380                 build_host_supports_sse2 = 1
381             #if "sse3" in x86_flags:
382                 #build_host_supports_sse3 = 1
383             if "3dnow" in x86_flags:
384                 opt_flags.append ("-m3dnow")
385            
386             if config[config_cpu] == "i586":
387                 opt_flags.append ("-march=i586")
388             elif config[config_cpu] == "i686":
389                 opt_flags.append ("-march=i686")
390
391         elif (env['DIST_TARGET'] == 'powerpc') or (env['DIST_TARGET'] == 'powerpc64'):
392
393             cpu_line = os.popen ("cat /proc/cpuinfo | grep '^cpu'").read()[:-1]
394
395             ppc_type = cpu_line.split (": ")[1]
396             if re.search ("altivec", ppc_type) != None:
397                 opt_flags.append ("-maltivec")
398                 opt_flags.append ("-mabi=altivec")
399
400             ppc_type = ppc_type.split (", ")[0]
401             if re.match ("74[0145][0578]A?", ppc_type) != None:
402                 opt_flags.append ("-mcpu=7400")
403                 opt_flags.append ("-mtune=7400")
404             elif re.match ("750", ppc_type) != None:
405                 opt_flags.append ("-mcpu=750")
406                 opt_flags.append ("-mtune=750")
407             elif re.match ("PPC970", ppc_type) != None:
408                 opt_flags.append ("-mcpu=970")
409                 opt_flags.append ("-mtune=970")
410             elif re.match ("Cell Broadband Engine", ppc_type) != None:
411                 opt_flags.append ("-mcpu=cell")
412                 opt_flags.append ("-mtune=cell")
413
414     if ((env['DIST_TARGET'] == 'i686') or (env['DIST_TARGET'] == 'x86_64')) \
415        and build_host_supports_sse and env['ENABLE_OPTIMIZATIONS']:
416         opt_flags.extend (["-msse", "-mfpmath=sse"])
417         env['USE_SSE'] = 1
418
419     if ((env['DIST_TARGET'] == 'i686') or (env['DIST_TARGET'] == 'x86_64')) \
420        and build_host_supports_sse2 and env['ENABLE_OPTIMIZATIONS']:
421         opt_flags.extend (["-msse2"])
422         env['USE_SSE2'] = 1
423
424     #if ((env['DIST_TARGET'] == 'i686') or (env['DIST_TARGET'] == 'x86_64')) \
425        #and build_host_supports_sse2 and env['ENABLE_OPTIMIZATIONS']:
426         #opt_flags.extend (["-msse3"])
427         #env['USE_SSE3'] = 1
428
429     # build for 64-bit userland?
430     if env['DIST_TARGET'] == "powerpc64":
431         print "Doing a 64-bit PowerPC build"
432         env.MergeFlags( "-m64" )
433     elif env['DIST_TARGET'] == "x86_64":
434         print "Doing a 64-bit x86 build"
435         env.MergeFlags( "-m64" )
436         needs_fPIC = True
437     else:
438         print "Doing a 32-bit build"
439         env.MergeFlags( "-m32" )
440
441 if needs_fPIC or ( env.has_key('COMPILE_FLAGS') and '-fPIC' in env['COMPILE_FLAGS'] ):
442     env.MergeFlags( "-fPIC" )
443
444 # end of processor-specific section
445 if env['ENABLE_OPTIMIZATIONS']:
446     opt_flags.extend (["-fomit-frame-pointer","-ffast-math","-funroll-loops"])
447     env.MergeFlags( opt_flags )
448     print "Doing an optimized build..."
449
450 env['REVISION'] = os.popen('svnversion .').read()[:-1]
451 # This may be as simple as '89' or as complex as '4123:4184M'.
452 # We'll just use the last bit.
453 env['REVISION'] = env['REVISION'].split(':')[-1]
454
455 # try to circumvent localized versions
456 if len(env['REVISION']) >= 5 and env['REVISION'][0:6] == 'export':
457         env['REVISION'] = ''
458
459 # avoid the 1.999.41- type of version for exported versions
460 if env['REVISION'] != '':
461         env['REVISIONSTRING'] = '-' + env['REVISION']
462 else:
463         env['REVISIONSTRING'] = ''
464
465 env['FFADO_API_VERSION'] = FFADO_API_VERSION
466
467 env['PACKAGE'] = "libffado"
468 env['VERSION'] = FFADO_VERSION
469 env['LIBVERSION'] = "1.0.0"
470
471 env['CONFIGDIR'] = "~/.ffado"
472 env['CACHEDIR'] = "~/.ffado"
473
474 env['USER_CONFIG_FILE'] = env['CONFIGDIR'] + "/configuration"
475 env['SYSTEM_CONFIG_FILE'] = env['SHAREDIR'] + "/configuration"
476
477 env['REGISTRATION_URL'] = "http://ffado.org/deviceregistration/register.php?action=register"
478
479 #
480 # To have the top_srcdir as the doxygen-script is used from auto*
481 #
482 env['top_srcdir'] = env.Dir( "." ).abspath
483
484 #
485 # Start building
486 #
487 env.ScanReplace( "config.h.in" )
488 # ensure that the config.h is updated with the version
489
490 env.Depends( "config.h", "SConstruct" )
491 env.Depends( "config.h", 'cache/options.cache' )
492
493 # update config.h whenever the SVN revision changes
494 env.Depends( "config.h", env.Value(env['REVISION']))
495
496 env.Depends( "libffado.pc", "SConstruct" )
497 pkgconfig = env.ScanReplace( "libffado.pc.in" )
498 env.Install( env['libdir'] + '/pkgconfig', pkgconfig )
499
500 env.Install( env['sharedir'], 'configuration' )
501
502 subdirs=['external','src','libffado','support','doc']
503 if env['BUILD_TESTS']:
504         subdirs.append('tests')
505
506 env.SConscript( dirs=subdirs, exports="env" )
507
508 # By default only src is built but all is cleaned
509 if not env.GetOption('clean'):
510     Default( 'src' )
511     Default( 'support' )
512     if env['BUILD_TESTS']:
513         Default( 'tests' )
514
515 #
516 # Deal with the DESTDIR vs. xdg-tools conflict (which is basicely that the
517 # xdg-tools can't deal with DESTDIR, so the packagers have to deal with this
518 # their own :-/
519 #
520 if len(env.destdir) > 0:
521         if not len( ARGUMENTS.get( "WILL_DEAL_WITH_XDG_MYSELF", "" ) ) > 0:
522                 print """
523 WARNING!
524 You are using the (packagers) option DESTDIR to install this package to a
525 different place than the real prefix. As the xdg-tools can't cope with
526 that, the .desktop-files are not installed by this build, you have to
527 deal with them your own.
528 (And you have to look into the SConstruct to learn how to disable this
529 message.)
530 """
531 else:
532
533         def CleanAction( action ):
534                 if env.GetOption( "clean" ):
535                         env.Execute( action )
536
537         if env.has_key( 'XDG_TOOLS' ) and env.has_key( 'PYUIC4' ):
538                 if not env.GetOption("clean"):
539                         action = "install"
540                 else:
541                         action = "uninstall"
542                 mixerdesktopaction = env.Action( "xdg-desktop-menu %s support/xdg/ffado.org-ffadomixer.desktop" % action )
543                 mixericonaction = env.Action( "xdg-icon-resource %s --size 64 --novendor --context apps support/xdg/hi64-apps-ffado.png ffado" % action )
544                 env.Command( "__xdgstuff1", None, mixerdesktopaction )
545                 env.Command( "__xdgstuff2", None, mixericonaction )
546                 env.Alias( "install", ["__xdgstuff1", "__xdgstuff2" ] )
547                 CleanAction( mixerdesktopaction )
548                 CleanAction( mixericonaction )
549
550 #
551 # Create a tags-file for easier emacs/vim-source-browsing
552 #  I don't know if the dependency is right...
553 #
554 findcommand = "find . \( -path \"*.h\" -o -path \"*.cpp\" -o -path \"*.c\" \) \! -path \"*.svn*\" \! -path \"./doc*\" \! -path \"./cache*\""
555 env.Command( "tags", "", findcommand + " |xargs ctags" )
556 env.Command( "TAGS", "", findcommand + " |xargs etags" )
557 env.AlwaysBuild( "tags", "TAGS" )
558 if 'NoCache' in dir(env):
559     env.NoCache( "tags", "TAGS" )
560
561 # Another convinience target
562 if env.GetOption( "clean" ):
563         env.Execute( "rm cache/objects -Rf" )
564
Note: See TracBrowser for help on using the browser.