4 Experimental scons (www.scons.org) building:
8 scons lily # build lily
10 LILYPONDPREFIX=out-scons/usr/share/lilypond lily/out-scons/lilypond-bin
11 scons doc # build web doc
13 scons fonts # build all font stuff (split this? )
15 scons config # reconfigure
17 scons / # builds all possible targets
23 scons build=DIR # scrdir build, write to new tree =build
24 scons out=DIR # write output to deeper dir DIR
26 Optionally, make a custom.py. I have
33 os.path.join (os.getcwd (), '=install')
34 prefix=os.path.join (os.environ['HOME'], 'usr', 'pkg', 'lilypond')
43 # * separate environments?
44 # - compile environment checks headers and libraries
45 # - doc environment checks doc stuff
47 # * commandline targets:
49 # * more fine-grained config.h -- move lilypondprefix to version.hh?
50 # - config.h: changes after system upgrades, affects all files
51 # - version.hh: prefix, version etc? affects few
59 subdirs = ['flower', 'lily', 'mf', 'scm', 'ly', 'Documentation',
60 'Documentation/user', 'input']
63 scons [KEY=VALUE].. [TARGET]..
65 where TARGET is config|lily|all|fonts|doc|tar|dist|release
70 # Without target arguments, build lily only
71 if not COMMAND_LINE_TARGETS:
74 # All builds everything (all directories)
75 env.Alias ('all', ['lily', 'mf', 'input', 'Documentation'])
78 env.Depends ('Documentation', ['lily', 'mf'])
79 env.Depends ('input', ['lily', 'mf'])
80 env.Depends ('doc', ['lily', 'mf'])
81 env.Depends ('doc', 'mf')
82 env.Depends ('input', ['lily', 'mf'])
85 ## FIXME: opts in function
87 # Put your favourite stuff in custom.py
88 opts = Options (['config.cache', 'custom.py'], ARGUMENTS)
89 opts.Add ('prefix', 'Install prefix', '/usr/')
90 opts.Add ('out', 'Output directory', 'out-scons')
91 opts.Add ('build', 'Build directory', '.')
93 BoolOption ('warnings', 'compile with -Wall and similiar',
95 BoolOption ('debugging', 'compile with debugging symbols',
97 BoolOption ('optimising', 'compile with optimising',
99 BoolOption ('shared', 'build shared libraries',
101 BoolOption ('static', 'build static libraries',
103 BoolOption ('gui', 'build with GNOME backend (EXPERIMENTAL)',
105 BoolOption ('verbose', 'run commands with verbose flag',
109 Help (usage + opts.GenerateHelpText (env))
111 env = Environment (options = opts)
114 opts.Save ('config.cache', env)
116 env.CacheDir (os.path.join (env['build'], '=build-cache'))
119 sys.path.append (os.path.join ('.', 'stepmake', 'bin'))
121 package = packagepython.Package ('.')
123 env['version'] = packagepython.version_tuple_to_str (package.version)
124 env['bindir'] = os.path.join (env['prefix'], 'bin')
125 env['sharedir'] = os.path.join (env['prefix'], 'share')
126 env['libdir'] = os.path.join (env['prefix'], 'lib')
127 env['localedir'] = os.path.join (env['sharedir'], 'locale')
129 env['sharedir_package'] = os.path.join (env['sharedir'], package.name)
130 env['sharedir_package_version'] = os.path.join (env['sharedir_package'],
132 env['lilypondprefix'] = os.path.join (env['sharedir_package_version'])
136 env.Append (CFLAGS = '-g')
137 env.Append (CXXFLAGS = '-g')
138 if env['optimising']:
139 env.Append (CFLAGS = '-O2')
140 env.Append (CXXFLAGS = '-O2')
141 env.Append (CXXFLAGS = '-DSTRING_UTILS_INLINED')
143 env.Append (CFLAGS = '-W ')
144 env.Append (CFLAGS = '-Wall')
145 # what about = ['-W', '-Wall', ...]?
146 env.Append (CXXFLAGS = '-W')
147 env.Append (CXXFLAGS = '-Wall')
148 env.Append (CXXFLAGS = '-Wconversion')
154 reldir = str (Dir ('.').srcnode ())
156 srcdir = os.getcwd ()
158 ##outdir = os.path.join (env['build'], reldir, env['out'])
159 outdir = os.path.join (env['build'], env['out'])
161 env['srcdir'] = srcdir
171 env['MFMODE'] = 'ljfour'
172 config_h = os.path.join (outdir, 'config.h')
173 env.Alias ('config', config_h)
176 conf = Configure (env)
178 vre = re.compile ('^.*[^-.0-9]([0-9][0-9]*\.[0-9][.0-9]*).*$', re.DOTALL)
179 def get_version (program):
180 command = '(%(program)s --version || %(program)s -V) 2>&1' % vars ()
181 pipe = os.popen (command)
182 output = pipe.read ()
185 v = re.sub (vre, '\\1', output)
186 return string.split (v, '.')
188 def assert_version (lst, program, minimal, description, package):
190 sys.stdout.write ('Checking %s version... ' % program)
191 actual = get_version (program)
194 lst.append ((description, package, minimal, program,
197 sys.stdout.write (string.join (actual, '.'))
198 sys.stdout.write ('\n')
199 if actual < string.split (minimal, '.'):
200 lst.append ((description, package, minimal, program,
201 string.join (actual, '.')))
204 assert_version (required, 'gcc', '2.8', 'GNU C compiler', 'gcc')
205 assert_version (required, 'g++', '3.0.5', 'GNU C++ compiler', 'g++')
206 assert_version (required, 'python', '2.1', 'Python (www.python.org)', 'python')
207 assert_version (required, 'guile-config', '1.6', 'GUILE development',
208 'libguile-dev or guile-devel')
209 # Do not use bison 1.50 and 1.75.
210 assert_version (required, 'bison', '1.25', 'Bison -- parser generator',
212 assert_version (required, 'flex', '0.0', 'Flex -- lexer generator', 'flex')
216 assert_version (optional, 'makeinfo', '4.7', 'Makeinfo tool', 'texinfo')
217 assert_version (optional, 'guile', '1.6', 'GUILE scheme',
218 'libguile-dev or guile-devel')
219 assert_version (optional, 'mftrace', '1.0.27', 'Metafont tracing Type1',
221 assert_version (optional, 'perl', '4.0',
222 'Perl practical efficient readonly language', 'perl')
223 #assert_version (optional, 'foo', '2.0', 'Foomatic tester', 'bar')
229 'TOPLEVEL_VERSION' : '"' + env['version'] + '"',
230 'PACKAGE': '"' + package.name + '"',
231 'DATADIR' : '"' + env['sharedir'] + '"',
232 'LILYPOND_DATADIR' : '"' + env['sharedir_package'] + '"',
233 'LOCAL_LILYPOND_DATADIR' : '"' + env['sharedir_package_version'] + '"',
234 'LOCALEDIR' : '"' + env['localedir'] + '"',
238 command = r"""python -c 'import sys; sys.stdout.write ("%s/include/python%s" % (sys.prefix, sys.version[:3]))'""" #"
239 PYTHON_INCLUDE = os.popen (command).read ()
240 env.Append (CPPPATH = PYTHON_INCLUDE)
242 headers = ('sys/stat.h', 'assert.h', 'kpathsea/kpathsea.h', 'Python.h')
244 if conf.CheckCHeader (i):
245 key = re.sub ('[./]', '_', 'HAVE_' + string.upper (i))
248 ccheaders = ('sstream',)
250 if conf.CheckCXXHeader (i):
251 key = re.sub ('[./]', '_', 'HAVE_' + string.upper (i))
254 functions = ('gettext', 'isinf', 'memmem', 'snprintf', 'vsnprintf')
256 if 0 or conf.CheckFunc (i):
257 key = re.sub ('[./]', '_', 'HAVE_' + string.upper (i))
260 key = 'HAVE_FLEXLEXER_YY_CURRENT_BUFFER'
262 sys.stdout.write('Checking for yy_current_buffer ... ')
264 res = conf.TryCompile ("""using namespace std;
265 #include <FlexLexer.h>
266 class yy_flex_lexer: public yyFlexLexer
271 yy_current_buffer = 0;
276 sys.stdout.write('yes\n')
278 sys.stdout.write('no\n')
281 if conf.CheckLib ('dl'):
284 if conf.CheckLib ('kpathsea'):
285 defines['KPATHSEA'] = '1'
288 if conf.CheckLib ('kpathsea', 'kpse_find_file'):
289 defines['HAVE_KPSE_FIND_FILE'] = '1'
290 if conf.CheckLib ('kpathsea', 'kpse_find_tfm'):
291 defines['HAVE_KPSE_FIND_TFM'] = '1'
293 #this could happen after flower...
294 env.ParseConfig ('guile-config compile')
296 #this could happen only for compiling pango-*
298 env.ParseConfig ('pkg-config --cflags --libs gtk+-2.0')
299 env.ParseConfig ('pkg-config --cflags --libs pango')
300 if conf.CheckCHeader ('pango/pangofc-fontmap.h'):
301 defines['HAVE_PANGO_PANGOFC_FONTMAP_H'] = '1'
303 if conf.CheckLib ('pango-1.0',
304 'pango_fc_font_map_add_decoder_find_func'):
305 defines['HAVE_PANGO_CVS'] = '1'
306 defines['HAVE_PANGO_FC_FONT_MAP_ADD_DECODER_FIND_FUNC'] = '1'
309 if not os.path.exists (outdir):
312 config = open (config_h, 'w')
313 for i in list_sort (defines.keys ()):
314 config.write ('#define %s %s\n' % (i, defines[i]))
317 os.system (sys.executable \
318 + ' ./stepmake/bin/make-version.py VERSION > '\
319 + os.path.join (outdir, 'version.hh'))
323 print '********************************'
324 print 'Please install required packages'
326 print '%s: %s-%s or newer (found: %s %s)' % i
331 print '*************************************'
332 print 'Consider installing optional packages'
334 print '%s: %s-%s or newer (found: %s %s)' % i
336 return conf.Finish ()
338 # Hmm. Must configure when building lily, to get compiler and linker
341 if 1 or not os.path.exists (config_h) or 'config' in COMMAND_LINE_TARGETS:
342 env = configure (env)
344 env.Append (LIBPATH = ['#/flower/' + out,], CPPPATH = [outdir, '#',])
350 absbuild = os.getcwd ()
353 env['absbuild'] = absbuild
356 env['MAKEINFO'] = 'LANG= makeinfo'
357 env['PYTHON'] = 'python'
358 env['LILYPOND_BIN'] = os.path.join (absbuild, 'lily', out, 'lilypond-bin')
359 env['LILYPONDPREFIX'] = os.path.join (outdir, 'usr/share/lilypond')
360 env['LILYPOND_BOOK'] = srcdir + '/scripts/lilypond-book.py'
361 env['ABC2LY_PY'] = srcdir + '/scripts/abc2ly.py'
362 env['MF_TO_TABLE_PY'] = srcdir + '/buildscripts/mf-to-table.py'
363 env['LILYPOND_PY'] = srcdir + '/scripts/lilypond.py'
364 env['LILYPOND_BOOK_FLAGS'] = ''
365 env['LILYPOND_BOOK_FORMAT'] = 'texi-html'
367 env['LILYPOND_BOOK_PATH'] = ['.', '#/input', '#/input/regression',
368 '#/input/test', '#/input/tutorial',
369 os.path.join (absbuild, 'mf', out),
370 '#/Documentation/user',
371 os.path.join (absbuild, 'Documentation', out),
372 os.path.join (absbuild, 'Documentation/user', out),
375 env['MAKEINFO_PATH'] = ['.', '#/Documentation/user',
376 os.path.join (absbuild, 'Documentation/user', out)]
378 ## TEXINFO_PAPERSIZE_OPTION= $(if $(findstring $(PAPERSIZE),a4),,-t @afourpaper)
379 env['TEXINFO_PAPERSIZE_OPTION'] = '-t @afourpaper'
381 SConscript ('buildscripts/builder.py')
384 b = os.path.join (build, d, out)
385 # Support clean sourcetree build (--srcdir build)
387 if (build and build != '.') \
388 or (out and out != '.'):
389 env.BuildDir (b, d, duplicate=0)
390 SConscript (os.path.join (b, 'SConscript'))
393 def symlink_tree (prefix):
399 if not os.path.isdir (dir):
400 if os.path.exists (dir):
404 map (mkdir, string.split (dir, os.sep))
405 def symlink (src, dst):
407 dir = os.path.dirname (dst)
410 frm = os.path.join (srcdir, src[1:])
412 depth = len (string.split (dir, '/'))
413 frm = os.path.join ('../' * depth, src, out)
414 os.symlink (frm, os.path.basename (dst))
415 map (lambda x: symlink (x[0], os.path.join (prefix, x[1])),
416 (('python', 'lib/lilypond/python'),
417 # UGHR, lilypond.py uses lilypond-bin from PATH
419 ('#mf', 'share/lilypond/fonts/mf'),
420 ('mf', 'share/lilypond/fonts/afm'),
421 ('mf', 'share/lilypond/fonts/tfm'),
422 ('mf', 'share/lilypond/fonts/type1'),
423 ('#tex', 'share/lilypond/tex/source'),
424 ('mf', 'share/lilypond/tex/generate'),
425 ('#ly', 'share/lilypond/ly'),
426 ('#scm', 'share/lilypond/scm'),
427 ('#ps', 'share/lilypond/ps'),
428 ('elisp', 'share/lilypond/elisp')))
432 prefix = os.path.join (out, 'usr')
433 if not os.path.exists (os.path.join (absbuild, prefix)):
434 symlink_tree (prefix)
438 entries = open (os.path.join (dir, 'CVS/Entries')).readlines ()
439 files = filter (lambda x: x[0] != 'D', entries)
440 return map (lambda x: os.path.join (dir, x[1:x[1:].index ('/')+1]),
443 readme_files = ['AUTHORS', 'README', 'INSTALL', 'NEWS']
444 foo = map (lambda x: env.Texi2txt (x + '.txt',
445 os.path.join ('Documentation/topdocs',
448 txt_files = map (lambda x: x + '.txt', readme_files)
449 src_files = reduce (lambda x, y: x + y, map (cvs_files, subdirs))
450 tar_base = package.name + '-' + env['version']
451 tar_name = tar_base + '.tar.gz'
452 ball_prefix = os.path.join (outdir, tar_base)
453 tar_ball = os.path.join (outdir, tar_name)
455 dist_files = src_files + txt_files
456 ball_files = map (lambda x: os.path.join (ball_prefix, x), dist_files)
457 map (lambda x: env.Depends (tar_ball, x), ball_files)
458 map (lambda x: env.Command (os.path.join (ball_prefix, x), x,
459 'ln $SOURCE $TARGET'), dist_files)
460 tar = env.Command (tar_ball, src_files,
461 'tar czf $TARGET -C $TARGET.dir %s' % tar_base)
462 env.Alias ('tar', tar)
464 dist_ball = os.path.join (package.release_dir, tar_name)
465 env.Command (dist_ball, tar_ball,
466 'if [ -e $SOURCE -a -e $TARGET ]; then rm $TARGET; fi;' \
467 + 'ln $SOURCE $TARGET')
468 env.Depends ('dist', dist_ball)
469 patch_name = os.path.join (outdir, tar_base + '.diff.gz')
470 patch = env.PATCH (patch_name, tar_ball)
471 env.Depends (patch_name, dist_ball)
472 env.Alias ('release', patch)