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/<VERSION>
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
# - too many stages in Environments setup
66
# (see also buildscripts/builders.py)
67
# - Home-brew scons.cach configuration caching
68
# - Home-brew source tarball generating -- [why] isn't that in SCons?
70
# * usability and documentation for "./configure; make" users
72
# * too much cruft in toplevel SConstruct
74
# * (optional) operation without CVS directories, from tarball
76
# * more program configure tests, actually use full executable name
80
# * split doc target: doc input examples mutopia?
82
# * grep FIXME $(find . -name 'S*t')
95
EnsureSConsVersion (0, 95)
98
[ENVVAR=VALUE]... scons [OPTION=VALUE]... [TARGET|DIR]...
100
TARGETS: clean, config, doc, dist, install, mf-essential, po-update,
101
realclean, release, sconsclean, tar, TAGS
103
ENVVARS: BASH, CCFLAGS, CC, CXX, LIBS, PYTHON, SH...
104
(see SConstruct:config_vars)
110
config_cache = 'scons.cache'
111
if os.path.exists (config_cache) and 'config' in COMMAND_LINE_TARGETS:
112
os.unlink (config_cache)
114
# All config_vars can be set as ENVVAR, eg:
116
# CXX=g++-4.0 GS=~/usr/pkg/gs/bin/gs scons config
118
# append test_program variables automagically?
143
# Put your favourite stuff in custom.py
144
opts = Options ([config_cache, 'custom.py'], ARGUMENTS)
145
opts.Add ('prefix', 'Install prefix', '/usr/')
146
opts.Add ('out', 'Output directory', 'out-scons')
147
opts.Add ('build', 'Build directory', '.')
148
opts.Add ('DESTDIR', 'DESTDIR prepended to prefix', '')
150
BoolOption ('warnings', 'compile with -Wall and similiar',
152
BoolOption ('debugging', 'compile with debugging symbols',
154
BoolOption ('optimising', 'compile with optimising',
156
BoolOption ('shared', 'build shared libraries',
158
BoolOption ('static', 'build static libraries',
160
BoolOption ('gui', 'build with GNOME backend (EXPERIMENTAL)',
162
BoolOption ('verbose', 'run commands with verbose flag',
164
BoolOption ('checksums', 'use checksums instead of timestamps',
166
BoolOption ('fast', 'use timestamps, implicit cache, prune CPPPATH',
170
srcdir = Dir ('.').srcnode ().abspath
172
sys.path.append (os.path.join (srcdir, 'stepmake', 'bin'))
174
package = packagepython.Package (srcdir)
175
version = packagepython.version_tuple_to_str (package.version)
177
ENV = { 'PATH' : os.environ['PATH'] }
178
for key in ['LD_LIBRARY_PATH', 'GUILE_LOAD_PATH', 'PKG_CONFIG_PATH', 'TEXMF']:
179
if os.environ.has_key (key):
180
ENV[key] = os.environ[key]
184
BYTEORDER = sys.byteorder.upper (),
187
CPPDEFINES = '-DHAVE_CONFIG_H',
188
MAKEINFO = 'LANG= makeinfo',
189
MF_TO_TABLE_PY = srcdir + '/buildscripts/mf-to-table.py',
191
PKG_CONFIG_PATH = [os.path.join (os.environ['HOME'],
192
'usr/pkg/gnome/lib'),
193
os.path.join (os.environ['HOME'],
194
'usr/pkg/pango/lib')],
197
TOPLEVEL_VERSION = version,
200
Help (usage + opts.GenerateHelpText (env))
202
# Add all config_vars to opts, so that they will be read and saved
203
# together with the other configure options.
204
map (lambda x: opts.AddOptions ((x,)), config_vars)
207
for key in config_vars:
208
if os.environ.has_key (key):
209
env[key] = os.environ[key]
212
# Usability switch (Anthony Roach).
213
# See http://www.scons.org/cgi-bin/wiki/GoFastButton
214
# First do: scons realclean .
216
SetOption ('max_drift', 1)
217
SetOption ('implicit_cache', 1)
218
elif env['checksums']:
219
# Always use checksums (makes more sense than timestamps).
220
SetOption ('max_drift', 0)
221
# Using *content* checksums prevents rebuilds after
222
# [re]configure if config.hh has not changed. Too bad that it
224
TargetSignatures ('content')
226
absbuild = Dir (env['build']).abspath
227
outdir = os.path.join (Dir (env['build']).abspath, env['out'])
228
run_prefix = os.path.join (absbuild, os.path.join (env['out'], 'usr'))
231
config_hh = os.path.join (outdir, 'config.hh')
232
version_hh = os.path.join (outdir, 'version.hh')
234
env.Alias ('config', config_cache)
236
cachedir = os.path.join (outdir, 'build-cache')
238
if not os.path.exists (cachedir):
239
os.makedirs (cachedir)
243
# No need to set $LILYPONDPREFIX to run lily, but cannot install...
244
if env['debugging'] and not 'install' in COMMAND_LINE_TARGETS:
245
env['prefix'] = run_prefix
247
prefix = env['prefix']
248
bindir = os.path.join (prefix, 'bin')
249
sharedir = os.path.join (prefix, 'share')
250
libdir = os.path.join (prefix, 'lib')
251
libdir_package = os.path.join (libdir, package.name)
252
lidbir_package_version = os.path.join (libdir_package, version)
253
localedir = os.path.join (sharedir, 'locale')
254
sharedir_doc_package = os.path.join (sharedir, 'doc', package.name)
255
sharedir_package = os.path.join (sharedir, package.name)
256
sharedir_package_version = os.path.join (sharedir_package, version)
257
lilypondprefix = sharedir_package_version
272
def configure (target, source, env):
273
vre = re.compile ('^.*[^-.0-9]([0-9][0-9]*\.[0-9]([.0-9]*[0-9])*).*$',
275
def get_version (program):
276
command = '(pkg-config --modversion %(program)s || %(program)s --version || %(program)s -V) 2>&1' % vars ()
277
pipe = os.popen (command)
278
output = pipe.read ()
281
v = re.sub (vre, '\\1', output)
284
return string.split (v, '.')
286
def test_version (lst, full_name, minimal, description, package):
287
program = os.path.basename (full_name)
288
sys.stdout.write ('Checking %s version... ' % program)
289
actual = get_version (program)
292
lst.append ((description, package, minimal, program,
295
print string.join (actual, '.')
296
if map (string.atoi, actual) \
297
< map (string.atoi, string.split (minimal, '.')):
298
lst.append ((description, package, minimal, program,
299
string.join (actual, '.')))
303
def test_program (lst, program, minimal, description, package):
304
key = program.upper ()
306
key = re.sub ('\+', 'X', key)
307
key = re.sub ('-', '_', key)
308
sys.stdout.write ('Checking for %s ... ' % program)
309
if env.has_key (key):
311
sys.stdout.write ('(cached) ')
313
f = WhereIs (program)
317
lst.append ((description, package, minimal, program,
321
return test_version (lst, program, minimal, description, package)
323
def test_lib (lst, program, minimal, description, package):
324
# FIXME: test for Debian or RPM (or -foo?) based dists
325
# to guess (or get correct!: apt-cache search?)
327
#if os.system ('pkg-config --atleast-version=0 freetype2'):
329
if test_version (lst, program, minimal, description,
330
'lib%(package)s-dev or %(package)s-devel'
332
env.ParseConfig ('pkg-config --cflags --libs %(program)s'
338
test_program (required, 'bash', '2.0', 'Bash', 'bash')
339
test_program (required, 'gcc', '2.8', 'GNU C compiler', 'gcc')
340
test_program (required, 'g++', '3.0.5', 'GNU C++ compiler', 'g++')
341
test_program (required, 'guile-config', '1.6', 'GUILE development',
342
'libguile-dev or guile-devel')
343
test_program (required, 'mf', '0.0', 'Metafont', 'tetex-bin')
344
test_program (required, 'mftrace', '1.1.9',
345
'mftrace (http://xs4all.nl/~hanwen/mftrace)', 'mftrace')
346
test_program (required, 'potrace', '0.0', 'Potrace', 'potrace')
347
test_program (required, 'python', '2.1', 'Python (www.python.org)',
349
test_program (required, 'sh', '0.0', 'Bourne shell', 'sh')
352
# Do not use bison 1.50 and 1.75.
353
#test_program (optional, 'foo', '2.0', 'Foomatic tester', 'bar')
354
test_program (optional, 'bison', '1.25', 'Bison -- parser generator',
356
test_program (optional, 'dvips', '0.0', 'Dvips', 'tetex-bin')
357
test_program (optional, 'fontforge', '0.0.20041224', 'FontForge',
359
test_program (optional, 'flex', '0.0', 'Flex -- lexer generator',
361
test_program (optional, 'guile', '1.6', 'GUILE scheme', 'guile')
362
test_program (optional, 'gs', '8.14',
363
'Ghostscript PostScript interpreter',
364
'gs or gs-afpl or gs-esp or gs-gpl')
365
test_program (optional, 'mftrace', '1.1.0', 'Metafont tracing Type1',
367
test_program (optional, 'makeinfo', '4.7', 'Makeinfo tool', 'texinfo')
368
test_program (optional, 'perl', '4.0',
369
'Perl practical efficient readonly language', 'perl')
370
#test_program (optional, 'ps2pdf', '0.0', 'Ps2pdf', 'gs')
372
def CheckYYCurrentBuffer (context):
373
context.Message ('Checking for yy_current_buffer... ')
374
ret = conf.TryCompile ("""using namespace std;
375
#include <FlexLexer.h>
376
class yy_flex_lexer: public yyFlexLexer
381
yy_current_buffer = 0;
387
def CheckLibkpathseaSo (context):
389
if context.env.has_key ('CFLAGS'):
390
saveCFLAGS = context.env['CFLAGS']
391
CFLAGS_shared_no_debugging = filter (lambda x: x != '-g',
394
# FIXME: how does this work, with scons
395
context.env.Replace (CFLAGS = CFLAGS_shared_no_debugging)
396
#context.env.Replace (CFLAGS = '')
397
#context.env.Append (CFLAGS = ['-shared'])
398
context.Message ('Checking for libkpathsea... ')
399
ret = conf.TryLink ('''#include <kpathsea/kpathsea.h>
402
kpse_var_expand ("\$TEXMF");
406
context.env.Replace (CFLAGS = saveCFLAGS)
407
# FIXME: this prints 'ok' already
412
sys.stdout.write ('Checking for libkpathsea.so... ')
413
testfile = str (context.sconf.lastTarget)
414
shared_size = os.path.getsize (testfile)
415
ret = shared_size < 40000
422
conf = Configure (env, custom_tests = { 'CheckYYCurrentBuffer'
423
: CheckYYCurrentBuffer,
425
: CheckLibkpathseaSo })
428
'DIRSEP' : "'%s'" % os.sep,
429
'PATHSEP' : "'%s'" % os.pathsep,
430
'PACKAGE': '"%s"' % package.name,
431
'DATADIR' : '"%s"' % sharedir,
432
'PACKAGE_DATADIR' : '"%s"' % sharedir_package,
433
'LOCALEDIR' : '"%s"' %localedir,
435
conf.env.Append (DEFINES = defines)
437
command = r"""python -c 'import sys; sys.stdout.write ("%s/include/python%s" % (sys.prefix, sys.version[:3]))'""" #"
438
PYTHON_INCLUDE = os.popen (command).read ()#[:-1]
440
env.Append (CCFLAGS = ['-I%s' % PYTHON_INCLUDE])
442
env.Append (CPPPATH = [PYTHON_INCLUDE])
444
headers = ('sys/stat.h', 'assert.h', 'kpathsea/kpathsea.h', 'libio.h',
447
if conf.CheckCHeader (i):
448
key = re.sub ('[./]', '_', 'HAVE_' + string.upper (i))
449
conf.env['DEFINES'][key] = 1
451
ccheaders = ('sstream',)
453
if conf.CheckCXXHeader (i):
454
key = re.sub ('[./]', '_', 'HAVE_' + string.upper (i))
455
conf.env['DEFINES'][key] = 1
457
functions = ('fopencookie', 'funopen',
458
'gettext', 'isinf', 'memmem', 'snprintf', 'vsnprintf')
460
if 0 or conf.CheckFunc (i):
461
key = re.sub ('[./]', '_', 'HAVE_' + string.upper (i))
462
conf.env['DEFINES'][key] = 1
464
if conf.CheckYYCurrentBuffer ():
465
conf.env['DEFINES']['HAVE_FLEXLEXER_YY_CURRENT_BUFFER'] = 1
467
if conf.CheckLibkpathseaSo ():
468
conf.env['DEFINES']['HAVE_LIBKPATHSEA_SO'] = '1'
470
if conf.CheckLib ('dl'):
473
if conf.CheckLib ('kpathsea'):
474
conf.env['DEFINES']['KPATHSEA'] = 1
477
if conf.CheckLib ('kpathsea', 'kpse_find_file'):
478
conf.env['DEFINES']['HAVE_KPSE_FIND_FILE'] = '1'
479
if conf.CheckLib ('kpathsea', 'kpse_find_tfm'):
480
conf.env['DEFINES']['HAVE_KPSE_FIND_TFM'] = '1'
484
if env.has_key ('CPPPATH'):
485
cpppath = env['CPPPATH']
487
## FIXME: linkage, check for libguile.h and scm_boot_guile
488
#this could happen after flower...
489
env.ParseConfig ('guile-config compile')
491
test_program (required, 'pkg-config', '0.9.0',
492
'pkg-config library compile manager', 'pkg-config')
493
if test_lib (required, 'freetype2', '0.0',
494
'Development files for FreeType 2 font engine',
496
conf.env['DEFINES']['HAVE_FREETYPE2'] = '1'
498
if test_lib (required, 'pangoft2', '1.6.0',
499
'Development files for pango, with FreeType2',
501
conf.env['DEFINES']['HAVE_PANGO_FT2'] = '1'
502
conf.env['DEFINES']['HAVE_PANGO16'] = '1'
504
if test_lib (optional, 'fontconfig', '2.2.0',
505
'Development files for fontconfig', 'fontconfig1'):
506
conf.env['DEFINES']['HAVE_FONTCONFIG'] = '1'
508
#this could happen only for compiling pango-*
510
test_lib (required, 'gtk+-2.0', '2.4.0',
511
'Development files for GTK+', 'gtk2.0')
512
if test_lib (required, 'pango', '1.6.0',
513
'Development files for pango', 'pango1.0'):
514
conf.env['DEFINES']['HAVE_PANGO16'] = '1'
516
if conf.CheckCHeader ('pango/pangofc-fontmap.h'):
517
conf.env['DEFINES']['HAVE_PANGO_PANGOFC_FONTMAP_H'] = '1'
519
# Using CCFLAGS = -I<system-dir> rather than CPPPATH = [
520
# <system-dir>] speeds up SCons
521
env['CCFLAGS'] += map (lambda x: '-I' + x,
522
env['CPPPATH'][len (cpppath):])
523
env['CPPPATH'] = cpppath
527
print '********************************'
528
print 'Please install required packages'
530
print '%s: %s-%s or newer (found: %s %s)' % i
535
print '*************************************'
536
print 'Consider installing optional packages'
538
print '%s: %s-%s or newer (found: %s %s)' % i
540
return conf.Finish ()
542
def config_header (target, source, env):
543
config = open (str (target[0]), 'w')
544
for i in list_sort (env['DEFINES'].keys ()):
545
config.write ('#define %s %s\n' % (i, env['DEFINES'][i]))
547
env.Command (config_hh, config_cache, config_header)
563
if not d.has_key (lst[i]):
571
def uniquify_config_vars (env):
572
for i in config_vars:
573
if env.has_key (i) and type (env[i]) == type ([]):
574
env[i] = uniquify (env[i])
576
def save_config_cache (env):
577
## FIXME: Is this smart, using option cache for saving
578
## config.cache? I cannot seem to find the official method.
579
uniquify_config_vars (env)
580
opts.Save (config_cache, env)
582
if 'config' in COMMAND_LINE_TARGETS:
583
sys.stdout.write ('\n')
584
sys.stdout.write ('LilyPond configured')
585
sys.stdout.write ('\n')
586
sys.stdout.write ('Now run')
587
sys.stdout.write ('\n')
588
sys.stdout.write (' scons [TARGET|DIR]...')
589
sys.stdout.write ('\n')
590
sys.stdout.write ('\n')
591
sys.stdout.write ('Examples:')
592
sys.stdout.write ('\n')
593
sys.stdout.write (' scons lily # build lilypond')
594
sys.stdout.write ('\n')
595
sys.stdout.write (' scons all # build everything')
596
sys.stdout.write ('\n')
597
sys.stdout.write (' scons doc # build documentation')
598
sys.stdout.write ('\n')
600
## sys.stdout.write (' scons prefix=/usr DESTDIR=/tmp/pkg all install')
601
## sys.stdout.write ('\n')
603
elif not env['checksums']:
604
# When using timestams, config.hh is NEW. The next
605
# build triggers recompilation of everything. Exiting
606
# here makes SCons use the actual timestamp for config.hh
607
# and prevents recompiling everything the next run.
608
command = sys.argv[0] + ' ' + string.join (COMMAND_LINE_TARGETS)
609
sys.stdout.write ('Running %s ... ' % command)
610
sys.stdout.write ('\n')
611
s = os.system (command)
615
# scons: *** Calling Configure from Builders is not supported.
616
# env.Command (config_cache, None, configure)
617
if not os.path.exists (config_cache) \
618
or (os.stat ('SConstruct')[stat.ST_MTIME]
619
> os.stat (config_cache)[stat.ST_MTIME]):
620
env = configure (None, None, env)
621
save_config_cache (env)
622
elif env['checksums']:
623
# just save everything
624
save_config_cache (env)
626
#urg how does #/ subst work?
628
SConscript ('buildscripts/builder.py')
630
env.PrependENVPath ('PATH',
631
os.path.join (env['absbuild'], env['out'], 'usr/bin'))
633
LILYPONDPREFIX = os.path.join (run_prefix, 'share/lilypond/', version)
636
#'LILYPONDPREFIX' : os.path.join (run_prefix, 'share/lilypond/', version),
637
'LILYPONDPREFIX' : LILYPONDPREFIX,
638
# ugh, can't use LILYPONDPREFIX here
639
#'TEXMF' : '{' + os.path.join (run_prefix, 'share/lilypond/', version)\
641
'TEXMF' : '{$LILYPONDPREFIX,'
642
+ os.popen ('kpsexpand \$TEXMF').read ()[:-1] + '}',
645
BUILD_ABC2LY = '${set__x}$PYTHON $srcdir/scripts/abc2ly.py'
646
BUILD_LILYPOND = '$absbuild/lily/$out/lilypond ${__verbose}'
647
BUILD_LILYPOND_BOOK = '$PYTHON $srcdir/scripts/lilypond-book.py ${__verbose}'
650
# post-option environment-update
654
lilypond_datadir = sharedir_package,
655
localedir = localedir,
656
local_lilypond_datadir = sharedir_package_version,
657
lilypondprefix = lilypondprefix,
658
sharedir_package = sharedir_package,
659
sharedir_doc_package = sharedir_doc_package,
660
sharedir_package_version = sharedir_package_version,
662
# global build verbosity switch
663
__verbose = ' --verbose',
665
LILYPOND = BUILD_LILYPOND,
666
ABC2LY = BUILD_ABC2LY,
667
LILYPOND_BOOK = BUILD_LILYPOND_BOOK,
668
LILYPOND_BOOK_FORMAT = 'texi-html',
669
MAKEINFO_FLAGS = '--css-include=$srcdir/Documentation/texinfo.css',
670
# should not be necessary
671
# PYTHONPATH = ['$absbuild/python/$out'],
672
TEXI2DVI_PAPERSIZE = '@afourpaper',
673
TEXI2DVI_FLAGS = [ '-t$TEXI2DVI_PAPERSIZE'],
674
DVIPS_PAPERSIZE = 'a4',
675
DVIPS_FLAGS = ['-t$DVIPS_PAPERSIZE',
677
'-u+ec-mftrace.map'],
678
PSPDF_FLAGS = ['-sPAPERSIZE=$DVIPS_PAPERSIZE'],
681
env.Append (CCFLAGS = ['-pipe', '-Wno-pmf-conversions'])
683
env.Append (CCFLAGS = ['-g'])
684
if env['optimising']:
685
env.Append (CCFLAGS = '-O2')
686
env.Append (CXXFLAGS = ['-DSTRING_UTILS_INLINED'])
688
env.Append (CCFLAGS = ['-W', '-Wall'])
689
env.Append (CXXFLAGS = ['-Wconversion'])
692
env.Append (LINKFLAGS = ['-Wl,--export-dynamic'])
693
# FIXME: ParseConfig ignores -L flag?
694
env.Append (LINKFLAGS = ['-L/usr/X11R6/lib'])
697
env['__verbose'] = ' --verbose'
698
env['set__x'] = 'set -x;'
701
## Explicit target and dependencies
703
if 'clean' in COMMAND_LINE_TARGETS:
704
# ugh: prevent reconfigure instead of clean
705
os.system ('touch %s' % config_cache)
707
command = sys.argv[0] + ' -c .'
708
sys.stdout.write ('Running %s ... ' % command)
709
sys.stdout.write ('\n')
710
s = os.system (command)
711
if os.path.exists (config_cache):
712
os.unlink (config_cache)
715
if 'sconsclean' in COMMAND_LINE_TARGETS:
716
command = 'rm -rf scons.cache $(find . -name ".scon*")'
717
s = os.system (command)
718
if os.path.exists (config_cache):
719
os.unlink (config_cache)
722
if 'realclean' in COMMAND_LINE_TARGETS:
723
command = 'rm -rf $(find . -name "out-scons" -o -name ".scon*")'
724
sys.stdout.write ('Running %s ... ' % command)
725
sys.stdout.write ('\n')
726
s = os.system (command)
727
if os.path.exists (config_cache):
728
os.unlink (config_cache)
731
# Declare SConscript phonies
732
env.Alias ('minimal', config_cache)
733
env.Alias ('mf-essential', config_cache)
735
env.Alias ('minimal', ['lily', 'mf-essential'])
736
env.Alias ('all', ['minimal', 'mf', '.'])
737
# Do we want the doc/web separation?
740
'Documentation/user',
741
'Documentation/topdocs',
742
'Documentation/bibliography',
745
# Without target arguments, do minimal build
746
if not COMMAND_LINE_TARGETS:
747
env.Default (['minimal'])
749
# GNU Make rerouting compat:
750
env.Alias ('web', 'doc')
753
env.Command (version_hh, '#/VERSION',
754
'$PYTHON ./stepmake/bin/make-version.py VERSION > $TARGET')
756
# post-config environment update
758
run_prefix = run_prefix,
759
LILYPONDPREFIX = LILYPONDPREFIX,
761
# FIXME: move to lily/SConscript?
762
LIBPATH = [os.path.join (absbuild, 'flower', env['out']),
763
os.path.join (absbuild, 'kpath-guile', env['out']),],
764
CPPPATH = [outdir, ],
765
LILYPOND_PATH = ['.',
767
'$srcdir/input/regression',
768
'$srcdir/input/test',
769
'$srcdir/input/tutorial',
770
'$srcdir/Documentation/user',
772
# os.path.join (absbuild, 'Documentation',
774
# os.path.join (absbuild, 'Documentation/user',
777
MAKEINFO_PATH = ['.', '$srcdir/Documentation/user',
778
'$absbuild/Documentation/user/$out'],
781
def symlink_tree (target, source, env):
787
if not os.path.isdir (dir):
788
if os.path.exists (dir):
792
map (mkdir, string.split (dir, os.sep))
793
def symlink (src, dst):
795
dir = os.path.dirname (dst)
798
frm = os.path.join (srcdir, src[1:])
800
depth = len (string.split (dir, '/'))
801
if src.find ('@') > -1:
802
frm = os.path.join ('../' * depth,
803
string.replace (src, '@',
806
frm = os.path.join ('../' * depth, src,
809
frm = os.path.join (frm, os.path.basename (dst))
811
print 'ln -s %s -> %s' % (frm, os.path.basename (dst))
812
os.symlink (frm, os.path.basename (dst))
813
shutil.rmtree (run_prefix)
814
prefix = os.path.join (env['out'], 'usr')
815
map (lambda x: symlink (x[0], os.path.join (prefix,
816
x[1] % {'ver' : version})),
819
# /$ := add dst file_name
820
(('python', 'lib/lilypond/python'),
822
('python', 'share/lilypond/%(ver)s/python'),
823
('lily/', 'bin/lilypond'),
824
('scripts/', 'bin/convert-ly'),
825
('scripts/', 'bin/lilypond-book'),
826
('scripts/', 'bin/ps2png'),
827
('mf', 'share/lilypond/%(ver)s/dvips/mf-out'),
828
('#ps', 'share/lilypond/%(ver)s/dvips/ps'),
829
('#ps', 'share/lilypond/%(ver)s/tex/music-drawing-routines.ps'),
830
('mf', 'share/lilypond/%(ver)s/otf'),
831
('mf', 'share/lilypond/%(ver)s/tfm'),
832
('tex', 'share/lilypond/%(ver)s/tex/enc'),
833
('#mf', 'share/lilypond/%(ver)s/fonts/mf'),
834
('mf', 'share/lilypond/%(ver)s/fonts/map'),
835
('mf', 'share/lilypond/%(ver)s/fonts/otf'),
836
('mf', 'share/lilypond/%(ver)s/fonts/tfm'),
837
('mf', 'share/lilypond/%(ver)s/fonts/type1'),
838
('#tex', 'share/lilypond/%(ver)s/tex/source'),
839
('tex', 'share/lilypond/%(ver)s/tex/tex-out'),
840
('mf', 'share/lilypond/%(ver)s/tex/mf-out'),
841
('#ly', 'share/lilypond/%(ver)s/ly'),
842
('#scm', 'share/lilypond/%(ver)s/scm'),
843
('#scripts', 'share/lilypond/%(ver)s/scripts'),
844
('#ps', 'share/lilypond/%(ver)s/ps'),
845
('po/@/nl.mo', 'share/locale/nl/LC_MESSAGES/lilypond.mo'),
846
('elisp', 'share/lilypond/%(ver)s/elisp')))
848
print "FIXME: BARF BARF BARF"
852
prefix = os.path.join (env['out'], 'usr/share/lilypond/%(ver)s/fonts'
854
for ext in ('enc', 'map', 'otf', 'svg', 'tfm', 'pfa'):
855
dir = os.path.join (absbuild, prefix, ext)
856
os.system ('rm -f ' + dir)
859
os.system ('ln -s ../../../../../../../mf/%(out)s/*.%(ext)s .'
863
if 1: #env['debugging']:
864
stamp = os.path.join (run_prefix, 'stamp')
865
env.Command (stamp, ['#/SConstruct', '#/VERSION'],
866
[symlink_tree, 'touch $TARGET'])
867
env.Depends ('lily', stamp)
873
def cvs_entry_is_dir (line):
874
return line[0] == 'D' and line[-2] == '/'
876
def cvs_entry_is_file (line):
877
return line[0] == '/' and line[-2] == '/'
880
entries = os.path.join (dir, 'CVS/Entries')
881
if not os.path.exists (entries):
883
entries = open (entries).readlines ()
884
dir_entries = filter (cvs_entry_is_dir, entries)
885
dirs = map (lambda x: os.path.join (dir, x[2:x[2:].index ('/')+3]),
887
return dirs + map (cvs_dirs, dirs)
890
entries = os.path.join (dir, 'CVS/Entries')
891
if not os.path.exists (entries):
893
entries = open (entries).readlines ()
894
file_entries = filter (cvs_entry_is_file, entries)
895
files = map (lambda x: x[1:x[1:].index ('/')+1], file_entries)
896
return map (lambda x: os.path.join (dir, x), files)
898
def flatten (tree, lst):
899
if type (tree) == type ([]):
901
if type (i) == type ([]):
907
if os.path.isdir ('%(srcdir)s/CVS' % vars ()):
908
subdirs = flatten (cvs_dirs ('.'), [])
911
command = 'cd %(srcdir)s \
912
&& find . -name SConscript | sed s@/SConscript@@' % vars ()
913
subdirs = string.split (os.popen (command).read ())
916
and 'all' not in COMMAND_LINE_TARGETS\
917
and 'doc' not in COMMAND_LINE_TARGETS\
918
and 'web' not in COMMAND_LINE_TARGETS\
919
and 'install' not in COMMAND_LINE_TARGETS\
920
and 'clean' not in COMMAND_LINE_TARGETS:
928
if os.path.isdir ('%(srcdir)s/CVS' % vars ()):
929
src_files = reduce (lambda x, y: x + y, map (cvs_files, subdirs))
931
src_files = ['foobar']
933
readme_files = ['AUTHORS', 'README', 'INSTALL', 'NEWS']
934
txt_files = map (lambda x: x + '.txt', readme_files)
938
# speeds up build by +- 5%
941
foo = map (lambda x: env.TXT (x + '.txt',
942
os.path.join ('Documentation/topdocs', x)),
944
tar_base = package.name + '-' + version
945
tar_name = tar_base + '.tar.gz'
946
ball_prefix = os.path.join (outdir, tar_base)
947
tar_ball = os.path.join (outdir, tar_name)
949
dist_files = src_files + txt_files
950
ball_files = map (lambda x: os.path.join (ball_prefix, x), dist_files)
951
map (lambda x: env.Depends (tar_ball, x), ball_files)
952
map (lambda x: env.Command (os.path.join (ball_prefix, x), x,
953
'ln $SOURCE $TARGET'), dist_files)
954
tar = env.Command (tar_ball, src_files,
955
['rm -f $$(find $TARGET.dir -name .sconsign)',
956
'tar czf $TARGET -C $TARGET.dir %s' % tar_base,])
957
env.Alias ('tar', tar)
959
dist_ball = os.path.join (package.release_dir, tar_name)
960
env.Command (dist_ball, tar_ball,
961
'if [ -e $SOURCE -a -e $TARGET ]; then rm $TARGET; fi;' \
962
+ 'ln $SOURCE $TARGET')
963
env.Depends ('dist', dist_ball)
964
patch_name = os.path.join (outdir, tar_base + '.diff.gz')
965
patch = env.PATCH (patch_name, tar_ball)
966
env.Depends (patch_name, dist_ball)
967
env.Alias ('release', patch)
971
web_base = os.path.join (outdir, 'web')
972
web_ball = web_base + '.tar.gz'
973
env['footify'] = 'MAILADDRESS=bug-lilypond@gnu.org $PYTHON stepmake/bin/add-html-footer.py --name=lilypond --version=$TOPLEVEL_VERSION'
974
web_ext = ['.html', '.ly', '.midi', '.pdf', '.png', '.ps.gz', '.txt',]
975
web_path = '-path "*/$out/*"' + string.join (web_ext, ' -or -path "*/$out/*"') + '-or -type l'
976
env['web_path'] = web_path
977
web_list = os.path.join (outdir, 'weblist')
978
# compatible make heritits
979
# fixme: generate in $outdir is cwd/builddir
980
env.Command (web_list,
981
## Adding 'doc' dependency is correct, but takes
982
## > 5min extra if you have a peder :-)
986
['$PYTHON buildscripts/mutopia-index.py -o examples.html ./',
987
'cd $absbuild && $footify $$(find . -name "*.html" -print)',
988
'cd $absbuild && rm -f $$(find . -name "*.html~" -print)',
989
'cd $absbuild && find Documentation input $web_path \
991
'''echo '<META HTTP-EQUIV="refresh" content="0;URL=Documentation/out-www/index.html">' > $absbuild/index.html''',
992
'''echo '<html><body>Redirecting to the documentation index...</body></html>' >> $absbuild/index.html''',
993
'cd $absbuild && ls *.html >> $TARGET',])
994
env.Command (web_ball, web_list,
995
['cat $SOURCE | tar -C $absbuild -czf $TARGET -T -',])
996
#env.Alias ('web', web_ball)
997
www_base = os.path.join (outdir, 'www')
998
www_ball = www_base + '.tar.gz'
999
env.Command (www_ball, web_ball,
1001
'mkdir -p $absbuild/$out/tmp',
1002
'tar -C $absbuild/$out/tmp -xzf $SOURCE',
1003
'cd $absbuild/$out/tmp && for i in $$(find . -name "$out"); '
1004
+ ' do mv $$i $$(dirname $$i)/out-www; done',
1005
'tar -C $absbuild/$out/tmp -czf $TARGET .'])
1006
env.Alias ('web', www_ball)
1010
ETAGSFLAGS = """--regex='{c++}/^LY_DEFINE *(\([^,]+\)/\\1/' \
1011
--regex='{c++}/^LY_DEFINE *([^"]*"\([^"]+\)"/\\1/'""")
1012
code_ext = ['.cc', '.hh', '.scm', '.tcc',]
1013
env.Command ('TAGS', filter (lambda x: os.path.splitext (x)[1] in code_ext,
1015
'etags $ETAGSFLAGS $SOURCES')
1017
# Note: SConscripts are only needed in directories where something needs
1018
# to be done, building or installing
1020
if os.path.exists (os.path.join (d, 'SConscript')):
1021
b = os.path.join (env['build'], d, env['out'])
1022
# Support clean sourcetree build (--srcdir build)
1024
if os.path.abspath (b) != os.path.abspath (d):
1025
env.BuildDir (b, d, duplicate = 0)
1026
SConscript (os.path.join (b, 'SConscript'))