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'),
671 ('#ps', 'share/lilypond/tex/music-drawing-routines.ps'),
672 ('mf', 'share/lilypond/afm'),
673 ('mf', 'share/lilypond/tfm'),
674 ('#mf', 'share/lilypond/fonts/mf'),
675 ('mf', 'share/lilypond/fonts/afm'),
676 ('mf', 'share/lilypond/fonts/tfm'),
677 ('mf', 'share/lilypond/fonts/type1'),
678 ('#tex', 'share/lilypond/tex/source'),
679 ('tex', 'share/lilypond/tex/tex-out'),
680 ('mf', 'share/lilypond/tex/mf-out'),
681 ('#ly', 'share/lilypond/ly'),
682 ('#scm', 'share/lilypond/scm'),
683 ('#ps', 'share/lilypond/ps'),
684 ('po/@/nl.mo', 'share/locale/nl/LC_MESSAGES/lilypond.mo'),
685 ('elisp', 'share/lilypond/elisp')))
689 stamp = os.path.join (run_prefix, 'stamp')
690 env.Command (stamp, 'SConstruct', [symlink_tree, 'touch $TARGET'])
691 env.Depends ('lily', stamp)
697 def cvs_entry_is_dir (line):
698 return line[0] == 'D' and line[-2] == '/'
700 def cvs_entry_is_file (line):
701 return line[0] == '/' and line[-2] == '/'
704 ENTRIES = os.path.join (dir, 'CVS/Entries')
705 if not os.path.exists (ENTRIES):
707 entries = open (ENTRIES).readlines ()
708 dir_entries = filter (cvs_entry_is_dir, entries)
709 dirs = map (lambda x: os.path.join (dir, x[2:x[2:].index ('/')+3]),
711 return dirs + map (cvs_dirs, dirs)
714 ENTRIES = os.path.join (dir, 'CVS/Entries')
715 entries = open (ENTRIES).readlines ()
716 file_entries = filter (cvs_entry_is_file, entries)
717 files = map (lambda x: x[1:x[1:].index ('/')+1], file_entries)
718 return map (lambda x: os.path.join (dir, x), files)
720 def flatten (tree, lst):
721 if type (tree) == type ([]):
723 if type (i) == type ([]):
730 and 'all' not in COMMAND_LINE_TARGETS\
731 and 'doc' not in COMMAND_LINE_TARGETS\
732 and 'web' not in COMMAND_LINE_TARGETS\
733 and 'install' not in COMMAND_LINE_TARGETS\
734 and 'clean' not in COMMAND_LINE_TARGETS:
735 subdirs = ['lily', 'lily/include', 'flower', 'flower/include', 'mf']
737 subdirs = flatten (cvs_dirs ('.'), [])
739 src_files = reduce (lambda x, y: x + y, map (cvs_files, subdirs))
740 readme_files = ['AUTHORS', 'README', 'INSTALL', 'NEWS']
741 txt_files = map (lambda x: x + '.txt', readme_files)
745 # speeds up build by +- 5%
748 foo = map (lambda x: env.TXT (x + '.txt',
749 os.path.join ('Documentation/topdocs', x)),
751 tar_base = package.name + '-' + version
752 tar_name = tar_base + '.tar.gz'
753 ball_prefix = os.path.join (outdir, tar_base)
754 tar_ball = os.path.join (outdir, tar_name)
756 dist_files = src_files + txt_files
757 ball_files = map (lambda x: os.path.join (ball_prefix, x), dist_files)
758 map (lambda x: env.Depends (tar_ball, x), ball_files)
759 map (lambda x: env.Command (os.path.join (ball_prefix, x), x,
760 'ln $SOURCE $TARGET'), dist_files)
761 tar = env.Command (tar_ball, src_files,
762 ['rm -f $$(find $TARGET.dir -name .sconsign)',
763 'tar czf $TARGET -C $TARGET.dir %s' % tar_base,])
764 env.Alias ('tar', tar)
766 dist_ball = os.path.join (package.release_dir, tar_name)
767 env.Command (dist_ball, tar_ball,
768 'if [ -e $SOURCE -a -e $TARGET ]; then rm $TARGET; fi;' \
769 + 'ln $SOURCE $TARGET')
770 env.Depends ('dist', dist_ball)
771 patch_name = os.path.join (outdir, tar_base + '.diff.gz')
772 patch = env.PATCH (patch_name, tar_ball)
773 env.Depends (patch_name, dist_ball)
774 env.Alias ('release', patch)
778 web_base = os.path.join (outdir, 'web')
779 web_ball = web_base + '.tar.gz'
780 env['footify'] = 'MAILADDRESS=bug-lilypond@gnu.org $PYTHON stepmake/bin/add-html-footer.py --name=lilypond --version=$TOPLEVEL_VERSION'
781 web_ext = ['.html', '.ly', '.midi', '.pdf', '.png', '.ps.gz', '.txt',]
782 web_path = '-path "*/$out/*"' + string.join (web_ext, ' -or -path "*/$out/*"')
783 env['web_path'] = web_path
784 web_list = os.path.join (outdir, 'weblist')
785 # compatible make heritits
786 # fixme: generate in $outdir is cwd/builddir
787 env.Command (web_list,
788 ## this is correct, but takes > 5min if you have a peder :-)
791 ['$PYTHON buildscripts/mutopia-index.py -o examples.html ./',
792 'cd $absbuild && $footify $$(find . -name "*.html" -print)',
793 'cd $absbuild && rm -f $$(find . -name "*.html~" -print)',
794 'cd $absbuild && find Documentation input $web_path \
796 '''echo '<META HTTP-EQUIV="refresh" content="0;URL=Documentation/out-www/index.html">' > $absbuild/index.html''',
797 '''echo '<html><body>Redirecting to the documentation index...</body></html>' >> $absbuild/index.html''',
798 'cd $absbuild && ls *.html >> $TARGET',])
799 env.Command (web_ball, web_list,
800 ['cat $SOURCE | tar -C $absbuild -czf $TARGET -T -',])
801 #env.Alias ('web', web_ball)
802 www_base = os.path.join (outdir, 'www')
803 www_ball = www_base + '.tar.gz'
804 env.Command (www_ball, web_ball,
806 'mkdir -p $absbuild/$out/tmp',
807 'tar -C $absbuild/$out/tmp -xzf $SOURCE',
808 'cd $absbuild/$out/tmp && for i in $$(find . -name "$out"); '
809 + ' do mv $$i $$(dirname $$i)/out-www; done',
810 'tar -C $absbuild/$out/tmp -czf $TARGET .'])
811 env.Alias ('web', www_ball)
815 ETAGSFLAGS = """--regex='{c++}/^LY_DEFINE *(\([^,]+\)/\\1/' \
816 --regex='{c++}/^LY_DEFINE *([^"]*"\([^"]+\)"/\\1/'""")
817 code_ext = ['.cc', '.hh', '.scm', '.tcc',]
818 env.Command ('TAGS', filter (lambda x: os.path.splitext (x)[1] in code_ext,
820 'etags $ETAGSFLAGS $SOURCES')
822 # Note: SConscripts are only needed in directories where something needs
823 # to be done, building or installing
825 if os.path.exists (os.path.join (d, 'SConscript')):
826 b = os.path.join (env['build'], d, env['out'])
827 # Support clean sourcetree build (--srcdir build)
829 if os.path.abspath (b) != os.path.abspath (d):
830 env.BuildDir (b, d, duplicate = 0)
831 SConscript (os.path.join (b, 'SConscript'))