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, 'mftrace', '1.1.0', 'Metafont tracing Type1',
311 test_program (optional, 'perl', '4.0',
312 'Perl practical efficient readonly language', 'perl')
313 #test_program (optional, 'foo', '2.0', 'Foomatic tester', 'bar')
315 def CheckYYCurrentBuffer (context):
316 context.Message ('Checking for yy_current_buffer... ')
317 ret = conf.TryCompile ("""using namespace std;
318 #include <FlexLexer.h>
319 class yy_flex_lexer: public yyFlexLexer
324 yy_current_buffer = 0;
330 conf = Configure (env, custom_tests = { 'CheckYYCurrentBuffer'
331 : CheckYYCurrentBuffer })
334 'DIRSEP' : "'%s'" % os.sep,
335 'PATHSEP' : "'%s'" % os.pathsep,
336 'PACKAGE': '"%s"' % package.name,
337 'DATADIR' : '"%s"' % sharedir,
338 'PACKAGE_DATADIR' : '"%s"' % sharedir_package,
339 'LOCALEDIR' : '"%s"' %localedir,
341 conf.env.Append (DEFINES = defines)
343 command = r"""python -c 'import sys; sys.stdout.write ("%s/include/python%s" % (sys.prefix, sys.version[:3]))'""" #"
344 PYTHON_INCLUDE = os.popen (command).read ()
346 env.Append (CCFLAGS = ['-I%s ' % PYTHON_INCLUDE])
348 env.Append (CPPPATH = PYTHON_INCLUDE)
350 headers = ('sys/stat.h', 'assert.h', 'kpathsea/kpathsea.h', 'libio.h',
353 if conf.CheckCHeader (i):
354 key = re.sub ('[./]', '_', 'HAVE_' + string.upper (i))
355 conf.env['DEFINES'][key] = 1
357 ccheaders = ('sstream',)
359 if conf.CheckCXXHeader (i):
360 key = re.sub ('[./]', '_', 'HAVE_' + string.upper (i))
361 conf.env['DEFINES'][key] = 1
363 functions = ('fopencookie', 'funopen',
364 'gettext', 'isinf', 'memmem', 'snprintf', 'vsnprintf')
366 if 0 or conf.CheckFunc (i):
367 key = re.sub ('[./]', '_', 'HAVE_' + string.upper (i))
368 conf.env['DEFINES'][key] = 1
370 if conf.CheckYYCurrentBuffer ():
371 conf.env['DEFINES']['HAVE_FLEXLEXER_YY_CURRENT_BUFFER'] = 1
373 if conf.CheckLib ('dl'):
376 if conf.CheckLib ('kpathsea'):
377 conf.env['DEFINES']['KPATHSEA'] = 1
380 if conf.CheckLib ('kpathsea', 'kpse_find_file'):
381 conf.env['DEFINES']['HAVE_KPSE_FIND_FILE'] = '1'
382 if conf.CheckLib ('kpathsea', 'kpse_find_tfm'):
383 conf.env['DEFINES']['HAVE_KPSE_FIND_TFM'] = '1'
385 # FIXME fc3 - move to kpath-guile/SConscript?
386 conf.env['DEFINES']['HAVE_LIBKPATHSEA_SO'] = '1'
390 if env.has_key ('CPPPATH'):
391 cpppath = env['CPPPATH']
393 ## FIXME: linkage, check for libguile.h and scm_boot_guile
394 #this could happen after flower...
395 env.ParseConfig ('guile-config compile')
397 test_program (required, 'pkg-config', '0.9.0',
398 'pkg-config library compile manager', 'pkg-config')
399 if test_lib (required, 'freetype2', '0.0',
400 'Development files for FreeType 2 font engine'):
401 conf.env['DEFINES']['HAVE_FREETYPE2'] = '1'
403 if test_lib (required, 'pangoft2', '1.6.0',
404 'Development files for pango, with fontconfig2'):
405 conf.env['DEFINES']['HAVE_PANGO_FT2'] = '1'
406 conf.env['DEFINES']['HAVE_PANGO16'] = '1'
408 if test_lib (optional, 'fontconfig', '2.2.0',
409 'Development files for fontconfig'):
410 conf.env['DEFINES']['HAVE_FONTCONFIG'] = '1'
412 #this could happen only for compiling pango-*
414 test_lib (required, 'gtk+-2.0', '2.4.0',
415 'Development files for GTK+')
416 if test_lib (required, 'pango', '1.6.0',
417 'Development files for pango'):
418 conf.env['DEFINES']['HAVE_PANGO16'] = '1'
420 if conf.CheckCHeader ('pango/pangofc-fontmap.h'):
421 conf.env['DEFINES']['HAVE_PANGO_PANGOFC_FONTMAP_H'] = '1'
422 if conf.CheckLib ('pango-1.0',
423 'pango_fc_font_map_add_decoder_find_func'):
424 conf.env['DEFINES']['HAVE_PANGO16'] = '1'
425 conf.env['DEFINES']['HAVE_PANGO_FC_FONT_MAP_ADD_DECODER_FIND_FUNC'] = '1'
428 # Using CCFLAGS = -I<system-dir> rather than CPPPATH = [
429 # <system-dir>] speeds up SCons
430 env['CCFLAGS'] += map (lambda x: '-I' + x,
431 env['CPPPATH'][len (cpppath):])
432 env['CPPPATH'] = cpppath
436 print '********************************'
437 print 'Please install required packages'
439 print '%s: %s-%s or newer (found: %s %s)' % i
444 print '*************************************'
445 print 'Consider installing optional packages'
447 print '%s: %s-%s or newer (found: %s %s)' % i
449 return conf.Finish ()
451 def config_header (target, source, env):
452 config = open (str (target[0]), 'w')
453 for i in list_sort (env['DEFINES'].keys ()):
454 config.write ('#define %s %s\n' % (i, env['DEFINES'][i]))
456 env.Command (config_hh, config_cache, config_header)
472 if not d.has_key (lst[i]):
480 def uniquify_config_vars (env):
481 for i in config_vars:
482 if env.has_key (i) and type (env[i]) == type ([]):
483 env[i] = uniquify (env[i])
485 def save_config_cache (env):
486 ## FIXME: Is this smart, using option cache for saving
487 ## config.cache? I cannot seem to find the official method.
488 uniquify_config_vars (env)
489 opts.Save (config_cache, env)
491 if 'config' in COMMAND_LINE_TARGETS:
492 sys.stdout.write ('\n')
493 sys.stdout.write ('LilyPond configured')
494 sys.stdout.write ('\n')
495 sys.stdout.write ('now run')
496 sys.stdout.write ('\n')
497 sys.stdout.write (' scons [TARGET|DIR]...')
498 sys.stdout.write ('\n')
500 elif not env['checksums']:
501 # When using timestams, config.hh is NEW. The next
502 # build triggers recompilation of everything. Exiting
503 # here makes SCons use the actual timestamp for config.hh
504 # and prevents recompiling everything the next run.
505 command = sys.argv[0] + ' ' + string.join (COMMAND_LINE_TARGETS)
506 sys.stdout.write ('Running %s ... ' % command)
507 sys.stdout.write ('\n')
508 s = os.system (command)
512 if os.path.exists (config_cache) and 'config' in COMMAND_LINE_TARGETS:
513 os.unlink (config_cache)
515 # scons: *** Calling Configure from Builders is not supported.
516 # env.Command (config_cache, None, configure)
517 if not os.path.exists (config_cache) \
518 or (os.stat ('SConstruct')[stat.ST_MTIME]
519 > os.stat (config_cache)[stat.ST_MTIME]):
520 env = configure (None, None, env)
521 save_config_cache (env)
522 elif env['checksums']:
523 # just save everything
524 save_config_cache (env)
526 #urg how does #/ subst work?
528 SConscript ('buildscripts/builder.py')
530 env.PrependENVPath ('PATH',
531 os.path.join (env['absbuild'], env['out'], 'usr/bin'))
533 if os.environ.has_key ('TEXMF'):
534 env.Append (ENV = {'TEXMF' : os.environ['TEXMF']})
536 'TEXMF' : '{$LILYPONDPREFIX,' \
537 + os.popen ('kpsexpand \$TEXMF').read ()[:-1] + '}',
538 'LILYPONDPREFIX' : os.path.join (run_prefix, 'share/lilypond'),
541 BUILD_ABC2LY = '${set__x}$PYTHON $srcdir/scripts/abc2ly.py'
542 BUILD_LILYPOND = '${set__x}$PYTHON $srcdir/scripts/lilypond.py${__verbose}'
543 BUILD_LILYPOND_BIN = '$absbuild/$out/lilypond-bin ${__verbose}'
544 BUILD_LILYPOND_BOOK = '$PYTHON $srcdir/scripts/lilypond-book.py --verbose'
547 # post-option environment-update
551 lilypond_datadir = sharedir_package,
552 localedir = localedir,
553 local_lilypond_datadir = sharedir_package_version,
554 lilypondprefix = lilypondprefix,
555 sharedir_package = sharedir_package,
556 sharedir_doc_package = sharedir_doc_package,
557 sharedir_package_version = sharedir_package_version,
559 LILYPOND = BUILD_LILYPOND,
560 ABC2LY = BUILD_ABC2LY,
561 LILYPOND_BOOK = BUILD_LILYPOND_BOOK,
562 LILYPOND_BOOK_FORMAT = 'texi-html',
563 MAKEINFO_FLAGS = '--css-include=$srcdir/Documentation/texinfo.css',
565 TEXI2DVI_PAPERSIZE = '@afourpaper',
566 TEXI2DVI_FLAGS = [ '-t $TEXI2DVI_PAPERSIZE'],
567 DVIPS_PAPERSIZE = 'a4',
568 DVIPS_FLAGS = ['-t $DVIPS_PAPERSIZE',
570 '-u+ec-mftrace.map'],
571 PSPDF_FLAGS = ['-sPAPERSIZE=$DVIPS_PAPERSIZE'],
575 env.Append (CCFLAGS = ['-g', '-pipe'])
576 if env['optimising']:
577 env.Append (CCFLAGS = '-O2')
578 env.Append (CXXFLAGS = ['-DSTRING_UTILS_INLINED'])
580 env.Append (CCFLAGS = ['-W', '-Wall'])
581 env.Append (CXXFLAGS = ['-Wconversion'])
584 env.Append (LINKFLAGS = ['-Wl,--export-dynamic'])
587 env['__verbose'] = ' --verbose'
588 env['set__x'] = 'set -x;'
591 ## Explicit target and dependencies
593 if 'clean' in COMMAND_LINE_TARGETS:
594 # ugh: prevent reconfigure instead of clean
595 os.system ('touch %s' % config_cache)
597 command = sys.argv[0] + ' -c .'
598 sys.stdout.write ('Running %s ... ' % command)
599 sys.stdout.write ('\n')
600 s = os.system (command)
601 if os.path.exists (config_cache):
602 os.unlink (config_cache)
605 if 'sconsclean' in COMMAND_LINE_TARGETS:
606 command = 'rm -rf scons.cache $(find . -name ".scon*")'
607 s = os.system (command)
608 if os.path.exists (config_cache):
609 os.unlink (config_cache)
612 if 'realclean' in COMMAND_LINE_TARGETS:
613 command = 'rm -rf $(find . -name "out-scons" -o -name ".scon*")'
614 sys.stdout.write ('Running %s ... ' % command)
615 sys.stdout.write ('\n')
616 s = os.system (command)
617 if os.path.exists (config_cache):
618 os.unlink (config_cache)
621 # Declare SConscript phonies
622 env.Alias ('minimal', config_cache)
623 env.Alias ('mf-essential', config_cache)
625 env.Alias ('minimal', ['lily', 'mf-essential'])
626 env.Alias ('all', ['minimal', 'mf', '.'])
627 # Do we want the doc/web separation?
630 'Documentation/user',
631 'Documentation/topdocs',
632 'Documentation/bibliography',
635 # Without target arguments, do minimal build
636 if not COMMAND_LINE_TARGETS:
637 env.Default (['minimal'])
639 # GNU Make rerouting compat:
640 env.Alias ('web', 'doc')
643 env.Command (version_hh, '#/VERSION',
644 '$PYTHON ./stepmake/bin/make-version.py VERSION > $TARGET')
646 # post-config environment update
648 run_prefix = run_prefix,
649 LILYPONDPREFIX = os.path.join (run_prefix, 'share/lilypond'),
651 # FIXME: move to lily/SConscript?
652 LIBPATH = [os.path.join (absbuild, 'flower', env['out']),
653 os.path.join (absbuild, 'kpath-guile', env['out']),
654 os.path.join (absbuild, 'ttftool', env['out']),],
655 CPPPATH = [outdir, ],
656 LILYPOND_PATH = ['.', '$srcdir/input',
657 '$srcdir/input/regression',
658 '$srcdir/input/test',
659 '$srcdir/input/tutorial',
660 '$srcdir/Documentation/user',
662 # os.path.join (absbuild, 'Documentation',
664 # os.path.join (absbuild, 'Documentation/user',
667 MAKEINFO_PATH = ['.', '$srcdir/Documentation/user',
668 '$absbuild/Documentation/user/$out'],
671 def symlink_tree (target, source, env):
677 if not os.path.isdir (dir):
678 if os.path.exists (dir):
682 map (mkdir, string.split (dir, os.sep))
683 def symlink (src, dst):
685 dir = os.path.dirname (dst)
688 frm = os.path.join (srcdir, src[1:])
690 depth = len (string.split (dir, '/'))
691 if src.find ('@') > -1:
692 frm = os.path.join ('../' * depth,
693 string.replace (src, '@',
696 frm = os.path.join ('../' * depth, src,
699 frm = os.path.join (frm, os.path.basename (dst))
701 print 'ln -s %s -> %s' % (frm, os.path.basename (dst))
702 os.symlink (frm, os.path.basename (dst))
703 shutil.rmtree (run_prefix)
704 prefix = os.path.join (env['out'], 'usr')
705 map (lambda x: symlink (x[0], os.path.join (prefix,
706 x[1] % {'ver' : version})),
709 # /$ := add dst file_name
710 (('python', 'lib/lilypond/python'),
711 ('lily/', 'bin/lilypond'),
712 ('scripts/', 'bin/convert-ly'),
713 ('scripts/', 'bin/lilypond-book'),
714 ('scripts/', 'bin/ps2png'),
715 ('mf', 'share/lilypond/%(ver)s/dvips/mf-out'),
716 ('#ps', 'share/lilypond/%(ver)s/dvips/ps'),
717 ('#ps', 'share/lilypond/%(ver)s/tex/music-drawing-routines.ps'),
718 ('mf', 'share/lilypond/%(ver)s/otf'),
719 ('mf', 'share/lilypond/%(ver)s/tfm'),
720 ('tex', 'share/lilypond/%(ver)s/tex/enc'),
721 ('#mf', 'share/lilypond/%(ver)s/fonts/mf'),
722 ('mf', 'share/lilypond/%(ver)s/fonts/map'),
723 ('mf', 'share/lilypond/%(ver)s/fonts/otf'),
724 ('mf', 'share/lilypond/%(ver)s/fonts/tfm'),
725 ('mf', 'share/lilypond/%(ver)s/fonts/type1'),
726 ('#tex', 'share/lilypond/%(ver)s/tex/source'),
727 ('tex', 'share/lilypond/%(ver)s/tex/tex-out'),
728 ('mf', 'share/lilypond/%(ver)s/tex/mf-out'),
729 ('#ly', 'share/lilypond/%(ver)s/ly'),
730 ('#scm', 'share/lilypond/%(ver)s/scm'),
731 ('#scripts', 'share/lilypond/%(ver)s/scripts'),
732 ('#ps', 'share/lilypond/%(ver)s/ps'),
733 ('po/@/nl.mo', 'share/locale/nl/LC_MESSAGES/lilypond.mo'),
734 ('elisp', 'share/lilypond/%(ver)s/elisp')))
738 stamp = os.path.join (run_prefix, 'stamp')
739 env.Command (stamp, 'SConstruct', [symlink_tree, 'touch $TARGET'])
740 env.Depends ('lily', stamp)
746 def cvs_entry_is_dir (line):
747 return line[0] == 'D' and line[-2] == '/'
749 def cvs_entry_is_file (line):
750 return line[0] == '/' and line[-2] == '/'
753 ENTRIES = os.path.join (dir, 'CVS/Entries')
754 if not os.path.exists (ENTRIES):
756 entries = open (ENTRIES).readlines ()
757 dir_entries = filter (cvs_entry_is_dir, entries)
758 dirs = map (lambda x: os.path.join (dir, x[2:x[2:].index ('/')+3]),
760 return dirs + map (cvs_dirs, dirs)
763 ENTRIES = os.path.join (dir, 'CVS/Entries')
764 entries = open (ENTRIES).readlines ()
765 file_entries = filter (cvs_entry_is_file, entries)
766 files = map (lambda x: x[1:x[1:].index ('/')+1], file_entries)
767 return map (lambda x: os.path.join (dir, x), files)
769 def flatten (tree, lst):
770 if type (tree) == type ([]):
772 if type (i) == type ([]):
779 and 'all' not in COMMAND_LINE_TARGETS\
780 and 'doc' not in COMMAND_LINE_TARGETS\
781 and 'web' not in COMMAND_LINE_TARGETS\
782 and 'install' not in COMMAND_LINE_TARGETS\
783 and 'clean' not in COMMAND_LINE_TARGETS:
784 subdirs = ['lily', 'lily/include',
785 'flower', 'flower/include',
791 subdirs = flatten (cvs_dirs ('.'), [])
793 src_files = reduce (lambda x, y: x + y, map (cvs_files, subdirs))
794 readme_files = ['AUTHORS', 'README', 'INSTALL', 'NEWS']
795 txt_files = map (lambda x: x + '.txt', readme_files)
799 # speeds up build by +- 5%
802 foo = map (lambda x: env.TXT (x + '.txt',
803 os.path.join ('Documentation/topdocs', x)),
805 tar_base = package.name + '-' + version
806 tar_name = tar_base + '.tar.gz'
807 ball_prefix = os.path.join (outdir, tar_base)
808 tar_ball = os.path.join (outdir, tar_name)
810 dist_files = src_files + txt_files
811 ball_files = map (lambda x: os.path.join (ball_prefix, x), dist_files)
812 map (lambda x: env.Depends (tar_ball, x), ball_files)
813 map (lambda x: env.Command (os.path.join (ball_prefix, x), x,
814 'ln $SOURCE $TARGET'), dist_files)
815 tar = env.Command (tar_ball, src_files,
816 ['rm -f $$(find $TARGET.dir -name .sconsign)',
817 'tar czf $TARGET -C $TARGET.dir %s' % tar_base,])
818 env.Alias ('tar', tar)
820 dist_ball = os.path.join (package.release_dir, tar_name)
821 env.Command (dist_ball, tar_ball,
822 'if [ -e $SOURCE -a -e $TARGET ]; then rm $TARGET; fi;' \
823 + 'ln $SOURCE $TARGET')
824 env.Depends ('dist', dist_ball)
825 patch_name = os.path.join (outdir, tar_base + '.diff.gz')
826 patch = env.PATCH (patch_name, tar_ball)
827 env.Depends (patch_name, dist_ball)
828 env.Alias ('release', patch)
832 web_base = os.path.join (outdir, 'web')
833 web_ball = web_base + '.tar.gz'
834 env['footify'] = 'MAILADDRESS=bug-lilypond@gnu.org $PYTHON stepmake/bin/add-html-footer.py --name=lilypond --version=$TOPLEVEL_VERSION'
835 web_ext = ['.html', '.ly', '.midi', '.pdf', '.png', '.ps.gz', '.txt',]
836 web_path = '-path "*/$out/*"' + string.join (web_ext, ' -or -path "*/$out/*"')
837 env['web_path'] = web_path
838 web_list = os.path.join (outdir, 'weblist')
839 # compatible make heritits
840 # fixme: generate in $outdir is cwd/builddir
841 env.Command (web_list,
842 ## this is correct, but takes > 5min if you have a peder :-)
845 ['$PYTHON buildscripts/mutopia-index.py -o examples.html ./',
846 'cd $absbuild && $footify $$(find . -name "*.html" -print)',
847 'cd $absbuild && rm -f $$(find . -name "*.html~" -print)',
848 'cd $absbuild && find Documentation input $web_path \
850 '''echo '<META HTTP-EQUIV="refresh" content="0;URL=Documentation/out-www/index.html">' > $absbuild/index.html''',
851 '''echo '<html><body>Redirecting to the documentation index...</body></html>' >> $absbuild/index.html''',
852 'cd $absbuild && ls *.html >> $TARGET',])
853 env.Command (web_ball, web_list,
854 ['cat $SOURCE | tar -C $absbuild -czf $TARGET -T -',])
855 #env.Alias ('web', web_ball)
856 www_base = os.path.join (outdir, 'www')
857 www_ball = www_base + '.tar.gz'
858 env.Command (www_ball, web_ball,
860 'mkdir -p $absbuild/$out/tmp',
861 'tar -C $absbuild/$out/tmp -xzf $SOURCE',
862 'cd $absbuild/$out/tmp && for i in $$(find . -name "$out"); '
863 + ' do mv $$i $$(dirname $$i)/out-www; done',
864 'tar -C $absbuild/$out/tmp -czf $TARGET .'])
865 env.Alias ('web', www_ball)
869 ETAGSFLAGS = """--regex='{c++}/^LY_DEFINE *(\([^,]+\)/\\1/' \
870 --regex='{c++}/^LY_DEFINE *([^"]*"\([^"]+\)"/\\1/'""")
871 code_ext = ['.cc', '.hh', '.scm', '.tcc',]
872 env.Command ('TAGS', filter (lambda x: os.path.splitext (x)[1] in code_ext,
874 'etags $ETAGSFLAGS $SOURCES')
876 # Note: SConscripts are only needed in directories where something needs
877 # to be done, building or installing
879 if os.path.exists (os.path.join (d, 'SConscript')):
880 b = os.path.join (env['build'], d, env['out'])
881 # Support clean sourcetree build (--srcdir build)
883 if os.path.abspath (b) != os.path.abspath (d):
884 env.BuildDir (b, d, duplicate = 0)
885 SConscript (os.path.join (b, 'SConscript'))