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