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]*).*$',
240 def get_version (program):
241 command = '(pkg-config --modversion %(program)s || %(program)s --version || %(program)s -V) 2>&1' % vars ()
242 pipe = os.popen (command)
243 output = pipe.read ()
246 v = re.sub (vre, '\\1', output)
249 return string.split (v, '.')
251 def test_program (lst, program, minimal, description, package):
252 sys.stdout.write ('Checking %s version... ' % program)
253 actual = get_version (program)
256 lst.append ((description, package, minimal, program,
259 sys.stdout.write (string.join (actual, '.'))
260 sys.stdout.write ('\n')
261 if map (string.atoi, actual) \
262 < map (string.atoi, string.split (minimal, '.')):
263 lst.append ((description, package, minimal, program,
264 string.join (actual, '.')))
268 def test_lib (lst, program, minimal, description):
269 # FIXME: test for Debian or RPM (or -foo?) based dists
270 # to guess (or get correct!: apt-cache search?)
272 #if os.system ('pkg-config --atleast-version=0 freetype2'):
274 if test_program (lst, program, minimal, description,
275 'lib%(program)s-dev or %(program)s-devel'
277 env.ParseConfig ('pkg-config --cflags --libs %(program)s'
282 for i in ['bash', 'perl', 'python', 'sh']:
283 sys.stdout.write ('Checking for %s... ' % i)
285 key = string.upper (i)
290 sys.stdout.write ('not found: %s (using: %s)' \
293 sys.stdout.write ('\n')
296 test_program (required, 'gcc', '2.8', 'GNU C compiler', 'gcc')
297 test_program (required, 'g++', '3.0.5', 'GNU C++ compiler', 'g++')
298 test_program (required, 'python', '2.1', 'Python (www.python.org)', 'python')
299 test_program (required, 'guile-config', '1.6', 'GUILE development',
300 'libguile-dev or guile-devel')
301 # Do not use bison 1.50 and 1.75.
302 test_program (required, 'bison', '1.25', 'Bison -- parser generator',
304 test_program (required, 'flex', '0.0', 'Flex -- lexer generator', 'flex')
307 test_program (optional, 'makeinfo', '4.7', 'Makeinfo tool', 'texinfo')
308 test_program (optional, 'guile', '1.6', 'GUILE scheme', 'guile')
309 test_program (optional, 'gs', '8.14', 'Ghostscript PostScript interpreter', 'gs or gs-afpl or gs-esp or gs-gpl')
310 test_program (optional, 'mftrace', '1.1.0', 'Metafont tracing Type1',
312 test_program (optional, 'perl', '4.0',
313 'Perl practical efficient readonly language', 'perl')
314 #test_program (optional, 'foo', '2.0', 'Foomatic tester', 'bar')
316 def CheckYYCurrentBuffer (context):
317 context.Message ('Checking for yy_current_buffer... ')
318 ret = conf.TryCompile ("""using namespace std;
319 #include <FlexLexer.h>
320 class yy_flex_lexer: public yyFlexLexer
325 yy_current_buffer = 0;
331 conf = Configure (env, custom_tests = { 'CheckYYCurrentBuffer'
332 : CheckYYCurrentBuffer })
335 'DIRSEP' : "'%s'" % os.sep,
336 'PATHSEP' : "'%s'" % os.pathsep,
337 'PACKAGE': '"%s"' % package.name,
338 'DATADIR' : '"%s"' % sharedir,
339 'PACKAGE_DATADIR' : '"%s"' % sharedir_package,
340 'LOCALEDIR' : '"%s"' %localedir,
342 conf.env.Append (DEFINES = defines)
344 command = r"""python -c 'import sys; sys.stdout.write ("%s/include/python%s" % (sys.prefix, sys.version[:3]))'""" #"
345 PYTHON_INCLUDE = os.popen (command).read ()
347 env.Append (CCFLAGS = ['-I%s ' % PYTHON_INCLUDE])
349 env.Append (CPPPATH = PYTHON_INCLUDE)
351 headers = ('sys/stat.h', 'assert.h', 'kpathsea/kpathsea.h', 'libio.h',
354 if conf.CheckCHeader (i):
355 key = re.sub ('[./]', '_', 'HAVE_' + string.upper (i))
356 conf.env['DEFINES'][key] = 1
358 ccheaders = ('sstream',)
360 if conf.CheckCXXHeader (i):
361 key = re.sub ('[./]', '_', 'HAVE_' + string.upper (i))
362 conf.env['DEFINES'][key] = 1
364 functions = ('fopencookie', 'funopen',
365 'gettext', 'isinf', 'memmem', 'snprintf', 'vsnprintf')
367 if 0 or conf.CheckFunc (i):
368 key = re.sub ('[./]', '_', 'HAVE_' + string.upper (i))
369 conf.env['DEFINES'][key] = 1
371 if conf.CheckYYCurrentBuffer ():
372 conf.env['DEFINES']['HAVE_FLEXLEXER_YY_CURRENT_BUFFER'] = 1
374 if conf.CheckLib ('dl'):
377 if conf.CheckLib ('kpathsea'):
378 conf.env['DEFINES']['KPATHSEA'] = 1
381 if conf.CheckLib ('kpathsea', 'kpse_find_file'):
382 conf.env['DEFINES']['HAVE_KPSE_FIND_FILE'] = '1'
383 if conf.CheckLib ('kpathsea', 'kpse_find_tfm'):
384 conf.env['DEFINES']['HAVE_KPSE_FIND_TFM'] = '1'
386 # FIXME fc3 - move to kpath-guile/SConscript?
387 conf.env['DEFINES']['HAVE_LIBKPATHSEA_SO'] = '1'
391 if env.has_key ('CPPPATH'):
392 cpppath = env['CPPPATH']
394 ## FIXME: linkage, check for libguile.h and scm_boot_guile
395 #this could happen after flower...
396 env.ParseConfig ('guile-config compile')
398 test_program (required, 'pkg-config', '0.9.0',
399 'pkg-config library compile manager', 'pkg-config')
400 if test_lib (required, 'freetype2', '0.0',
401 'Development files for FreeType 2 font engine'):
402 conf.env['DEFINES']['HAVE_FREETYPE2'] = '1'
404 if test_lib (required, 'pangoft2', '1.6.0',
405 'Development files for pango, with fontconfig2'):
406 conf.env['DEFINES']['HAVE_PANGO_FT2'] = '1'
407 conf.env['DEFINES']['HAVE_PANGO16'] = '1'
409 if test_lib (optional, 'fontconfig', '2.2.0',
410 'Development files for fontconfig'):
411 conf.env['DEFINES']['HAVE_FONTCONFIG'] = '1'
413 #this could happen only for compiling pango-*
415 test_lib (required, 'gtk+-2.0', '2.4.0',
416 'Development files for GTK+')
417 if test_lib (required, 'pango', '1.6.0',
418 'Development files for pango'):
419 conf.env['DEFINES']['HAVE_PANGO16'] = '1'
421 if conf.CheckCHeader ('pango/pangofc-fontmap.h'):
422 conf.env['DEFINES']['HAVE_PANGO_PANGOFC_FONTMAP_H'] = '1'
423 if conf.CheckLib ('pango-1.0',
424 'pango_fc_font_map_add_decoder_find_func'):
425 conf.env['DEFINES']['HAVE_PANGO16'] = '1'
426 conf.env['DEFINES']['HAVE_PANGO_FC_FONT_MAP_ADD_DECODER_FIND_FUNC'] = '1'
429 # Using CCFLAGS = -I<system-dir> rather than CPPPATH = [
430 # <system-dir>] speeds up SCons
431 env['CCFLAGS'] += map (lambda x: '-I' + x,
432 env['CPPPATH'][len (cpppath):])
433 env['CPPPATH'] = cpppath
437 print '********************************'
438 print 'Please install required packages'
440 print '%s: %s-%s or newer (found: %s %s)' % i
445 print '*************************************'
446 print 'Consider installing optional packages'
448 print '%s: %s-%s or newer (found: %s %s)' % i
450 return conf.Finish ()
452 def config_header (target, source, env):
453 config = open (str (target[0]), 'w')
454 for i in list_sort (env['DEFINES'].keys ()):
455 config.write ('#define %s %s\n' % (i, env['DEFINES'][i]))
457 env.Command (config_hh, config_cache, config_header)
473 if not d.has_key (lst[i]):
481 def uniquify_config_vars (env):
482 for i in config_vars:
483 if env.has_key (i) and type (env[i]) == type ([]):
484 env[i] = uniquify (env[i])
486 def save_config_cache (env):
487 ## FIXME: Is this smart, using option cache for saving
488 ## config.cache? I cannot seem to find the official method.
489 uniquify_config_vars (env)
490 opts.Save (config_cache, env)
492 if 'config' in COMMAND_LINE_TARGETS:
493 sys.stdout.write ('\n')
494 sys.stdout.write ('LilyPond configured')
495 sys.stdout.write ('\n')
496 sys.stdout.write ('now run')
497 sys.stdout.write ('\n')
498 sys.stdout.write (' scons [TARGET|DIR]...')
499 sys.stdout.write ('\n')
501 elif not env['checksums']:
502 # When using timestams, config.hh is NEW. The next
503 # build triggers recompilation of everything. Exiting
504 # here makes SCons use the actual timestamp for config.hh
505 # and prevents recompiling everything the next run.
506 command = sys.argv[0] + ' ' + string.join (COMMAND_LINE_TARGETS)
507 sys.stdout.write ('Running %s ... ' % command)
508 sys.stdout.write ('\n')
509 s = os.system (command)
513 if os.path.exists (config_cache) and 'config' in COMMAND_LINE_TARGETS:
514 os.unlink (config_cache)
516 # scons: *** Calling Configure from Builders is not supported.
517 # env.Command (config_cache, None, configure)
518 if not os.path.exists (config_cache) \
519 or (os.stat ('SConstruct')[stat.ST_MTIME]
520 > os.stat (config_cache)[stat.ST_MTIME]):
521 env = configure (None, None, env)
522 save_config_cache (env)
523 elif env['checksums']:
524 # just save everything
525 save_config_cache (env)
527 #urg how does #/ subst work?
529 SConscript ('buildscripts/builder.py')
531 env.PrependENVPath ('PATH',
532 os.path.join (env['absbuild'], env['out'], 'usr/bin'))
534 if os.environ.has_key ('TEXMF'):
535 env.Append (ENV = {'TEXMF' : os.environ['TEXMF']})
537 'TEXMF' : '{$LILYPONDPREFIX,' \
538 + os.popen ('kpsexpand \$TEXMF').read ()[:-1] + '}',
539 'LILYPONDPREFIX' : os.path.join (run_prefix, 'share/lilypond'),
542 BUILD_ABC2LY = '${set__x}$PYTHON $srcdir/scripts/abc2ly.py'
543 BUILD_LILYPOND = '${set__x}$PYTHON $srcdir/scripts/lilypond.py${__verbose}'
544 BUILD_LILYPOND_BIN = '$absbuild/$out/lilypond-bin ${__verbose}'
545 BUILD_LILYPOND_BOOK = '$PYTHON $srcdir/scripts/lilypond-book.py --verbose'
548 # post-option environment-update
552 lilypond_datadir = sharedir_package,
553 localedir = localedir,
554 local_lilypond_datadir = sharedir_package_version,
555 lilypondprefix = lilypondprefix,
556 sharedir_package = sharedir_package,
557 sharedir_doc_package = sharedir_doc_package,
558 sharedir_package_version = sharedir_package_version,
560 LILYPOND = BUILD_LILYPOND,
561 ABC2LY = BUILD_ABC2LY,
562 LILYPOND_BOOK = BUILD_LILYPOND_BOOK,
563 LILYPOND_BOOK_FORMAT = 'texi-html',
564 MAKEINFO_FLAGS = '--css-include=$srcdir/Documentation/texinfo.css',
566 TEXI2DVI_PAPERSIZE = '@afourpaper',
567 TEXI2DVI_FLAGS = [ '-t $TEXI2DVI_PAPERSIZE'],
568 DVIPS_PAPERSIZE = 'a4',
569 DVIPS_FLAGS = ['-t $DVIPS_PAPERSIZE',
571 '-u+ec-mftrace.map'],
572 PSPDF_FLAGS = ['-sPAPERSIZE=$DVIPS_PAPERSIZE'],
576 env.Append (CCFLAGS = ['-g', '-pipe'])
577 if env['optimising']:
578 env.Append (CCFLAGS = '-O2')
579 env.Append (CXXFLAGS = ['-DSTRING_UTILS_INLINED'])
581 env.Append (CCFLAGS = ['-W', '-Wall'])
582 env.Append (CXXFLAGS = ['-Wconversion'])
585 env.Append (LINKFLAGS = ['-Wl,--export-dynamic'])
588 env['__verbose'] = ' --verbose'
589 env['set__x'] = 'set -x;'
592 ## Explicit target and dependencies
594 if 'clean' in COMMAND_LINE_TARGETS:
595 # ugh: prevent reconfigure instead of clean
596 os.system ('touch %s' % config_cache)
598 command = sys.argv[0] + ' -c .'
599 sys.stdout.write ('Running %s ... ' % command)
600 sys.stdout.write ('\n')
601 s = os.system (command)
602 if os.path.exists (config_cache):
603 os.unlink (config_cache)
606 if 'sconsclean' in COMMAND_LINE_TARGETS:
607 command = 'rm -rf scons.cache $(find . -name ".scon*")'
608 s = os.system (command)
609 if os.path.exists (config_cache):
610 os.unlink (config_cache)
613 if 'realclean' in COMMAND_LINE_TARGETS:
614 command = 'rm -rf $(find . -name "out-scons" -o -name ".scon*")'
615 sys.stdout.write ('Running %s ... ' % command)
616 sys.stdout.write ('\n')
617 s = os.system (command)
618 if os.path.exists (config_cache):
619 os.unlink (config_cache)
622 # Declare SConscript phonies
623 env.Alias ('minimal', config_cache)
624 env.Alias ('mf-essential', config_cache)
626 env.Alias ('minimal', ['lily', 'mf-essential'])
627 env.Alias ('all', ['minimal', 'mf', '.'])
628 # Do we want the doc/web separation?
631 'Documentation/user',
632 'Documentation/topdocs',
633 'Documentation/bibliography',
636 # Without target arguments, do minimal build
637 if not COMMAND_LINE_TARGETS:
638 env.Default (['minimal'])
640 # GNU Make rerouting compat:
641 env.Alias ('web', 'doc')
644 env.Command (version_hh, '#/VERSION',
645 '$PYTHON ./stepmake/bin/make-version.py VERSION > $TARGET')
647 # post-config environment update
649 run_prefix = run_prefix,
650 LILYPONDPREFIX = os.path.join (run_prefix, 'share/lilypond'),
652 # FIXME: move to lily/SConscript?
653 LIBPATH = [os.path.join (absbuild, 'flower', env['out']),
654 os.path.join (absbuild, 'kpath-guile', env['out']),
655 os.path.join (absbuild, 'ttftool', env['out']),],
656 CPPPATH = [outdir, ],
657 LILYPOND_PATH = ['.', '$srcdir/input',
658 '$srcdir/input/regression',
659 '$srcdir/input/test',
660 '$srcdir/input/tutorial',
661 '$srcdir/Documentation/user',
663 # os.path.join (absbuild, 'Documentation',
665 # os.path.join (absbuild, 'Documentation/user',
668 MAKEINFO_PATH = ['.', '$srcdir/Documentation/user',
669 '$absbuild/Documentation/user/$out'],
672 def symlink_tree (target, source, env):
678 if not os.path.isdir (dir):
679 if os.path.exists (dir):
683 map (mkdir, string.split (dir, os.sep))
684 def symlink (src, dst):
686 dir = os.path.dirname (dst)
689 frm = os.path.join (srcdir, src[1:])
691 depth = len (string.split (dir, '/'))
692 if src.find ('@') > -1:
693 frm = os.path.join ('../' * depth,
694 string.replace (src, '@',
697 frm = os.path.join ('../' * depth, src,
700 frm = os.path.join (frm, os.path.basename (dst))
702 print 'ln -s %s -> %s' % (frm, os.path.basename (dst))
703 os.symlink (frm, os.path.basename (dst))
704 shutil.rmtree (run_prefix)
705 prefix = os.path.join (env['out'], 'usr')
706 map (lambda x: symlink (x[0], os.path.join (prefix,
707 x[1] % {'ver' : version})),
710 # /$ := add dst file_name
711 (('python', 'lib/lilypond/python'),
712 ('lily/', 'bin/lilypond'),
713 ('scripts/', 'bin/convert-ly'),
714 ('scripts/', 'bin/lilypond-book'),
715 ('scripts/', 'bin/ps2png'),
716 ('mf', 'share/lilypond/%(ver)s/dvips/mf-out'),
717 ('#ps', 'share/lilypond/%(ver)s/dvips/ps'),
718 ('#ps', 'share/lilypond/%(ver)s/tex/music-drawing-routines.ps'),
719 ('mf', 'share/lilypond/%(ver)s/otf'),
720 ('mf', 'share/lilypond/%(ver)s/tfm'),
721 ('tex', 'share/lilypond/%(ver)s/tex/enc'),
722 ('#mf', 'share/lilypond/%(ver)s/fonts/mf'),
723 ('mf', 'share/lilypond/%(ver)s/fonts/map'),
724 ('mf', 'share/lilypond/%(ver)s/fonts/otf'),
725 ('mf', 'share/lilypond/%(ver)s/fonts/tfm'),
726 ('mf', 'share/lilypond/%(ver)s/fonts/type1'),
727 ('#tex', 'share/lilypond/%(ver)s/tex/source'),
728 ('tex', 'share/lilypond/%(ver)s/tex/tex-out'),
729 ('mf', 'share/lilypond/%(ver)s/tex/mf-out'),
730 ('#ly', 'share/lilypond/%(ver)s/ly'),
731 ('#scm', 'share/lilypond/%(ver)s/scm'),
732 ('#scripts', 'share/lilypond/%(ver)s/scripts'),
733 ('#ps', 'share/lilypond/%(ver)s/ps'),
734 ('po/@/nl.mo', 'share/locale/nl/LC_MESSAGES/lilypond.mo'),
735 ('elisp', 'share/lilypond/%(ver)s/elisp')))
739 stamp = os.path.join (run_prefix, 'stamp')
740 env.Command (stamp, 'SConstruct', [symlink_tree, 'touch $TARGET'])
741 env.Depends ('lily', stamp)
747 def cvs_entry_is_dir (line):
748 return line[0] == 'D' and line[-2] == '/'
750 def cvs_entry_is_file (line):
751 return line[0] == '/' and line[-2] == '/'
754 ENTRIES = os.path.join (dir, 'CVS/Entries')
755 if not os.path.exists (ENTRIES):
757 entries = open (ENTRIES).readlines ()
758 dir_entries = filter (cvs_entry_is_dir, entries)
759 dirs = map (lambda x: os.path.join (dir, x[2:x[2:].index ('/')+3]),
761 return dirs + map (cvs_dirs, dirs)
764 ENTRIES = os.path.join (dir, 'CVS/Entries')
765 entries = open (ENTRIES).readlines ()
766 file_entries = filter (cvs_entry_is_file, entries)
767 files = map (lambda x: x[1:x[1:].index ('/')+1], file_entries)
768 return map (lambda x: os.path.join (dir, x), files)
770 def flatten (tree, lst):
771 if type (tree) == type ([]):
773 if type (i) == type ([]):
780 and 'all' not in COMMAND_LINE_TARGETS\
781 and 'doc' not in COMMAND_LINE_TARGETS\
782 and 'web' not in COMMAND_LINE_TARGETS\
783 and 'install' not in COMMAND_LINE_TARGETS\
784 and 'clean' not in COMMAND_LINE_TARGETS:
785 subdirs = ['lily', 'lily/include',
786 'flower', 'flower/include',
792 subdirs = flatten (cvs_dirs ('.'), [])
794 src_files = reduce (lambda x, y: x + y, map (cvs_files, subdirs))
795 readme_files = ['AUTHORS', 'README', 'INSTALL', 'NEWS']
796 txt_files = map (lambda x: x + '.txt', readme_files)
800 # speeds up build by +- 5%
803 foo = map (lambda x: env.TXT (x + '.txt',
804 os.path.join ('Documentation/topdocs', x)),
806 tar_base = package.name + '-' + version
807 tar_name = tar_base + '.tar.gz'
808 ball_prefix = os.path.join (outdir, tar_base)
809 tar_ball = os.path.join (outdir, tar_name)
811 dist_files = src_files + txt_files
812 ball_files = map (lambda x: os.path.join (ball_prefix, x), dist_files)
813 map (lambda x: env.Depends (tar_ball, x), ball_files)
814 map (lambda x: env.Command (os.path.join (ball_prefix, x), x,
815 'ln $SOURCE $TARGET'), dist_files)
816 tar = env.Command (tar_ball, src_files,
817 ['rm -f $$(find $TARGET.dir -name .sconsign)',
818 'tar czf $TARGET -C $TARGET.dir %s' % tar_base,])
819 env.Alias ('tar', tar)
821 dist_ball = os.path.join (package.release_dir, tar_name)
822 env.Command (dist_ball, tar_ball,
823 'if [ -e $SOURCE -a -e $TARGET ]; then rm $TARGET; fi;' \
824 + 'ln $SOURCE $TARGET')
825 env.Depends ('dist', dist_ball)
826 patch_name = os.path.join (outdir, tar_base + '.diff.gz')
827 patch = env.PATCH (patch_name, tar_ball)
828 env.Depends (patch_name, dist_ball)
829 env.Alias ('release', patch)
833 web_base = os.path.join (outdir, 'web')
834 web_ball = web_base + '.tar.gz'
835 env['footify'] = 'MAILADDRESS=bug-lilypond@gnu.org $PYTHON stepmake/bin/add-html-footer.py --name=lilypond --version=$TOPLEVEL_VERSION'
836 web_ext = ['.html', '.ly', '.midi', '.pdf', '.png', '.ps.gz', '.txt',]
837 web_path = '-path "*/$out/*"' + string.join (web_ext, ' -or -path "*/$out/*"')
838 env['web_path'] = web_path
839 web_list = os.path.join (outdir, 'weblist')
840 # compatible make heritits
841 # fixme: generate in $outdir is cwd/builddir
842 env.Command (web_list,
843 ## this is correct, but takes > 5min if you have a peder :-)
846 ['$PYTHON buildscripts/mutopia-index.py -o examples.html ./',
847 'cd $absbuild && $footify $$(find . -name "*.html" -print)',
848 'cd $absbuild && rm -f $$(find . -name "*.html~" -print)',
849 'cd $absbuild && find Documentation input $web_path \
851 '''echo '<META HTTP-EQUIV="refresh" content="0;URL=Documentation/out-www/index.html">' > $absbuild/index.html''',
852 '''echo '<html><body>Redirecting to the documentation index...</body></html>' >> $absbuild/index.html''',
853 'cd $absbuild && ls *.html >> $TARGET',])
854 env.Command (web_ball, web_list,
855 ['cat $SOURCE | tar -C $absbuild -czf $TARGET -T -',])
856 #env.Alias ('web', web_ball)
857 www_base = os.path.join (outdir, 'www')
858 www_ball = www_base + '.tar.gz'
859 env.Command (www_ball, web_ball,
861 'mkdir -p $absbuild/$out/tmp',
862 'tar -C $absbuild/$out/tmp -xzf $SOURCE',
863 'cd $absbuild/$out/tmp && for i in $$(find . -name "$out"); '
864 + ' do mv $$i $$(dirname $$i)/out-www; done',
865 'tar -C $absbuild/$out/tmp -czf $TARGET .'])
866 env.Alias ('web', www_ball)
870 ETAGSFLAGS = """--regex='{c++}/^LY_DEFINE *(\([^,]+\)/\\1/' \
871 --regex='{c++}/^LY_DEFINE *([^"]*"\([^"]+\)"/\\1/'""")
872 code_ext = ['.cc', '.hh', '.scm', '.tcc',]
873 env.Command ('TAGS', filter (lambda x: os.path.splitext (x)[1] in code_ext,
875 'etags $ETAGSFLAGS $SOURCES')
877 # Note: SConscripts are only needed in directories where something needs
878 # to be done, building or installing
880 if os.path.exists (os.path.join (d, 'SConscript')):
881 b = os.path.join (env['build'], d, env['out'])
882 # Support clean sourcetree build (--srcdir build)
884 if os.path.abspath (b) != os.path.abspath (d):
885 env.BuildDir (b, d, duplicate = 0)
886 SConscript (os.path.join (b, 'SConscript'))