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 CPPDEFINES = '-DHAVE_CONFIG_H',
154 PERL = '/usr/bin/perl',
155 PYTHON = '/usr/bin/python',
158 MAKEINFO = 'LANG= makeinfo',
159 MF_TO_TABLE_PY = srcdir + '/buildscripts/mf-to-table.py',
161 PKG_CONFIG_PATH = [os.path.join (os.environ['HOME'],
162 'usr/pkg/gnome/lib'),
163 os.path.join (os.environ['HOME'],
164 'usr/pkg/pango/lib')],
167 TOPLEVEL_VERSION = version,
170 # Add all config_vars to opts, so that they will be read and saved
171 # together with the other configure options.
172 map (lambda x: opts.AddOptions ((x,)), config_vars)
174 Help (usage + opts.GenerateHelpText (env))
179 # Usability switch (Anthony Roach).
180 # See http://www.scons.org/cgi-bin/wiki/GoFastButton
181 # First do: scons realclean .
183 SetOption ('max_drift', 1)
184 SetOption ('implicit_cache', 1)
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)
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', 'libio.h',
337 if conf.CheckCHeader (i):
338 key = re.sub ('[./]', '_', 'HAVE_' + string.upper (i))
339 conf.env['DEFINES'][key] = 1
341 ccheaders = ('sstream',)
343 if conf.CheckCXXHeader (i):
344 key = re.sub ('[./]', '_', 'HAVE_' + string.upper (i))
345 conf.env['DEFINES'][key] = 1
347 functions = ('fopencookie', 'funopen',
348 'gettext', 'isinf', 'memmem', 'snprintf', 'vsnprintf')
350 if 0 or conf.CheckFunc (i):
351 key = re.sub ('[./]', '_', 'HAVE_' + string.upper (i))
352 conf.env['DEFINES'][key] = 1
354 if conf.CheckYYCurrentBuffer ():
355 conf.env['DEFINES']['HAVE_FLEXLEXER_YY_CURRENT_BUFFER'] = 1
357 if conf.CheckLib ('dl'):
360 if conf.CheckLib ('kpathsea'):
361 conf.env['DEFINES']['KPATHSEA'] = 1
364 if conf.CheckLib ('kpathsea', 'kpse_find_file'):
365 conf.env['DEFINES']['HAVE_KPSE_FIND_FILE'] = '1'
366 if conf.CheckLib ('kpathsea', 'kpse_find_tfm'):
367 conf.env['DEFINES']['HAVE_KPSE_FIND_TFM'] = '1'
369 # FIXME fc3 - move to kpath-guile/SConscript?
370 conf.env['DEFINES']['HAVE_LIBKPATHSEA_SO'] = '1'
374 if env.has_key ('CPPPATH'):
375 cpppath = env['CPPPATH']
377 ## FIXME: linkage, check for libguile.h and scm_boot_guile
378 #this could happen after flower...
379 env.ParseConfig ('guile-config compile')
381 ## FIXME: pkg-test to required/optional
382 if os.system ('pkg-config --atleast-version=1.6.0 pango'):
384 env.ParseConfig ('pkg-config --cflags --libs pango')
385 conf.env['DEFINES']['HAVE_PANGO16'] = '1'
387 if os.system ('pkg-config --atleast-version=1.6.0 pangoft2'):
389 env.ParseConfig ('pkg-config --cflags --libs pangoft2')
390 conf.env['DEFINES']['HAVE_PANGO_FT2'] = '1'
392 #this could happen only for compiling pango-*
394 env.ParseConfig ('pkg-config --cflags --libs gtk+-2.0')
395 env.ParseConfig ('pkg-config --cflags --libs pango')
396 if conf.CheckCHeader ('pango/pangofc-fontmap.h'):
397 conf.env['DEFINES']['HAVE_PANGO_PANGOFC_FONTMAP_H'] = '1'
399 if conf.CheckLib ('pango-1.0',
400 'pango_fc_font_map_add_decoder_find_func'):
401 conf.env['DEFINES']['HAVE_PANGO_CVS'] = '1'
402 conf.env['DEFINES']['HAVE_PANGO_FC_FONT_MAP_ADD_DECODER_FIND_FUNC'] = '1'
405 # Using CCFLAGS = -I<system-dir> rather than CPPPATH = [
406 # <system-dir>] speeds up SCons
407 env['CCFLAGS'] += map (lambda x: '-I' + x,
408 env['CPPPATH'][len (cpppath):])
409 env['CPPPATH'] = cpppath
413 print '********************************'
414 print 'Please install required packages'
416 print '%s: %s-%s or newer (found: %s %s)' % i
421 print '*************************************'
422 print 'Consider installing optional packages'
424 print '%s: %s-%s or newer (found: %s %s)' % i
426 return conf.Finish ()
428 def config_header (target, source, env):
429 config = open (str (target[0]), 'w')
430 for i in list_sort (env['DEFINES'].keys ()):
431 config.write ('#define %s %s\n' % (i, env['DEFINES'][i]))
433 env.Command (config_hh, config_cache, config_header)
449 if not d.has_key (lst[i]):
457 def uniquify_config_vars (env):
458 for i in config_vars:
459 if env.has_key (i) and type (env[i]) == type ([]):
460 env[i] = uniquify (env[i])
462 def save_config_cache (env):
463 ## FIXME: Is this smart, using option cache for saving
464 ## config.cache? I cannot seem to find the official method.
465 uniquify_config_vars (env)
466 opts.Save (config_cache, env)
468 if 'config' in COMMAND_LINE_TARGETS:
469 sys.stdout.write ('\n')
470 sys.stdout.write ('LilyPond configured')
471 sys.stdout.write ('\n')
472 sys.stdout.write ('now run')
473 sys.stdout.write ('\n')
474 sys.stdout.write (' scons [TARGET|DIR]...')
475 sys.stdout.write ('\n')
477 elif not env['checksums']:
478 # When using timestams, config.hh is NEW. The next
479 # build triggers recompilation of everything. Exiting
480 # here makes SCons use the actual timestamp for config.hh
481 # and prevents recompiling everything the next run.
482 command = sys.argv[0] + ' ' + string.join (COMMAND_LINE_TARGETS)
483 sys.stdout.write ('Running %s ... ' % command)
484 sys.stdout.write ('\n')
485 s = os.system (command)
489 if os.path.exists (config_cache) and 'config' in COMMAND_LINE_TARGETS:
490 os.unlink (config_cache)
492 # scons: *** Calling Configure from Builders is not supported.
493 # env.Command (config_cache, None, configure)
494 if not os.path.exists (config_cache) \
495 or (os.stat ('SConstruct')[stat.ST_MTIME]
496 > os.stat (config_cache)[stat.ST_MTIME]):
497 env = configure (None, None, env)
498 save_config_cache (env)
499 elif env['checksums']:
500 # just save everything
501 save_config_cache (env)
503 #urg how does #/ subst work?
505 SConscript ('buildscripts/builder.py')
507 env.PrependENVPath ('PATH',
508 os.path.join (env['absbuild'], env['out'], 'usr/bin'))
510 if os.environ.has_key ('TEXMF'):
511 env.Append (ENV = {'TEXMF' : os.environ['TEXMF']})
513 'TEXMF' : '{$LILYPONDPREFIX,' \
514 + os.popen ('kpsexpand \$TEXMF').read ()[:-1] + '}',
515 'LILYPONDPREFIX' : os.path.join (run_prefix, 'share/lilypond'),
518 BUILD_ABC2LY = '${set__x}$PYTHON $srcdir/scripts/abc2ly.py'
519 BUILD_LILYPOND = '${set__x}$PYTHON $srcdir/scripts/lilypond.py${__verbose}'
520 BUILD_LILYPOND_BIN = '$absbuild/$out/lilypond-bin ${__verbose}'
521 BUILD_LILYPOND_BOOK = '$PYTHON $srcdir/scripts/lilypond-book.py --verbose'
524 # post-option environment-update
528 lilypond_datadir = sharedir_package,
529 localedir = localedir,
530 local_lilypond_datadir = sharedir_package_version,
531 lilypondprefix = lilypondprefix,
532 sharedir_package = sharedir_package,
533 sharedir_doc_package = sharedir_doc_package,
534 sharedir_package_version = sharedir_package_version,
536 LILYPOND = BUILD_LILYPOND,
537 ABC2LY = BUILD_ABC2LY,
538 LILYPOND_BOOK = BUILD_LILYPOND_BOOK,
539 LILYPOND_BOOK_FORMAT = 'texi-html',
540 MAKEINFO_FLAGS = '--css-include=$srcdir/Documentation/texinfo.css',
542 TEXI2DVI_PAPERSIZE = '@afourpaper',
543 TEXI2DVI_FLAGS = [ '-t $TEXI2DVI_PAPERSIZE'],
544 DVIPS_PAPERSIZE = 'a4',
545 DVIPS_FLAGS = ['-t $DVIPS_PAPERSIZE',
547 '-u+ec-mftrace.map'],
548 PSPDF_FLAGS = ['-sPAPERSIZE=$DVIPS_PAPERSIZE'],
552 env.Append (CCFLAGS = ['-g', '-pipe'])
553 if env['optimising']:
554 env.Append (CCFLAGS = '-O2')
555 env.Append (CXXFLAGS = ['-DSTRING_UTILS_INLINED'])
557 env.Append (CCFLAGS = ['-W', '-Wall'])
558 env.Append (CXXFLAGS = ['-Wconversion'])
561 env.Append (LINKFLAGS = ['-Wl,--export-dynamic'])
564 env['__verbose'] = ' --verbose'
565 env['set__x'] = 'set -x;'
568 ## Explicit target and dependencies
570 if 'clean' in COMMAND_LINE_TARGETS:
571 # ugh: prevent reconfigure instead of clean
572 os.system ('touch %s' % config_cache)
574 command = sys.argv[0] + ' -c .'
575 sys.stdout.write ('Running %s ... ' % command)
576 sys.stdout.write ('\n')
577 s = os.system (command)
578 if os.path.exists (config_cache):
579 os.unlink (config_cache)
582 if 'sconsclean' in COMMAND_LINE_TARGETS:
583 command = 'rm -rf scons.cache $(find . -name ".scon*")'
584 s = os.system (command)
585 if os.path.exists (config_cache):
586 os.unlink (config_cache)
589 if 'realclean' in COMMAND_LINE_TARGETS:
590 command = 'rm -rf $(find . -name "out-scons" -o -name ".scon*")'
591 sys.stdout.write ('Running %s ... ' % command)
592 sys.stdout.write ('\n')
593 s = os.system (command)
594 if os.path.exists (config_cache):
595 os.unlink (config_cache)
598 # Declare SConscript phonies
599 env.Alias ('minimal', config_cache)
600 env.Alias ('mf-essential', config_cache)
602 env.Alias ('minimal', ['lily', 'mf-essential'])
603 env.Alias ('all', ['minimal', 'mf', '.'])
604 # Do we want the doc/web separation?
607 'Documentation/user',
608 'Documentation/topdocs',
609 'Documentation/bibliography',
612 # Without target arguments, do minimal build
613 if not COMMAND_LINE_TARGETS:
614 env.Default (['minimal'])
616 # GNU Make rerouting compat:
617 env.Alias ('web', 'doc')
620 env.Command (version_hh, '#/VERSION',
621 '$PYTHON ./stepmake/bin/make-version.py VERSION > $TARGET')
623 # post-config environment update
625 run_prefix = run_prefix,
626 LILYPONDPREFIX = os.path.join (run_prefix, 'share/lilypond'),
628 # FIXME: move to lily/SConscript?
629 LIBPATH = [os.path.join (absbuild, 'flower', env['out']),
630 os.path.join (absbuild, 'kpath-guile', env['out']),
631 os.path.join (absbuild, 'ttftool', env['out']),],
632 CPPPATH = [outdir, ],
633 LILYPOND_PATH = ['.', '$srcdir/input',
634 '$srcdir/input/regression',
635 '$srcdir/input/test',
636 '$srcdir/input/tutorial',
637 '$srcdir/Documentation/user',
639 # os.path.join (absbuild, 'Documentation',
641 # os.path.join (absbuild, 'Documentation/user',
644 MAKEINFO_PATH = ['.', '$srcdir/Documentation/user',
645 '$absbuild/Documentation/user/$out'],
648 def symlink_tree (target, source, env):
654 if not os.path.isdir (dir):
655 if os.path.exists (dir):
659 map (mkdir, string.split (dir, os.sep))
660 def symlink (src, dst):
662 dir = os.path.dirname (dst)
665 frm = os.path.join (srcdir, src[1:])
667 depth = len (string.split (dir, '/'))
668 if src.find ('@') > -1:
669 frm = os.path.join ('../' * depth,
670 string.replace (src, '@',
673 frm = os.path.join ('../' * depth, src,
676 frm = os.path.join (frm, os.path.basename (dst))
678 print 'ln -s %s -> %s' % (frm, os.path.basename (dst))
679 os.symlink (frm, os.path.basename (dst))
680 shutil.rmtree (run_prefix)
681 prefix = os.path.join (env['out'], 'usr')
682 map (lambda x: symlink (x[0], os.path.join (prefix,
683 x[1] % {'ver' : version})),
686 # /$ := add dst file_name
687 (('python', 'lib/lilypond/python'),
688 ('lily/', 'bin/lilypond-bin'),
689 ('scripts/', 'bin/lilypond'),
690 ('scripts/', 'bin/lilypond-book'),
691 ('mf', 'share/lilypond/%(ver)s/dvips/mf-out'),
692 ('#ps', 'share/lilypond/%(ver)s/dvips/ps'),
693 ('#ps', 'share/lilypond/%(ver)s/tex/music-drawing-routines.ps'),
694 ('mf', 'share/lilypond/%(ver)s/otf'),
695 ('mf', 'share/lilypond/%(ver)s/tfm'),
696 ('tex', 'share/lilypond/%(ver)s/tex/enc'),
697 ('#mf', 'share/lilypond/%(ver)s/fonts/mf'),
698 ('mf', 'share/lilypond/%(ver)s/fonts/map'),
699 ('mf', 'share/lilypond/%(ver)s/fonts/otf'),
700 ('mf', 'share/lilypond/%(ver)s/fonts/tfm'),
701 ('mf', 'share/lilypond/%(ver)s/fonts/type1'),
702 ('#tex', 'share/lilypond/%(ver)s/tex/source'),
703 ('tex', 'share/lilypond/%(ver)s/tex/tex-out'),
704 ('mf', 'share/lilypond/%(ver)s/tex/mf-out'),
705 ('#ly', 'share/lilypond/%(ver)s/ly'),
706 ('#scm', 'share/lilypond/%(ver)s/scm'),
707 ('#ps', 'share/lilypond/%(ver)s/ps'),
708 ('po/@/nl.mo', 'share/locale/nl/LC_MESSAGES/lilypond.mo'),
709 ('elisp', 'share/lilypond/%(ver)s/elisp')))
713 stamp = os.path.join (run_prefix, 'stamp')
714 env.Command (stamp, 'SConstruct', [symlink_tree, 'touch $TARGET'])
715 env.Depends ('lily', stamp)
721 def cvs_entry_is_dir (line):
722 return line[0] == 'D' and line[-2] == '/'
724 def cvs_entry_is_file (line):
725 return line[0] == '/' and line[-2] == '/'
728 ENTRIES = os.path.join (dir, 'CVS/Entries')
729 if not os.path.exists (ENTRIES):
731 entries = open (ENTRIES).readlines ()
732 dir_entries = filter (cvs_entry_is_dir, entries)
733 dirs = map (lambda x: os.path.join (dir, x[2:x[2:].index ('/')+3]),
735 return dirs + map (cvs_dirs, dirs)
738 ENTRIES = os.path.join (dir, 'CVS/Entries')
739 entries = open (ENTRIES).readlines ()
740 file_entries = filter (cvs_entry_is_file, entries)
741 files = map (lambda x: x[1:x[1:].index ('/')+1], file_entries)
742 return map (lambda x: os.path.join (dir, x), files)
744 def flatten (tree, lst):
745 if type (tree) == type ([]):
747 if type (i) == type ([]):
754 and 'all' not in COMMAND_LINE_TARGETS\
755 and 'doc' not in COMMAND_LINE_TARGETS\
756 and 'web' not in COMMAND_LINE_TARGETS\
757 and 'install' not in COMMAND_LINE_TARGETS\
758 and 'clean' not in COMMAND_LINE_TARGETS:
759 subdirs = ['lily', 'lily/include',
760 'flower', 'flower/include',
766 subdirs = flatten (cvs_dirs ('.'), [])
768 src_files = reduce (lambda x, y: x + y, map (cvs_files, subdirs))
769 readme_files = ['AUTHORS', 'README', 'INSTALL', 'NEWS']
770 txt_files = map (lambda x: x + '.txt', readme_files)
774 # speeds up build by +- 5%
777 foo = map (lambda x: env.TXT (x + '.txt',
778 os.path.join ('Documentation/topdocs', x)),
780 tar_base = package.name + '-' + version
781 tar_name = tar_base + '.tar.gz'
782 ball_prefix = os.path.join (outdir, tar_base)
783 tar_ball = os.path.join (outdir, tar_name)
785 dist_files = src_files + txt_files
786 ball_files = map (lambda x: os.path.join (ball_prefix, x), dist_files)
787 map (lambda x: env.Depends (tar_ball, x), ball_files)
788 map (lambda x: env.Command (os.path.join (ball_prefix, x), x,
789 'ln $SOURCE $TARGET'), dist_files)
790 tar = env.Command (tar_ball, src_files,
791 ['rm -f $$(find $TARGET.dir -name .sconsign)',
792 'tar czf $TARGET -C $TARGET.dir %s' % tar_base,])
793 env.Alias ('tar', tar)
795 dist_ball = os.path.join (package.release_dir, tar_name)
796 env.Command (dist_ball, tar_ball,
797 'if [ -e $SOURCE -a -e $TARGET ]; then rm $TARGET; fi;' \
798 + 'ln $SOURCE $TARGET')
799 env.Depends ('dist', dist_ball)
800 patch_name = os.path.join (outdir, tar_base + '.diff.gz')
801 patch = env.PATCH (patch_name, tar_ball)
802 env.Depends (patch_name, dist_ball)
803 env.Alias ('release', patch)
807 web_base = os.path.join (outdir, 'web')
808 web_ball = web_base + '.tar.gz'
809 env['footify'] = 'MAILADDRESS=bug-lilypond@gnu.org $PYTHON stepmake/bin/add-html-footer.py --name=lilypond --version=$TOPLEVEL_VERSION'
810 web_ext = ['.html', '.ly', '.midi', '.pdf', '.png', '.ps.gz', '.txt',]
811 web_path = '-path "*/$out/*"' + string.join (web_ext, ' -or -path "*/$out/*"')
812 env['web_path'] = web_path
813 web_list = os.path.join (outdir, 'weblist')
814 # compatible make heritits
815 # fixme: generate in $outdir is cwd/builddir
816 env.Command (web_list,
817 ## this is correct, but takes > 5min if you have a peder :-)
820 ['$PYTHON buildscripts/mutopia-index.py -o examples.html ./',
821 'cd $absbuild && $footify $$(find . -name "*.html" -print)',
822 'cd $absbuild && rm -f $$(find . -name "*.html~" -print)',
823 'cd $absbuild && find Documentation input $web_path \
825 '''echo '<META HTTP-EQUIV="refresh" content="0;URL=Documentation/out-www/index.html">' > $absbuild/index.html''',
826 '''echo '<html><body>Redirecting to the documentation index...</body></html>' >> $absbuild/index.html''',
827 'cd $absbuild && ls *.html >> $TARGET',])
828 env.Command (web_ball, web_list,
829 ['cat $SOURCE | tar -C $absbuild -czf $TARGET -T -',])
830 #env.Alias ('web', web_ball)
831 www_base = os.path.join (outdir, 'www')
832 www_ball = www_base + '.tar.gz'
833 env.Command (www_ball, web_ball,
835 'mkdir -p $absbuild/$out/tmp',
836 'tar -C $absbuild/$out/tmp -xzf $SOURCE',
837 'cd $absbuild/$out/tmp && for i in $$(find . -name "$out"); '
838 + ' do mv $$i $$(dirname $$i)/out-www; done',
839 'tar -C $absbuild/$out/tmp -czf $TARGET .'])
840 env.Alias ('web', www_ball)
844 ETAGSFLAGS = """--regex='{c++}/^LY_DEFINE *(\([^,]+\)/\\1/' \
845 --regex='{c++}/^LY_DEFINE *([^"]*"\([^"]+\)"/\\1/'""")
846 code_ext = ['.cc', '.hh', '.scm', '.tcc',]
847 env.Command ('TAGS', filter (lambda x: os.path.splitext (x)[1] in code_ext,
849 'etags $ETAGSFLAGS $SOURCES')
851 # Note: SConscripts are only needed in directories where something needs
852 # to be done, building or installing
854 if os.path.exists (os.path.join (d, 'SConscript')):
855 b = os.path.join (env['build'], d, env['out'])
856 # Support clean sourcetree build (--srcdir build)
858 if os.path.abspath (b) != os.path.abspath (d):
859 env.BuildDir (b, d, duplicate = 0)
860 SConscript (os.path.join (b, 'SConscript'))