4 Experimental scons (www.scons.org) building.
10 build from source directory ./TARGET (not recursive)
14 scons [config] # configure
19 run=$(pwd)/out-scons/usr
20 export LOCALE=$run/share/locale
21 export TEXMF='{'$run/share/lilypond,$(kpsexpand '$TEXMF')'}'
24 #optionally, if you do not use custom.py below
25 #export LILYPONDPREFIX=$run/share/lilypond
27 lilypond-bin input/simple
30 scons mf-essential # build minimal mf stuff
32 scons doc # build web doc
33 scons config # reconfigure
34 scons install # install
38 scons / # build *everything* (including installation)
40 Options (see scons -h)
41 scons build=DIR # clean srcdir build, output below DIR
42 scons out=DIR # write output for alterative config to DIR
56 os.path.join (os.getcwd (), '=install')
57 prefix=os.path.join (os.environ['HOME'], 'usr', 'pkg', 'lilypond')
65 # * more program configure tests (mfont, ...?)
69 # * split doc target: doc input examples mutopia?
71 # * grep FIXME $(find . -name 'S*t')
83 EnsureSConsVersion (0, 95)
86 scons [KEY=VALUE].. [TARGET|DIR]..
88 TARGETS: clean, config, doc, dist, install, mf-essential, po-update,
89 realclean, release, sconsclean, tar, TAGS
94 config_cache = 'scons.cache'
110 # Put your favourite stuff in custom.py
111 opts = Options ([config_cache, 'custom.py'], ARGUMENTS)
112 opts.Add ('prefix', 'Install prefix', '/usr/')
113 opts.Add ('out', 'Output directory', 'out-scons')
114 opts.Add ('build', 'Build directory', '.')
115 opts.Add ('DESTDIR', 'DESTDIR prepended to prefix', '')
117 BoolOption ('warnings', 'compile with -Wall and similiar',
119 BoolOption ('debugging', 'compile with debugging symbols',
121 BoolOption ('optimising', 'compile with optimising',
123 BoolOption ('shared', 'build shared libraries',
125 BoolOption ('static', 'build static libraries',
127 BoolOption ('gui', 'build with GNOME backend (EXPERIMENTAL)',
129 BoolOption ('verbose', 'run commands with verbose flag',
131 BoolOption ('checksums', 'use checksums instead of timestamps',
135 srcdir = Dir ('.').srcnode ().abspath
137 sys.path.append (os.path.join (srcdir, 'stepmake', 'bin'))
139 package = packagepython.Package (srcdir)
140 version = packagepython.version_tuple_to_str (package.version)
142 ENV = { 'PATH' : os.environ['PATH'] }
143 for key in ['LD_LIBRARY_PATH', 'GUILE_LOAD_PATH', 'PKG_CONFIG_PATH']:
144 if os.environ.has_key (key):
145 ENV[key] = os.environ[key]
151 PERL = '/usr/bin/perl',
152 PYTHON = '/usr/bin/python',
155 MAKEINFO = 'LANG= makeinfo',
156 MF_TO_TABLE_PY = srcdir + '/buildscripts/mf-to-table.py',
158 PKG_CONFIG_PATH = [os.path.join (os.environ['HOME'],
159 'usr/pkg/gnome/lib'),
160 os.path.join (os.environ['HOME'],
161 'usr/pkg/pango/lib')],
164 TOPLEVEL_VERSION = version,
167 # Hardcoded usability switch (Anthony Roach).
168 # See http://www.scons.org/cgi-bin/wiki/GoFastButton
169 # First do: scons realclean .
172 # Add all config_vars to opts, so that they will be read and saved
173 # together with the other configure options.
174 map (lambda x: opts.AddOptions ((x,)), config_vars)
176 Help (usage + opts.GenerateHelpText (env))
182 SetOption ('max_drift', 1)
183 # SetOption ('implicit_deps_unchanged', 1)
184 print "If scons feels slow, use --implicit-deps-unchanged"
185 elif env['checksums']:
186 # Always use checksums (makes more sense than timestamps).
187 SetOption ('max_drift', 0)
188 # Using *content* checksums prevents rebuilds after
189 # [re]configure if config.hh has not changed. Too bad that it
191 TargetSignatures ('content')
193 absbuild = Dir (env['build']).abspath
194 outdir = os.path.join (Dir (env['build']).abspath, env['out'])
195 run_prefix = os.path.join (absbuild, os.path.join (env['out'], 'usr'))
198 config_hh = os.path.join (outdir, 'config.hh')
199 version_hh = os.path.join (outdir, 'version.hh')
201 env.Alias ('config', config_cache)
203 cachedir = os.path.join (outdir, 'build-cache')
205 if not os.path.exists(cachedir):
206 os.makedirs(cachedir)
208 CacheDir (os.path.join (outdir, 'build-cache'))
210 # No need to set $LILYPONDPREFIX to run lily, but cannot install...
211 if env['debugging'] and not 'install' in COMMAND_LINE_TARGETS:
212 env['prefix'] = run_prefix
214 prefix = env['prefix']
215 bindir = os.path.join (prefix, 'bin')
216 sharedir = os.path.join (prefix, 'share')
217 libdir = os.path.join (prefix, 'lib')
218 localedir = os.path.join (sharedir, 'locale')
219 sharedir_doc_package = os.path.join (sharedir, 'doc', package.name)
220 sharedir_package = os.path.join (sharedir, package.name)
221 sharedir_package_version = os.path.join (sharedir_package, version)
222 lilypondprefix = sharedir_package_version
237 def configure (target, source, env):
238 vre = re.compile ('^.*[^-.0-9]([0-9][0-9]*\.[0-9][.0-9]*).*$', re.DOTALL)
239 def get_version (program):
240 command = '(%(program)s --version || %(program)s -V) 2>&1' % vars ()
241 pipe = os.popen (command)
242 output = pipe.read ()
245 v = re.sub (vre, '\\1', output)
246 return string.split (v, '.')
248 def test_program (lst, program, minimal, description, package):
249 sys.stdout.write ('Checking %s version... ' % program)
250 actual = get_version (program)
253 lst.append ((description, package, minimal, program,
256 sys.stdout.write (string.join (actual, '.'))
257 sys.stdout.write ('\n')
258 if actual < string.split (minimal, '.'):
259 lst.append ((description, package, minimal, program,
260 string.join (actual, '.')))
262 for i in ['bash', 'perl', 'python', 'sh']:
263 sys.stdout.write ('Checking for %s... ' % i)
265 key = string.upper (i)
270 sys.stdout.write ('not found: %s (using: %s)' \
273 sys.stdout.write ('\n')
276 test_program (required, 'gcc', '2.8', 'GNU C compiler', 'gcc')
277 test_program (required, 'g++', '3.0.5', 'GNU C++ compiler', 'g++')
278 test_program (required, 'python', '2.1', 'Python (www.python.org)', 'python')
279 test_program (required, 'guile-config', '1.6', 'GUILE development',
280 'libguile-dev or guile-devel')
281 # Do not use bison 1.50 and 1.75.
282 test_program (required, 'bison', '1.25', 'Bison -- parser generator',
284 test_program (required, 'flex', '0.0', 'Flex -- lexer generator', 'flex')
288 test_program (optional, 'makeinfo', '4.7', 'Makeinfo tool', 'texinfo')
289 test_program (optional, 'guile', '1.6', 'GUILE scheme',
290 'libguile-dev or guile-devel')
291 test_program (optional, 'mftrace', '1.0.27', 'Metafont tracing Type1',
293 test_program (optional, 'perl', '4.0',
294 'Perl practical efficient readonly language', 'perl')
295 #test_program (optional, 'foo', '2.0', 'Foomatic tester', 'bar')
297 def CheckYYCurrentBuffer (context):
298 context.Message ('Checking for yy_current_buffer... ')
299 ret = conf.TryCompile ("""using namespace std;
300 #include <FlexLexer.h>
301 class yy_flex_lexer: public yyFlexLexer
306 yy_current_buffer = 0;
312 conf = Configure (env, custom_tests = { 'CheckYYCurrentBuffer'
313 : CheckYYCurrentBuffer })
316 'DIRSEP' : "'%s'" % os.sep,
317 'PATHSEP' : "'%s'" % os.pathsep,
318 'TOPLEVEL_VERSION' : '"' + version + '"',
319 'PACKAGE': '"' + package.name + '"',
320 'DATADIR' : '"' + sharedir + '"',
321 'LILYPOND_DATADIR' : '"' + sharedir_package + '"',
322 'LOCAL_LILYPOND_DATADIR' : '"' + sharedir_package_version + '"',
323 'LOCALEDIR' : '"' + localedir + '"',
325 conf.env.Append (DEFINES = defines)
327 command = r"""python -c 'import sys; sys.stdout.write ("%s/include/python%s" % (sys.prefix, sys.version[:3]))'""" #"
328 PYTHON_INCLUDE = os.popen (command).read ()
330 env.Append (CCFLAGS = ['-I%s ' % PYTHON_INCLUDE])
332 env.Append (CPPPATH = PYTHON_INCLUDE)
334 headers = ('sys/stat.h', 'assert.h', 'kpathsea/kpathsea.h', 'Python.h')
336 if conf.CheckCHeader (i):
337 key = re.sub ('[./]', '_', 'HAVE_' + string.upper (i))
338 conf.env['DEFINES'][key] = 1
340 ccheaders = ('sstream',)
342 if conf.CheckCXXHeader (i):
343 key = re.sub ('[./]', '_', 'HAVE_' + string.upper (i))
344 conf.env['DEFINES'][key] = 1
346 functions = ('gettext', 'isinf', 'memmem', 'snprintf', 'vsnprintf')
348 if 0 or conf.CheckFunc (i):
349 key = re.sub ('[./]', '_', 'HAVE_' + string.upper (i))
350 conf.env['DEFINES'][key] = 1
352 if conf.CheckYYCurrentBuffer ():
353 conf.env['DEFINES']['HAVE_FLEXLEXER_YY_CURRENT_BUFFER'] = 1
355 if conf.CheckLib ('dl'):
358 if conf.CheckLib ('kpathsea'):
359 conf.env['DEFINES']['KPATHSEA'] = 1
362 if conf.CheckLib ('kpathsea', 'kpse_find_file'):
363 conf.env['DEFINES']['HAVE_KPSE_FIND_FILE'] = '1'
364 if conf.CheckLib ('kpathsea', 'kpse_find_tfm'):
365 conf.env['DEFINES']['HAVE_KPSE_FIND_TFM'] = '1'
369 if env.has_key ('CPPPATH'):
370 cpppath = env['CPPPATH']
371 #this could happen after flower...
372 env.ParseConfig ('guile-config compile')
374 #this could happen only for compiling pango-*
376 env.ParseConfig ('pkg-config --cflags --libs gtk+-2.0')
377 env.ParseConfig ('pkg-config --cflags --libs pango')
378 if conf.CheckCHeader ('pango/pangofc-fontmap.h'):
379 conf.env['DEFINES']['HAVE_PANGO_PANGOFC_FONTMAP_H'] = '1'
381 if conf.CheckLib ('pango-1.0',
382 'pango_fc_font_map_add_decoder_find_func'):
383 conf.env['DEFINES']['HAVE_PANGO_CVS'] = '1'
384 conf.env['DEFINES']['HAVE_PANGO_FC_FONT_MAP_ADD_DECODER_FIND_FUNC'] = '1'
387 # Using CCFLAGS = -I<system-dir> rather than CPPPATH = [
388 # <system-dir>] speeds up SCons
389 env['CCFLAGS'] += map (lambda x: '-I' + x,
390 env['CPPPATH'][len (cpppath):])
391 env['CPPPATH'] = cpppath
395 print '********************************'
396 print 'Please install required packages'
398 print '%s: %s-%s or newer (found: %s %s)' % i
403 print '*************************************'
404 print 'Consider installing optional packages'
406 print '%s: %s-%s or newer (found: %s %s)' % i
408 return conf.Finish ()
410 def config_header (target, source, env):
411 config = open (str (target[0]), 'w')
412 for i in list_sort (env['DEFINES'].keys ()):
413 config.write ('#define %s %s\n' % (i, env['DEFINES'][i]))
415 env.Command (config_hh, config_cache, config_header)
431 if not d.has_key (lst[i]):
439 def uniquify_config_vars (env):
440 for i in config_vars:
441 if env.has_key (i) and type (env[i]) == type ([]):
442 env[i] = uniquify (env[i])
444 def save_config_cache (env):
445 ## FIXME: Is this smart, using option cache for saving
446 ## config.cache? I cannot seem to find the official method.
447 uniquify_config_vars (env)
448 opts.Save (config_cache, env)
450 if 'config' in COMMAND_LINE_TARGETS:
451 sys.stdout.write ('\n')
452 sys.stdout.write ('LilyPond configured')
453 sys.stdout.write ('\n')
454 sys.stdout.write ('now run')
455 sys.stdout.write ('\n')
456 sys.stdout.write (' scons [TARGET|DIR]...')
457 sys.stdout.write ('\n')
459 elif not env['checksums']:
460 # When using timestams, config.hh is NEW. The next
461 # build triggers recompilation of everything. Exiting
462 # here makes SCons use the actual timestamp for config.hh
463 # and prevents recompiling everything the next run.
464 command = sys.argv[0] + ' ' + string.join (COMMAND_LINE_TARGETS)
465 sys.stdout.write ('Running %s ... ' % command)
466 sys.stdout.write ('\n')
467 s = os.system (command)
471 if os.path.exists (config_cache) and 'config' in COMMAND_LINE_TARGETS:
472 os.unlink (config_cache)
474 # scons: *** Calling Configure from Builders is not supported.
475 # env.Command (config_cache, None, configure)
476 if not os.path.exists (config_cache) \
477 or (os.stat ('SConstruct')[stat.ST_MTIME]
478 > os.stat (config_cache)[stat.ST_MTIME]):
479 env = configure (None, None, env)
480 save_config_cache (env)
481 elif env['checksums']:
482 # just save everything
483 save_config_cache (env)
485 #urg how does #/ subst work?
487 SConscript ('buildscripts/builder.py')
489 env.PrependENVPath ('PATH',
490 os.path.join (env['absbuild'], env['out'], 'usr/bin'))
492 if os.environ.has_key ('TEXMF'):
493 env.Append (ENV = {'TEXMF' : os.environ['TEXMF']})
495 'TEXMF' : '{$LILYPONDPREFIX,' \
496 + os.popen ('kpsexpand \$TEXMF').read ()[:-1] + '}',
497 'LILYPONDPREFIX' : os.path.join (run_prefix, 'share/lilypond'),
500 BUILD_ABC2LY = '${set__x}$PYTHON $srcdir/scripts/abc2ly.py'
501 BUILD_LILYPOND = '${set__x}$PYTHON $srcdir/scripts/lilypond.py${__verbose}'
502 BUILD_LILYPOND_BIN = '$absbuild/$out/lilypond-bin ${__verbose}'
503 BUILD_LILYPOND_BOOK = '$PYTHON $srcdir/scripts/lilypond-book.py --verbose'
506 # post-option environment-update
510 lilypond_datadir = sharedir_package,
511 localedir = localedir,
512 local_lilypond_datadir = sharedir_package_version,
513 lilypondprefix = lilypondprefix,
514 sharedir_package = sharedir_package,
515 sharedir_doc_package = sharedir_doc_package,
516 sharedir_package_version = sharedir_package_version,
518 LILYPOND = BUILD_LILYPOND,
519 ABC2LY = BUILD_ABC2LY,
520 LILYPOND_BOOK = BUILD_LILYPOND_BOOK,
521 LILYPOND_BOOK_FORMAT = 'texi-html',
522 MAKEINFO_FLAGS = '--css-include=$srcdir/Documentation/texinfo.css',
524 TEXI2DVI_PAPERSIZE = '@afourpaper',
525 TEXI2DVI_FLAGS = [ '-t $TEXI2DVI_PAPERSIZE'],
526 DVIPS_PAPERSIZE = 'a4',
527 DVIPS_FLAGS = ['-t $DVIPS_PAPERSIZE',
529 '-u+ec-mftrace.map'],
530 PSPDF_FLAGS = ['-sPAPERSIZE=$DVIPS_PAPERSIZE'],
534 env.Append (CCFLAGS = ['-g', '-pipe'])
535 if env['optimising']:
536 env.Append (CCFLAGS = '-O2')
537 env.Append (CXXFLAGS = ['-DSTRING_UTILS_INLINED'])
539 env.Append (CCFLAGS = ['-W', '-Wall'])
540 env.Append (CXXFLAGS = ['-Wconversion'])
543 env.Append (LINKFLAGS = ['-Wl,--export-dynamic'])
546 env['__verbose'] = ' --verbose'
547 env['set__x'] = 'set -x;'
550 ## Explicit target and dependencies
552 if 'clean' in COMMAND_LINE_TARGETS:
553 # ugh: prevent reconfigure instead of clean
554 os.system ('touch %s' % config_cache)
556 command = sys.argv[0] + ' -c .'
557 sys.stdout.write ('Running %s ... ' % command)
558 sys.stdout.write ('\n')
559 s = os.system (command)
560 if os.path.exists (config_cache):
561 os.unlink (config_cache)
564 if 'sconsclean' in COMMAND_LINE_TARGETS:
565 command = 'rm -rf scons.cache $(find . -name ".scon*")'
566 s = os.system (command)
567 if os.path.exists (config_cache):
568 os.unlink (config_cache)
571 if 'realclean' in COMMAND_LINE_TARGETS:
572 command = 'rm -rf $(find . -name "out-scons" -o -name ".scon*")'
573 sys.stdout.write ('Running %s ... ' % command)
574 sys.stdout.write ('\n')
575 s = os.system (command)
576 if os.path.exists (config_cache):
577 os.unlink (config_cache)
580 # Declare SConscript phonies
581 env.Alias ('minimal', config_cache)
582 env.Alias ('mf-essential', config_cache)
584 env.Alias ('minimal', ['lily', 'mf-essential'])
585 env.Alias ('all', ['minimal', 'mf', '.'])
586 # Do we want the doc/web separation?
589 'Documentation/user',
590 'Documentation/topdocs',
591 'Documentation/bibliography',
594 # Without target arguments, do minimal build
595 if not COMMAND_LINE_TARGETS:
596 env.Default (['minimal'])
598 # GNU Make rerouting compat:
599 env.Alias ('web', 'doc')
602 env.Command (version_hh, '#/VERSION',
603 '$PYTHON ./stepmake/bin/make-version.py VERSION > $TARGET')
605 # post-config environment update
607 run_prefix = run_prefix,
608 LILYPONDPREFIX = os.path.join (run_prefix, 'share/lilypond'),
610 LIBPATH = [os.path.join (absbuild, 'flower', env['out']),],
611 CPPPATH = [outdir, ],
612 LILYPOND_PATH = ['.', '$srcdir/input',
613 '$srcdir/input/regression',
614 '$srcdir/input/test',
615 '$srcdir/input/tutorial',
616 '$srcdir/Documentation/user',
618 # os.path.join (absbuild, 'Documentation',
620 # os.path.join (absbuild, 'Documentation/user',
623 MAKEINFO_PATH = ['.', '$srcdir/Documentation/user',
624 '$absbuild/Documentation/user/$out'],
627 def symlink_tree (target, source, env):
633 if not os.path.isdir (dir):
634 if os.path.exists (dir):
638 map (mkdir, string.split (dir, os.sep))
639 def symlink (src, dst):
641 dir = os.path.dirname (dst)
644 frm = os.path.join (srcdir, src[1:])
646 depth = len (string.split (dir, '/'))
647 if src.find ('@') > -1:
648 frm = os.path.join ('../' * depth,
649 string.replace (src, '@',
652 frm = os.path.join ('../' * depth, src,
655 frm = os.path.join (frm, os.path.basename (dst))
657 print 'ln -s %s -> %s' % (frm, os.path.basename (dst))
658 os.symlink (frm, os.path.basename (dst))
659 shutil.rmtree (run_prefix)
660 prefix = os.path.join (env['out'], 'usr')
661 map (lambda x: symlink (x[0], os.path.join (prefix, x[1])),
664 # /$ := add dst file_name
665 (('python', 'lib/lilypond/python'),
666 ('lily/', 'bin/lilypond-bin'),
667 ('scripts/', 'bin/lilypond'),
668 ('scripts/', 'bin/lilypond-book'),
669 ('mf', 'share/lilypond/dvips'),
670 ('#ps', 'share/lilypond/tex/music-drawing-routines.ps'),
671 ('mf', 'share/lilypond/afm'),
672 ('mf', 'share/lilypond/tfm'),
673 ('#mf', 'share/lilypond/fonts/mf'),
674 ('mf', 'share/lilypond/fonts/afm'),
675 ('mf', 'share/lilypond/fonts/tfm'),
676 ('mf', 'share/lilypond/fonts/type1'),
677 ('#tex', 'share/lilypond/tex/source'),
678 ('mf', 'share/lilypond/tex/generate'),
679 ('#ly', 'share/lilypond/ly'),
680 ('#scm', 'share/lilypond/scm'),
681 ('#ps', 'share/lilypond/ps'),
682 ('po/@/nl.mo', 'share/locale/nl/LC_MESSAGES/lilypond.mo'),
683 ('elisp', 'share/lilypond/elisp')))
687 stamp = os.path.join (run_prefix, 'stamp')
688 env.Command (stamp, 'SConstruct', [symlink_tree, 'touch $TARGET'])
689 env.Depends ('lily', stamp)
695 def cvs_entry_is_dir (line):
696 return line[0] == 'D' and line[-2] == '/'
698 def cvs_entry_is_file (line):
699 return line[0] == '/' and line[-2] == '/'
702 ENTRIES = os.path.join (dir, 'CVS/Entries')
703 if not os.path.exists (ENTRIES):
705 entries = open (ENTRIES).readlines ()
706 dir_entries = filter (cvs_entry_is_dir, entries)
707 dirs = map (lambda x: os.path.join (dir, x[2:x[2:].index ('/')+3]),
709 return dirs + map (cvs_dirs, dirs)
712 ENTRIES = os.path.join (dir, 'CVS/Entries')
713 entries = open (ENTRIES).readlines ()
714 file_entries = filter (cvs_entry_is_file, entries)
715 files = map (lambda x: x[1:x[1:].index ('/')+1], file_entries)
716 return map (lambda x: os.path.join (dir, x), files)
718 def flatten (tree, lst):
719 if type (tree) == type ([]):
721 if type (i) == type ([]):
728 and 'all' not in COMMAND_LINE_TARGETS\
729 and 'doc' not in COMMAND_LINE_TARGETS\
730 and 'web' not in COMMAND_LINE_TARGETS\
731 and 'install' not in COMMAND_LINE_TARGETS\
732 and 'clean' not in COMMAND_LINE_TARGETS:
733 subdirs = ['lily','flower', 'mf']
735 subdirs = flatten (cvs_dirs ('.'), [])
736 readme_files = ['AUTHORS', 'README', 'INSTALL', 'NEWS']
737 foo = map (lambda x: env.TXT (x + '.txt',
738 os.path.join ('Documentation/topdocs', x)),
740 txt_files = map (lambda x: x + '.txt', readme_files)
741 src_files = reduce (lambda x, y: x + y, map (cvs_files, subdirs))
742 tar_base = package.name + '-' + version
743 tar_name = tar_base + '.tar.gz'
744 ball_prefix = os.path.join (outdir, tar_base)
745 tar_ball = os.path.join (outdir, tar_name)
747 dist_files = src_files + txt_files
748 ball_files = map (lambda x: os.path.join (ball_prefix, x), dist_files)
749 map (lambda x: env.Depends (tar_ball, x), ball_files)
750 map (lambda x: env.Command (os.path.join (ball_prefix, x), x,
751 'ln $SOURCE $TARGET'), dist_files)
752 tar = env.Command (tar_ball, src_files,
753 ['rm -f $$(find $TARGET.dir -name .sconsign)',
754 'tar czf $TARGET -C $TARGET.dir %s' % tar_base,])
755 env.Alias ('tar', tar)
757 dist_ball = os.path.join (package.release_dir, tar_name)
758 env.Command (dist_ball, tar_ball,
759 'if [ -e $SOURCE -a -e $TARGET ]; then rm $TARGET; fi;' \
760 + 'ln $SOURCE $TARGET')
761 env.Depends ('dist', dist_ball)
762 patch_name = os.path.join (outdir, tar_base + '.diff.gz')
763 patch = env.PATCH (patch_name, tar_ball)
764 env.Depends (patch_name, dist_ball)
765 env.Alias ('release', patch)
768 web_base = os.path.join (outdir, 'web')
769 web_ball = web_base + '.tar.gz'
770 env['footify'] = 'MAILADDRESS=bug-lilypond@gnu.org $PYTHON stepmake/bin/add-html-footer.py --name=lilypond --version=$TOPLEVEL_VERSION'
771 web_ext = ['.html', '.ly', '.midi', '.pdf', '.png', '.ps.gz', '.txt',]
772 web_path = '-path "*/$out/*"' + string.join (web_ext, ' -or -path "*/$out/*"')
773 env['web_path'] = web_path
774 web_list = os.path.join (outdir, 'weblist')
775 # compatible make heritits
776 # fixme: generate in $outdir is cwd/builddir
777 env.Command (web_list,
778 ## this is correct, but takes > 5min if you have a peder :-)
781 ['$PYTHON buildscripts/mutopia-index.py -o examples.html ./',
782 'cd $absbuild && $footify $$(find . -name "*.html" -print)',
783 'cd $absbuild && rm -f $$(find . -name "*.html~" -print)',
784 'cd $absbuild && find Documentation input $web_path \
786 '''echo '<META HTTP-EQUIV="refresh" content="0;URL=Documentation/out-www/index.html">' > $absbuild/index.html''',
787 '''echo '<html><body>Redirecting to the documentation index...</body></html>' >> $absbuild/index.html''',
788 'cd $absbuild && ls *.html >> $TARGET',])
789 env.Command (web_ball, web_list,
790 ['cat $SOURCE | tar -C $absbuild -czf $TARGET -T -',])
791 #env.Alias ('web', web_ball)
792 www_base = os.path.join (outdir, 'www')
793 www_ball = www_base + '.tar.gz'
794 env.Command (www_ball, web_ball,
796 'mkdir -p $absbuild/$out/tmp',
797 'tar -C $absbuild/$out/tmp -xzf $SOURCE',
798 'cd $absbuild/$out/tmp && for i in $$(find . -name "$out"); do mv $$i $$(dirname $$i)/out-www; done',
799 'tar -C $absbuild/$out/tmp -czf $TARGET .'])
800 env.Alias ('web', www_ball)
804 ETAGSFLAGS = ["""--regex='{c++}/^LY_DEFINE *(\([^,]+\)/\1/'""",
805 """--regex='{c++}/^LY_DEFINE *([^"]*"\([^"]+\)"/\1/'"""])
806 # filter-out some files?
807 env.Command ('TAGS', src_files, 'etags $ETAGSFLAGS $SOURCES')
810 # Note: SConscripts are only needed in directories where something needs
811 # to be done, building or installing
813 if os.path.exists (os.path.join (d, 'SConscript')):
814 b = os.path.join (env['build'], d, env['out'])
815 # Support clean sourcetree build (--srcdir build)
817 if os.path.abspath (b) != os.path.abspath (d):
818 env.BuildDir (b, d, duplicate = 0)
819 SConscript (os.path.join (b, 'SConscript'))