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 XXX scons # without args builds all targets below ./
16 XXX # maybe catch this one and only build lily?
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')
40 # * separate environments?
41 # - compile environment checks headers and libraries
42 # - doc environment checks doc stuff
43 # * - help for targets?
44 # - build symlink tree
45 # * commandline targets:
47 # - dist, tar => env.Tar
48 # * Documentation, scripts
50 # * more fine-grained config.h -- move lilypondprefix to version.hh?
51 # - config.h: changes after system upgrades, affects all files
52 # - version.hh: prefix, version etc? affects few
60 subdirs = ['flower', 'lily', 'mf', 'scm', 'ly', 'Documentation',
61 'Documentation/user', 'input']
64 scons [KEY=VALUE].. [TARGET]..
66 where TARGET is lily|all|fonts|doc|tar|dist|release
71 # Without target arguments, build lily only
72 if not COMMAND_LINE_TARGETS:
75 # Target 'all' builds everything
76 #if 'all' in COMMAND_LINE_TARGETS:
79 env.Alias ('all', ['lily', 'mf', 'input', 'Documentation'])
81 # Put your favourite stuff in custom.py
82 opts = Options ('custom.py', ARGUMENTS)
83 #opts = Options (['config.cache', 'custom.py'], ARGUMENTS)
84 opts.Add ('prefix', 'Install prefix', '/usr/')
85 opts.Add ('out', 'Output directory', 'out-scons')
86 opts.Add ('build', 'Build directory', '.')
88 BoolOption ('warnings', 'compile with -Wall and similiar',
90 BoolOption ('debugging', 'compile with debugging symbols',
92 BoolOption ('optimising', 'compile with optimising',
94 BoolOption ('shared', 'build shared libraries',
96 BoolOption ('static', 'build static libraries',
98 BoolOption ('gui', 'build with GNOME backend (EXPERIMENTAL)',
100 BoolOption ('verbose', 'run commands with verbose flag',
104 Help (usage + opts.GenerateHelpText (env))
106 env = Environment (options = opts)
109 #opts.Save ('config.cache', env)
112 env.CacheDir (os.path.join (env['build'], '=build-cache'))
115 sys.path.append (os.path.join ('.', 'stepmake', 'bin'))
117 package = packagepython.Package ('.')
119 env['version'] = packagepython.version_tuple_to_str (package.version)
120 env['bindir'] = os.path.join (env['prefix'], 'bin')
121 env['sharedir'] = os.path.join (env['prefix'], 'share')
122 env['libdir'] = os.path.join (env['prefix'], 'lib')
123 env['localedir'] = os.path.join (env['sharedir'], 'locale')
125 env['sharedir_package'] = os.path.join (env['sharedir'], package.name)
126 env['sharedir_package_version'] = os.path.join (env['sharedir_package'],
128 env['lilypondprefix'] = os.path.join (env['sharedir_package_version'])
132 env.Append (CFLAGS = '-g')
133 env.Append (CXXFLAGS = '-g')
134 if env['optimising']:
135 env.Append (CFLAGS = '-O2')
136 env.Append (CXXFLAGS = '-O2')
137 env.Append (CXXFLAGS = '-DSTRING_UTILS_INLINED')
139 env.Append (CFLAGS = '-W ')
140 env.Append (CFLAGS = '-Wall')
141 # what about = ['-W', '-Wall', ...]?
142 env.Append (CXXFLAGS = '-W')
143 env.Append (CXXFLAGS = '-Wall')
144 env.Append (CXXFLAGS = '-Wconversion')
146 env['MFMODE'] = 'ljfour'
149 conf = Configure (env)
152 vre = re.compile ('^.*[^-.0-9]([0-9][0-9]*\.[0-9][.0-9]*).*$', re.DOTALL)
153 def get_version (program):
154 command = '(%(program)s --version || %(program)s -V) 2>&1' % vars ()
155 pipe = os.popen (command)
156 output = pipe.read ()
159 v = re.sub (vre, '\\1', output)
160 return string.split (v, '.')
162 def assert_version (lst, program, minimal, description, package):
164 sys.stdout.write ('Checking %s version... ' % program)
165 actual = get_version (program)
168 lst.append ((description, package, minimal, program,
171 sys.stdout.write (string.join (actual, '.'))
172 sys.stdout.write ('\n')
173 if actual < string.split (minimal, '.'):
174 lst.append ((description, package, minimal, program,
175 string.join (actual, '.')))
178 assert_version (required, 'gcc', '2.8', 'GNU C compiler', 'gcc')
179 assert_version (required, 'g++', '3.0.5', 'GNU C++ compiler', 'g++')
180 assert_version (required, 'python', '2.1', 'Python (www.python.org)', 'python')
181 assert_version (required, 'guile-config', '1.6', 'GUILE development',
182 'libguile-dev or guile-devel')
183 # Do not use bison 1.50 and 1.75.
184 assert_version (required, 'bison', '1.25', 'Bison -- parser generator',
186 assert_version (required, 'flex', '0.0', 'Flex -- lexer generator', 'flex')
190 assert_version (optional, 'makeinfo', '4.7', 'Makeinfo tool', 'texinfo')
191 assert_version (optional, 'guile', '1.6', 'GUILE scheme',
192 'libguile-dev or guile-devel')
193 assert_version (optional, 'mftrace', '1.0.27', 'Metafont tracing Type1',
195 assert_version (optional, 'perl', '4.0',
196 'Perl practical efficient readonly language', 'perl')
197 #assert_version (optional, 'foo', '2.0', 'Foomatic tester', 'bar')
203 'TOPLEVEL_VERSION' : '"' + env['version'] + '"',
204 'PACKAGE': '"' + package.name + '"',
205 'DATADIR' : '"' + env['sharedir'] + '"',
206 'LILYPOND_DATADIR' : '"' + env['sharedir_package'] + '"',
207 'LOCAL_LILYPOND_DATADIR' : '"' + env['sharedir_package_version'] + '"',
208 'LOCALEDIR' : '"' + env['localedir'] + '"',
212 command = r"""python -c 'import sys; sys.stdout.write ("%s/include/python%s" % (sys.prefix, sys.version[:3]))'""" #"
213 PYTHON_INCLUDE = os.popen (command).read ()
214 env.Append (CPPPATH = PYTHON_INCLUDE)
216 headers = ('sys/stat.h', 'assert.h', 'kpathsea/kpathsea.h', 'Python.h')
218 if conf.CheckCHeader (i):
219 key = re.sub ('[./]', '_', 'HAVE_' + string.upper (i))
222 ccheaders = ('sstream',)
224 if conf.CheckCXXHeader (i):
225 key = re.sub ('[./]', '_', 'HAVE_' + string.upper (i))
228 functions = ('gettext', 'isinf', 'memmem', 'snprintf', 'vsnprintf')
230 if 0 or conf.CheckFunc (i):
231 key = re.sub ('[./]', '_', 'HAVE_' + string.upper (i))
234 key = 'HAVE_FLEXLEXER_YY_CURRENT_BUFFER'
236 sys.stdout.write('Checking for yy_current_buffer ... ')
238 res = conf.TryCompile ("""using namespace std;
239 #include <FlexLexer.h>
240 class yy_flex_lexer: public yyFlexLexer
245 yy_current_buffer = 0;
250 sys.stdout.write('yes\n')
252 sys.stdout.write('no\n')
255 if conf.CheckLib ('dl'):
258 if conf.CheckLib ('kpathsea'):
259 defines['KPATHSEA'] = '1'
262 if conf.CheckLib ('kpathsea', 'kpse_find_file'):
263 defines['HAVE_KPSE_FIND_FILE'] = '1'
264 if conf.CheckLib ('kpathsea', 'kpse_find_tfm'):
265 defines['HAVE_KPSE_FIND_TFM'] = '1'
267 #this could happen after flower...
268 env.ParseConfig ('guile-config compile')
270 #this could happen only for compiling pango-*
272 env.ParseConfig ('pkg-config --cflags --libs gtk+-2.0')
273 env.ParseConfig ('pkg-config --cflags --libs pango')
274 if conf.CheckCHeader ('pango/pangofc-fontmap.h'):
275 defines['HAVE_PANGO_PANGOFC_FONTMAP_H'] = '1'
277 if conf.CheckLib ('pango-1.0',
278 'pango_fc_font_map_add_decoder_find_func'):
279 defines['HAVE_PANGO_CVS'] = '1'
280 defines['HAVE_PANGO_FC_FONT_MAP_ADD_DECODER_FIND_FUNC'] = '1'
286 reldir = str (Dir ('.').srcnode ())
288 srcdir = os.getcwd ()
290 ##outdir = os.path.join (env['build'], reldir, env['out'])
291 outdir = os.path.join (env['build'], env['out'])
293 env['srcdir'] = srcdir
298 if not os.path.exists (outdir):
306 config = open (os.path.join (outdir, 'config.h'), 'w')
307 for i in list_sort (defines.keys ()):
308 config.write ('#define %s %s\n' % (i, defines[i]))
311 os.system (sys.executable \
312 + ' ./stepmake/bin/make-version.py VERSION > '\
313 + os.path.join (outdir, 'version.hh'))
315 if os.path.exists ('parser'):
316 env.Append (LIBPATH = ['#/flower', '#/lily', '#/parser', '#/gui',],
317 CPPPATH = [outdir, '#',])
319 env.Append (LIBPATH = ['#/flower/' + out,],
320 CPPPATH = [outdir, '#',])
324 print '********************************'
325 print 'Please install required packages'
327 print '%s: %s-%s or newer (found: %s %s)' % i
332 print '*************************************'
333 print 'Consider installing optional packages'
335 print '%s: %s-%s or newer (found: %s %s)' % i
341 absbuild = os.getcwd ()
344 env['absbuild'] = absbuild
347 env['MAKEINFO'] = 'LANG= makeinfo'
348 env['PYTHON'] = 'python'
349 env['LILYPOND_BIN'] = os.path.join (absbuild, 'lily', out, 'lilypond-bin')
350 env['LILYPONDPREFIX'] = os.path.join (outdir, 'usr/share/lilypond')
351 env['LILYPOND_BOOK'] = srcdir + '/scripts/lilypond-book.py'
352 env['ABC2LY_PY'] = srcdir + '/scripts/abc2ly.py'
353 env['MF_TO_TABLE_PY'] = srcdir + '/buildscripts/mf-to-table.py'
354 env['LILYPOND_PY'] = srcdir + '/scripts/lilypond.py'
355 env['LILYPOND_BOOK_FLAGS'] = ''
356 env['LILYPOND_BOOK_FORMAT'] = 'texi-html'
358 env['LILYPOND_BOOK_PATH'] = ['.', '#/input', '#/input/regression',
359 '#/input/test', '#/input/tutorial',
360 os.path.join (absbuild, 'mf', out),
361 '#/Documentation/user',
362 os.path.join (absbuild, 'Documentation', out),
363 os.path.join (absbuild, 'Documentation/user', out),
366 env['MAKEINFO_PATH'] = ['.', '#/Documentation/user',
367 os.path.join (absbuild, 'Documentation/user', out)]
369 ## TEXINFO_PAPERSIZE_OPTION= $(if $(findstring $(PAPERSIZE),a4),,-t @afourpaper)
370 env['TEXINFO_PAPERSIZE_OPTION'] = '-t @afourpaper'
372 tarbase = package.name + '-' + env['version']
373 tarname = tarbase + '.tar.gz'
374 tarball = os.path.join (outdir, tarname)
375 env['tarball'] = tarball
377 ballprefix = os.path.join (outdir, tarbase) + '/'
378 env['ballprefix'] = ballprefix
380 SConscript ('buildscripts/builder.py')
382 readme_files = ['ChangeLog', 'COPYING', 'DEDICATION', 'ROADMAP', 'THANKS']
383 readme_txt = ['AUTHORS.txt', 'README.txt', 'INSTALL.txt', 'NEWS.txt']
384 # to be [re]moved after spit
385 patch_files = ['emacsclient.patch', 'server.el.patch', 'darwin.patch']
388 env.Append (TARFLAGS = '-z --owner=0 --group=0')
389 env.Append (GZIPFLAGS = '-9')
390 all_sources = ['SConstruct', 'VERSION', '.cvsignore']\
391 + readme_files + readme_txt + patch_files
393 map (lambda x: env.Texi2txt (x, os.path.join ('Documentation/topdocs',
394 os.path.splitext (x)[0])),
398 #print `map (lambda x: env['ballprefix'] + x, all_sources)`
399 #ballize = map (env.BALL, all_sources)
400 #ballize = map (env.BALL, ['SConstruct', 'VERSION'])
401 #tar = env.Tar (tarball, map (lambda x: env['ballprefix'] + x, all_sources))
402 tar = env.Tar (env['tarball'], all_sources)
403 env.Alias ('tar', tar)
405 distball = os.path.join (package.release_dir, tarname)
406 env.Command (distball, tarball,
407 'if [ -e $SOURCE -a -e $TARGET ]; then rm $TARGET; fi;' \
408 + 'ln $SOURCE $TARGET')
409 env.Depends ('dist', distball)
410 patchfile = os.path.join (outdir, tarbase + '.diff.gz')
411 patch = env.PATCH (patchfile, tarball)
412 env.Depends (patchfile, distball)
413 env.Alias ('release', patch)
417 b = os.path.join (build, d, out)
418 # Support clean sourctree build (srcdir build)
420 # TODO: figure out SConscript (dir, builddir, duplicate)) feature
421 if (build and build != '.') \
422 or (out and out != '.'):
423 env.BuildDir (b, d, duplicate=0)
424 SConscript (os.path.join (b, 'SConscript'))
427 def symlink_tree (prefix):
433 if not os.path.isdir (dir):
434 if os.path.exists (dir):
438 map (mkdir, string.split (dir, os.sep))
439 #srcdir = os.getcwd ()
440 def symlink (src, dst):
442 dir = os.path.dirname (dst)
445 frm = os.path.join (srcdir, src[1:])
448 depth = len (string.split (dir, '/'))
449 print 'depth: ' + `depth`
450 frm = os.path.join ('../' * depth, src, out)
451 print 'cwd: ' + `os.getcwd ()`
454 os.symlink (frm, os.path.basename (dst))
455 map (lambda x: symlink (x[0], os.path.join (prefix, x[1])),
456 (('python', 'lib/lilypond/python'),
457 # UGHR, lilypond.py uses lilypond-bin from PATH
459 ('#mf', 'share/lilypond/fonts/mf'),
460 ('mf', 'share/lilypond/fonts/afm'),
461 ('mf', 'share/lilypond/fonts/tfm'),
462 ('mf', 'share/lilypond/fonts/type1'),
463 ('#tex', 'share/lilypond/tex/source'),
464 ('mf', 'share/lilypond/tex/generate'),
465 ('#ly', 'share/lilypond/ly'),
466 ('#scm', 'share/lilypond/scm'),
467 ('#ps', 'share/lilypond/ps'),
468 ('elisp', 'share/lilypond/elisp')))
472 prefix = os.path.join (out, 'usr')
473 if not os.path.exists (prefix):
474 symlink_tree (prefix)