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',
133 BoolOption ('fast', 'use timestamps, implicit cache, prune CPPPATH',
137 srcdir = Dir ('.').srcnode ().abspath
139 sys.path.append (os.path.join (srcdir, 'stepmake', 'bin'))
141 package = packagepython.Package (srcdir)
142 version = packagepython.version_tuple_to_str (package.version)
144 ENV = { 'PATH' : os.environ['PATH'] }
145 for key in ['LD_LIBRARY_PATH', 'GUILE_LOAD_PATH', 'PKG_CONFIG_PATH']:
146 if os.environ.has_key (key):
147 ENV[key] = os.environ[key]
153 PERL = '/usr/bin/perl',
154 PYTHON = '/usr/bin/python',
157 MAKEINFO = 'LANG= makeinfo',
158 MF_TO_TABLE_PY = srcdir + '/buildscripts/mf-to-table.py',
160 PKG_CONFIG_PATH = [os.path.join (os.environ['HOME'],
161 'usr/pkg/gnome/lib'),
162 os.path.join (os.environ['HOME'],
163 'usr/pkg/pango/lib')],
166 TOPLEVEL_VERSION = version,
169 # Add all config_vars to opts, so that they will be read and saved
170 # together with the other configure options.
171 map (lambda x: opts.AddOptions ((x,)), config_vars)
173 Help (usage + opts.GenerateHelpText (env))
178 # Usability switch (Anthony Roach).
179 # See http://www.scons.org/cgi-bin/wiki/GoFastButton
180 # First do: scons realclean .
182 SetOption ('max_drift', 1)
183 SetOption ('implicit_cache', 1)
184 elif env['checksums']:
185 # Always use checksums (makes more sense than timestamps).
186 SetOption ('max_drift', 0)
187 # Using *content* checksums prevents rebuilds after
188 # [re]configure if config.hh has not changed. Too bad that it
190 TargetSignatures ('content')
192 absbuild = Dir (env['build']).abspath
193 outdir = os.path.join (Dir (env['build']).abspath, env['out'])
194 run_prefix = os.path.join (absbuild, os.path.join (env['out'], 'usr'))
197 config_hh = os.path.join (outdir, 'config.hh')
198 version_hh = os.path.join (outdir, 'version.hh')
200 env.Alias ('config', config_cache)
202 cachedir = os.path.join (outdir, 'build-cache')
204 if not os.path.exists(cachedir):
205 os.makedirs(cachedir)
207 CacheDir (os.path.join (outdir, 'build-cache'))
209 # No need to set $LILYPONDPREFIX to run lily, but cannot install...
210 if env['debugging'] and not 'install' in COMMAND_LINE_TARGETS:
211 env['prefix'] = run_prefix
213 prefix = env['prefix']
214 bindir = os.path.join (prefix, 'bin')
215 sharedir = os.path.join (prefix, 'share')
216 libdir = os.path.join (prefix, 'lib')
217 localedir = os.path.join (sharedir, 'locale')
218 sharedir_doc_package = os.path.join (sharedir, 'doc', package.name)
219 sharedir_package = os.path.join (sharedir, package.name)
220 sharedir_package_version = os.path.join (sharedir_package, version)
221 lilypondprefix = sharedir_package_version
236 def configure (target, source, env):
237 vre = re.compile ('^.*[^-.0-9]([0-9][0-9]*\.[0-9][.0-9]*).*$', re.DOTALL)
238 def get_version (program):
239 command = '(%(program)s --version || %(program)s -V) 2>&1' % vars ()
240 pipe = os.popen (command)
241 output = pipe.read ()
244 v = re.sub (vre, '\\1', output)
245 return string.split (v, '.')
247 def test_program (lst, program, minimal, description, package):
248 sys.stdout.write ('Checking %s version... ' % program)
249 actual = get_version (program)
252 lst.append ((description, package, minimal, program,
255 sys.stdout.write (string.join (actual, '.'))
256 sys.stdout.write ('\n')
257 if actual < string.split (minimal, '.'):
258 lst.append ((description, package, minimal, program,
259 string.join (actual, '.')))
261 for i in ['bash', 'perl', 'python', 'sh']:
262 sys.stdout.write ('Checking for %s... ' % i)
264 key = string.upper (i)
269 sys.stdout.write ('not found: %s (using: %s)' \
272 sys.stdout.write ('\n')
275 test_program (required, 'gcc', '2.8', 'GNU C compiler', 'gcc')
276 test_program (required, 'g++', '3.0.5', 'GNU C++ compiler', 'g++')
277 test_program (required, 'python', '2.1', 'Python (www.python.org)', 'python')
278 test_program (required, 'guile-config', '1.6', 'GUILE development',
279 'libguile-dev or guile-devel')
280 # Do not use bison 1.50 and 1.75.
281 test_program (required, 'bison', '1.25', 'Bison -- parser generator',
283 test_program (required, 'flex', '0.0', 'Flex -- lexer generator', 'flex')
287 test_program (optional, 'makeinfo', '4.7', 'Makeinfo tool', 'texinfo')
288 test_program (optional, 'guile', '1.6', 'GUILE scheme',
289 'libguile-dev or guile-devel')
290 test_program (optional, 'mftrace', '1.0.27', 'Metafont tracing Type1',
292 test_program (optional, 'perl', '4.0',
293 'Perl practical efficient readonly language', 'perl')
294 #test_program (optional, 'foo', '2.0', 'Foomatic tester', 'bar')
296 def CheckYYCurrentBuffer (context):
297 context.Message ('Checking for yy_current_buffer... ')
298 ret = conf.TryCompile ("""using namespace std;
299 #include <FlexLexer.h>
300 class yy_flex_lexer: public yyFlexLexer
305 yy_current_buffer = 0;
311 conf = Configure (env, custom_tests = { 'CheckYYCurrentBuffer'
312 : CheckYYCurrentBuffer })
315 'DIRSEP' : "'%s'" % os.sep,
316 'PATHSEP' : "'%s'" % os.pathsep,
317 'TOPLEVEL_VERSION' : '"' + version + '"',
318 'PACKAGE': '"' + package.name + '"',
319 'DATADIR' : '"' + sharedir + '"',
320 'LILYPOND_DATADIR' : '"' + sharedir_package + '"',
321 'LOCAL_LILYPOND_DATADIR' : '"' + sharedir_package_version + '"',
322 'LOCALEDIR' : '"' + localedir + '"',
324 conf.env.Append (DEFINES = defines)
326 command = r"""python -c 'import sys; sys.stdout.write ("%s/include/python%s" % (sys.prefix, sys.version[:3]))'""" #"
327 PYTHON_INCLUDE = os.popen (command).read ()
329 env.Append (CCFLAGS = ['-I%s ' % PYTHON_INCLUDE])
331 env.Append (CPPPATH = PYTHON_INCLUDE)
333 headers = ('sys/stat.h', 'assert.h', 'kpathsea/kpathsea.h', 'Python.h')
335 if conf.CheckCHeader (i):
336 key = re.sub ('[./]', '_', 'HAVE_' + string.upper (i))
337 conf.env['DEFINES'][key] = 1
339 ccheaders = ('sstream',)
341 if conf.CheckCXXHeader (i):
342 key = re.sub ('[./]', '_', 'HAVE_' + string.upper (i))
343 conf.env['DEFINES'][key] = 1
345 functions = ('gettext', 'isinf', 'memmem', 'snprintf', 'vsnprintf')
347 if 0 or conf.CheckFunc (i):
348 key = re.sub ('[./]', '_', 'HAVE_' + string.upper (i))
349 conf.env['DEFINES'][key] = 1
351 if conf.CheckYYCurrentBuffer ():
352 conf.env['DEFINES']['HAVE_FLEXLEXER_YY_CURRENT_BUFFER'] = 1
354 if conf.CheckLib ('dl'):
357 if conf.CheckLib ('kpathsea'):
358 conf.env['DEFINES']['KPATHSEA'] = 1
361 if conf.CheckLib ('kpathsea', 'kpse_find_file'):
362 conf.env['DEFINES']['HAVE_KPSE_FIND_FILE'] = '1'
363 if conf.CheckLib ('kpathsea', 'kpse_find_tfm'):
364 conf.env['DEFINES']['HAVE_KPSE_FIND_TFM'] = '1'
368 if env.has_key ('CPPPATH'):
369 cpppath = env['CPPPATH']
371 ## FIXME: linkage, check for libguile.h and scm_boot_guile
372 #this could happen after flower...
373 env.ParseConfig ('guile-config compile')
375 #this could happen only for compiling pango-*
377 env.ParseConfig ('pkg-config --cflags --libs gtk+-2.0')
378 env.ParseConfig ('pkg-config --cflags --libs pango')
379 if conf.CheckCHeader ('pango/pangofc-fontmap.h'):
380 conf.env['DEFINES']['HAVE_PANGO_PANGOFC_FONTMAP_H'] = '1'
382 if conf.CheckLib ('pango-1.0',
383 'pango_fc_font_map_add_decoder_find_func'):
384 conf.env['DEFINES']['HAVE_PANGO_CVS'] = '1'
385 conf.env['DEFINES']['HAVE_PANGO_FC_FONT_MAP_ADD_DECODER_FIND_FUNC'] = '1'
388 # Using CCFLAGS = -I<system-dir> rather than CPPPATH = [
389 # <system-dir>] speeds up SCons
390 env['CCFLAGS'] += map (lambda x: '-I' + x,
391 env['CPPPATH'][len (cpppath):])
392 env['CPPPATH'] = cpppath
396 print '********************************'
397 print 'Please install required packages'
399 print '%s: %s-%s or newer (found: %s %s)' % i
404 print '*************************************'
405 print 'Consider installing optional packages'
407 print '%s: %s-%s or newer (found: %s %s)' % i
409 return conf.Finish ()
411 def config_header (target, source, env):
412 config = open (str (target[0]), 'w')
413 for i in list_sort (env['DEFINES'].keys ()):
414 config.write ('#define %s %s\n' % (i, env['DEFINES'][i]))
416 env.Command (config_hh, config_cache, config_header)
432 if not d.has_key (lst[i]):
440 def uniquify_config_vars (env):
441 for i in config_vars:
442 if env.has_key (i) and type (env[i]) == type ([]):
443 env[i] = uniquify (env[i])
445 def save_config_cache (env):
446 ## FIXME: Is this smart, using option cache for saving
447 ## config.cache? I cannot seem to find the official method.
448 uniquify_config_vars (env)
449 opts.Save (config_cache, env)
451 if 'config' in COMMAND_LINE_TARGETS:
452 sys.stdout.write ('\n')
453 sys.stdout.write ('LilyPond configured')
454 sys.stdout.write ('\n')
455 sys.stdout.write ('now run')
456 sys.stdout.write ('\n')
457 sys.stdout.write (' scons [TARGET|DIR]...')
458 sys.stdout.write ('\n')
460 elif not env['checksums']:
461 # When using timestams, config.hh is NEW. The next
462 # build triggers recompilation of everything. Exiting
463 # here makes SCons use the actual timestamp for config.hh
464 # and prevents recompiling everything the next run.
465 command = sys.argv[0] + ' ' + string.join (COMMAND_LINE_TARGETS)
466 sys.stdout.write ('Running %s ... ' % command)
467 sys.stdout.write ('\n')
468 s = os.system (command)
472 if os.path.exists (config_cache) and 'config' in COMMAND_LINE_TARGETS:
473 os.unlink (config_cache)
475 # scons: *** Calling Configure from Builders is not supported.
476 # env.Command (config_cache, None, configure)
477 if not os.path.exists (config_cache) \
478 or (os.stat ('SConstruct')[stat.ST_MTIME]
479 > os.stat (config_cache)[stat.ST_MTIME]):
480 env = configure (None, None, env)
481 save_config_cache (env)
482 elif env['checksums']:
483 # just save everything
484 save_config_cache (env)
486 #urg how does #/ subst work?
488 SConscript ('buildscripts/builder.py')
490 env.PrependENVPath ('PATH',
491 os.path.join (env['absbuild'], env['out'], 'usr/bin'))
493 if os.environ.has_key ('TEXMF'):
494 env.Append (ENV = {'TEXMF' : os.environ['TEXMF']})
496 'TEXMF' : '{$LILYPONDPREFIX,' \
497 + os.popen ('kpsexpand \$TEXMF').read ()[:-1] + '}',
498 'LILYPONDPREFIX' : os.path.join (run_prefix, 'share/lilypond'),
501 BUILD_ABC2LY = '${set__x}$PYTHON $srcdir/scripts/abc2ly.py'
502 BUILD_LILYPOND = '${set__x}$PYTHON $srcdir/scripts/lilypond.py${__verbose}'
503 BUILD_LILYPOND_BIN = '$absbuild/$out/lilypond-bin ${__verbose}'
504 BUILD_LILYPOND_BOOK = '$PYTHON $srcdir/scripts/lilypond-book.py --verbose'
507 # post-option environment-update
511 lilypond_datadir = sharedir_package,
512 localedir = localedir,
513 local_lilypond_datadir = sharedir_package_version,
514 lilypondprefix = lilypondprefix,
515 sharedir_package = sharedir_package,
516 sharedir_doc_package = sharedir_doc_package,
517 sharedir_package_version = sharedir_package_version,
519 LILYPOND = BUILD_LILYPOND,
520 ABC2LY = BUILD_ABC2LY,
521 LILYPOND_BOOK = BUILD_LILYPOND_BOOK,
522 LILYPOND_BOOK_FORMAT = 'texi-html',
523 MAKEINFO_FLAGS = '--css-include=$srcdir/Documentation/texinfo.css',
525 TEXI2DVI_PAPERSIZE = '@afourpaper',
526 TEXI2DVI_FLAGS = [ '-t $TEXI2DVI_PAPERSIZE'],
527 DVIPS_PAPERSIZE = 'a4',
528 DVIPS_FLAGS = ['-t $DVIPS_PAPERSIZE',
530 '-u+ec-mftrace.map'],
531 PSPDF_FLAGS = ['-sPAPERSIZE=$DVIPS_PAPERSIZE'],
535 env.Append (CCFLAGS = ['-g', '-pipe'])
536 if env['optimising']:
537 env.Append (CCFLAGS = '-O2')
538 env.Append (CXXFLAGS = ['-DSTRING_UTILS_INLINED'])
540 env.Append (CCFLAGS = ['-W', '-Wall'])
541 env.Append (CXXFLAGS = ['-Wconversion'])
544 env.Append (LINKFLAGS = ['-Wl,--export-dynamic'])
547 env['__verbose'] = ' --verbose'
548 env['set__x'] = 'set -x;'
551 ## Explicit target and dependencies
553 if 'clean' in COMMAND_LINE_TARGETS:
554 # ugh: prevent reconfigure instead of clean
555 os.system ('touch %s' % config_cache)
557 command = sys.argv[0] + ' -c .'
558 sys.stdout.write ('Running %s ... ' % command)
559 sys.stdout.write ('\n')
560 s = os.system (command)
561 if os.path.exists (config_cache):
562 os.unlink (config_cache)
565 if 'sconsclean' in COMMAND_LINE_TARGETS:
566 command = 'rm -rf scons.cache $(find . -name ".scon*")'
567 s = os.system (command)
568 if os.path.exists (config_cache):
569 os.unlink (config_cache)
572 if 'realclean' in COMMAND_LINE_TARGETS:
573 command = 'rm -rf $(find . -name "out-scons" -o -name ".scon*")'
574 sys.stdout.write ('Running %s ... ' % command)
575 sys.stdout.write ('\n')
576 s = os.system (command)
577 if os.path.exists (config_cache):
578 os.unlink (config_cache)
581 # Declare SConscript phonies
582 env.Alias ('minimal', config_cache)
583 env.Alias ('mf-essential', config_cache)
585 env.Alias ('minimal', ['lily', 'mf-essential'])
586 env.Alias ('all', ['minimal', 'mf', '.'])
587 # Do we want the doc/web separation?
590 'Documentation/user',
591 'Documentation/topdocs',
592 'Documentation/bibliography',
595 # Without target arguments, do minimal build
596 if not COMMAND_LINE_TARGETS:
597 env.Default (['minimal'])
599 # GNU Make rerouting compat:
600 env.Alias ('web', 'doc')
603 env.Command (version_hh, '#/VERSION',
604 '$PYTHON ./stepmake/bin/make-version.py VERSION > $TARGET')
606 # post-config environment update
608 run_prefix = run_prefix,
609 LILYPONDPREFIX = os.path.join (run_prefix, 'share/lilypond'),
611 LIBPATH = [os.path.join (absbuild, 'flower', env['out']),],
612 CPPPATH = [outdir, ],
613 LILYPOND_PATH = ['.', '$srcdir/input',
614 '$srcdir/input/regression',
615 '$srcdir/input/test',
616 '$srcdir/input/tutorial',
617 '$srcdir/Documentation/user',
619 # os.path.join (absbuild, 'Documentation',
621 # os.path.join (absbuild, 'Documentation/user',
624 MAKEINFO_PATH = ['.', '$srcdir/Documentation/user',
625 '$absbuild/Documentation/user/$out'],
628 def symlink_tree (target, source, env):
634 if not os.path.isdir (dir):
635 if os.path.exists (dir):
639 map (mkdir, string.split (dir, os.sep))
640 def symlink (src, dst):
642 dir = os.path.dirname (dst)
645 frm = os.path.join (srcdir, src[1:])
647 depth = len (string.split (dir, '/'))
648 if src.find ('@') > -1:
649 frm = os.path.join ('../' * depth,
650 string.replace (src, '@',
653 frm = os.path.join ('../' * depth, src,
656 frm = os.path.join (frm, os.path.basename (dst))
658 print 'ln -s %s -> %s' % (frm, os.path.basename (dst))
659 os.symlink (frm, os.path.basename (dst))
660 shutil.rmtree (run_prefix)
661 prefix = os.path.join (env['out'], 'usr')
662 map (lambda x: symlink (x[0], os.path.join (prefix, x[1])),
665 # /$ := add dst file_name
666 (('python', 'lib/lilypond/python'),
667 ('lily/', 'bin/lilypond-bin'),
668 ('scripts/', 'bin/lilypond'),
669 ('scripts/', 'bin/lilypond-book'),
670 ('mf', 'share/lilypond/dvips/mf-out'),
671 ('#ps', 'share/lilypond/dvips/ps'),
672 ('#ps', 'share/lilypond/tex/music-drawing-routines.ps'),
673 ('mf', 'share/lilypond/otf'),
674 ('mf', 'share/lilypond/tfm'),
675 ('tex', 'share/lilypond/tex/enc'),
676 ('#mf', 'share/lilypond/fonts/mf'),
677 ('mf', 'share/lilypond/fonts/map'),
678 ('mf', 'share/lilypond/fonts/otf'),
679 ('mf', 'share/lilypond/fonts/tfm'),
680 ('mf', 'share/lilypond/fonts/type1'),
681 ('#tex', 'share/lilypond/tex/source'),
682 ('tex', 'share/lilypond/tex/tex-out'),
683 ('mf', 'share/lilypond/tex/mf-out'),
684 ('#ly', 'share/lilypond/ly'),
685 ('#scm', 'share/lilypond/scm'),
686 ('#ps', 'share/lilypond/ps'),
687 ('po/@/nl.mo', 'share/locale/nl/LC_MESSAGES/lilypond.mo'),
688 ('elisp', 'share/lilypond/elisp')))
692 stamp = os.path.join (run_prefix, 'stamp')
693 env.Command (stamp, 'SConstruct', [symlink_tree, 'touch $TARGET'])
694 env.Depends ('lily', stamp)
700 def cvs_entry_is_dir (line):
701 return line[0] == 'D' and line[-2] == '/'
703 def cvs_entry_is_file (line):
704 return line[0] == '/' and line[-2] == '/'
707 ENTRIES = os.path.join (dir, 'CVS/Entries')
708 if not os.path.exists (ENTRIES):
710 entries = open (ENTRIES).readlines ()
711 dir_entries = filter (cvs_entry_is_dir, entries)
712 dirs = map (lambda x: os.path.join (dir, x[2:x[2:].index ('/')+3]),
714 return dirs + map (cvs_dirs, dirs)
717 ENTRIES = os.path.join (dir, 'CVS/Entries')
718 entries = open (ENTRIES).readlines ()
719 file_entries = filter (cvs_entry_is_file, entries)
720 files = map (lambda x: x[1:x[1:].index ('/')+1], file_entries)
721 return map (lambda x: os.path.join (dir, x), files)
723 def flatten (tree, lst):
724 if type (tree) == type ([]):
726 if type (i) == type ([]):
733 and 'all' not in COMMAND_LINE_TARGETS\
734 and 'doc' not in COMMAND_LINE_TARGETS\
735 and 'web' not in COMMAND_LINE_TARGETS\
736 and 'install' not in COMMAND_LINE_TARGETS\
737 and 'clean' not in COMMAND_LINE_TARGETS:
738 subdirs = ['lily', 'lily/include', 'flower', 'flower/include', 'mf']
740 subdirs = flatten (cvs_dirs ('.'), [])
742 src_files = reduce (lambda x, y: x + y, map (cvs_files, subdirs))
743 readme_files = ['AUTHORS', 'README', 'INSTALL', 'NEWS']
744 txt_files = map (lambda x: x + '.txt', readme_files)
748 # speeds up build by +- 5%
751 foo = map (lambda x: env.TXT (x + '.txt',
752 os.path.join ('Documentation/topdocs', x)),
754 tar_base = package.name + '-' + version
755 tar_name = tar_base + '.tar.gz'
756 ball_prefix = os.path.join (outdir, tar_base)
757 tar_ball = os.path.join (outdir, tar_name)
759 dist_files = src_files + txt_files
760 ball_files = map (lambda x: os.path.join (ball_prefix, x), dist_files)
761 map (lambda x: env.Depends (tar_ball, x), ball_files)
762 map (lambda x: env.Command (os.path.join (ball_prefix, x), x,
763 'ln $SOURCE $TARGET'), dist_files)
764 tar = env.Command (tar_ball, src_files,
765 ['rm -f $$(find $TARGET.dir -name .sconsign)',
766 'tar czf $TARGET -C $TARGET.dir %s' % tar_base,])
767 env.Alias ('tar', tar)
769 dist_ball = os.path.join (package.release_dir, tar_name)
770 env.Command (dist_ball, tar_ball,
771 'if [ -e $SOURCE -a -e $TARGET ]; then rm $TARGET; fi;' \
772 + 'ln $SOURCE $TARGET')
773 env.Depends ('dist', dist_ball)
774 patch_name = os.path.join (outdir, tar_base + '.diff.gz')
775 patch = env.PATCH (patch_name, tar_ball)
776 env.Depends (patch_name, dist_ball)
777 env.Alias ('release', patch)
781 web_base = os.path.join (outdir, 'web')
782 web_ball = web_base + '.tar.gz'
783 env['footify'] = 'MAILADDRESS=bug-lilypond@gnu.org $PYTHON stepmake/bin/add-html-footer.py --name=lilypond --version=$TOPLEVEL_VERSION'
784 web_ext = ['.html', '.ly', '.midi', '.pdf', '.png', '.ps.gz', '.txt',]
785 web_path = '-path "*/$out/*"' + string.join (web_ext, ' -or -path "*/$out/*"')
786 env['web_path'] = web_path
787 web_list = os.path.join (outdir, 'weblist')
788 # compatible make heritits
789 # fixme: generate in $outdir is cwd/builddir
790 env.Command (web_list,
791 ## this is correct, but takes > 5min if you have a peder :-)
794 ['$PYTHON buildscripts/mutopia-index.py -o examples.html ./',
795 'cd $absbuild && $footify $$(find . -name "*.html" -print)',
796 'cd $absbuild && rm -f $$(find . -name "*.html~" -print)',
797 'cd $absbuild && find Documentation input $web_path \
799 '''echo '<META HTTP-EQUIV="refresh" content="0;URL=Documentation/out-www/index.html">' > $absbuild/index.html''',
800 '''echo '<html><body>Redirecting to the documentation index...</body></html>' >> $absbuild/index.html''',
801 'cd $absbuild && ls *.html >> $TARGET',])
802 env.Command (web_ball, web_list,
803 ['cat $SOURCE | tar -C $absbuild -czf $TARGET -T -',])
804 #env.Alias ('web', web_ball)
805 www_base = os.path.join (outdir, 'www')
806 www_ball = www_base + '.tar.gz'
807 env.Command (www_ball, web_ball,
809 'mkdir -p $absbuild/$out/tmp',
810 'tar -C $absbuild/$out/tmp -xzf $SOURCE',
811 'cd $absbuild/$out/tmp && for i in $$(find . -name "$out"); '
812 + ' do mv $$i $$(dirname $$i)/out-www; done',
813 'tar -C $absbuild/$out/tmp -czf $TARGET .'])
814 env.Alias ('web', www_ball)
818 ETAGSFLAGS = """--regex='{c++}/^LY_DEFINE *(\([^,]+\)/\\1/' \
819 --regex='{c++}/^LY_DEFINE *([^"]*"\([^"]+\)"/\\1/'""")
820 code_ext = ['.cc', '.hh', '.scm', '.tcc',]
821 env.Command ('TAGS', filter (lambda x: os.path.splitext (x)[1] in code_ext,
823 'etags $ETAGSFLAGS $SOURCES')
825 # Note: SConscripts are only needed in directories where something needs
826 # to be done, building or installing
828 if os.path.exists (os.path.join (d, 'SConscript')):
829 b = os.path.join (env['build'], d, env['out'])
830 # Support clean sourcetree build (--srcdir build)
832 if os.path.abspath (b) != os.path.abspath (d):
833 env.BuildDir (b, d, duplicate = 0)
834 SConscript (os.path.join (b, 'SConscript'))