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
62 # Without target arguments, build lily only
63 if not COMMAND_LINE_TARGETS:
66 # Target 'all' builds everything
67 if 'all' in COMMAND_LINE_TARGETS:
68 env.Default ('lily', 'fonts', 'doc')
70 # put your favourite stuff in custom.py
71 opts = Options ('custom.py', ARGUMENTS)
72 #opts = Options (['config.cache', 'custom.py'], ARGUMENTS)
73 opts.Add ('prefix', 'Install prefix', '/usr/')
74 opts.Add ('out', 'Output directory', 'out-scons')
75 opts.Add ('build', 'Build directory', '.')
77 BoolOption ('warnings', 'compile with -Wall and similiar',
79 BoolOption ('debugging', 'compile with debugging symbols',
81 BoolOption ('optimising', 'compile with optimising',
83 BoolOption ('shared', 'build shared libraries',
85 BoolOption ('static', 'build static libraries',
87 BoolOption ('gui', 'build with GNOME backend (EXPERIMENTAL)',
89 BoolOption ('verbose', 'run commands with verbose flag',
93 Help (opts.GenerateHelpText (env))
95 env = Environment (options = opts)
98 #opts.Save ('config.cache', env)
101 env.CacheDir (os.path.join (env['build'], '=build-cache'))
104 sys.path.append (os.path.join ('.', 'stepmake', 'bin'))
106 package = packagepython.Package ('.')
108 env['version'] = packagepython.version_tuple_to_str (package.version)
109 env['bindir'] = os.path.join (env['prefix'], 'bin')
110 env['sharedir'] = os.path.join (env['prefix'], 'share')
111 env['libdir'] = os.path.join (env['prefix'], 'lib')
112 env['localedir'] = os.path.join (env['sharedir'], 'locale')
114 env['sharedir_package'] = os.path.join (env['sharedir'], package.name)
115 env['sharedir_package_version'] = os.path.join (env['sharedir_package'],
117 env['lilypondprefix'] = os.path.join (env['sharedir_package_version'])
121 env.Append (CFLAGS = '-g')
122 env.Append (CXXFLAGS = '-g')
123 if env['optimising']:
124 env.Append (CFLAGS = '-O2')
125 env.Append (CXXFLAGS = '-O2')
126 env.Append (CXXFLAGS = '-DSTRING_UTILS_INLINED')
128 env.Append (CFLAGS = '-W ')
129 env.Append (CFLAGS = '-Wall')
130 # what about = ['-W', '-Wall', ...]?
131 env.Append (CXXFLAGS = '-W')
132 env.Append (CXXFLAGS = '-Wall')
133 env.Append (CXXFLAGS = '-Wconversion')
135 env['MFMODE'] = 'ljfour'
138 conf = Configure (env)
141 vre = re.compile ('^.*[^-.0-9]([0-9][0-9]*\.[0-9][.0-9]*).*$', re.DOTALL)
142 def get_version (program):
143 command = '(%(program)s --version || %(program)s -V) 2>&1' % vars ()
144 pipe = os.popen (command)
145 output = pipe.read ()
148 v = re.sub (vre, '\\1', output)
149 return string.split (v, '.')
151 def assert_version (lst, program, minimal, description, package):
153 sys.stdout.write ('Checking %s version... ' % program)
154 actual = get_version (program)
157 lst.append ((description, package, minimal, program,
160 sys.stdout.write (string.join (actual, '.'))
161 sys.stdout.write ('\n')
162 if actual < string.split (minimal, '.'):
163 lst.append ((description, package, minimal, program,
164 string.join (actual, '.')))
167 assert_version (required, 'gcc', '2.8', 'GNU C compiler', 'gcc')
168 assert_version (required, 'g++', '3.0.5', 'GNU C++ compiler', 'g++')
169 assert_version (required, 'python', '2.1', 'Python (www.python.org)', 'python')
170 assert_version (required, 'guile-config', '1.6', 'GUILE development',
171 'libguile-dev or guile-devel')
172 # Do not use bison 1.50 and 1.75.
173 assert_version (required, 'bison', '1.25', 'Bison -- parser generator',
175 assert_version (required, 'flex', '0.0', 'Flex -- lexer generator', 'flex')
179 assert_version (optional, 'makeinfo', '4.7', 'Makeinfo tool', 'texinfo')
180 assert_version (optional, 'guile', '1.6', 'GUILE scheme',
181 'libguile-dev or guile-devel')
182 assert_version (optional, 'mftrace', '1.0.27', 'Metafont tracing Type1',
184 assert_version (optional, 'perl', '4.0',
185 'Perl practical efficient readonly language', 'perl')
186 #assert_version (optional, 'foo', '2.0', 'Foomatic tester', 'bar')
192 'TOPLEVEL_VERSION' : '"' + env['version'] + '"',
193 'PACKAGE': '"' + package.name + '"',
194 'DATADIR' : '"' + env['sharedir'] + '"',
195 'LILYPOND_DATADIR' : '"' + env['sharedir_package'] + '"',
196 'LOCAL_LILYPOND_DATADIR' : '"' + env['sharedir_package_version'] + '"',
197 'LOCALEDIR' : '"' + env['localedir'] + '"',
201 command = r"""python -c 'import sys; sys.stdout.write ("%s/include/python%s" % (sys.prefix, sys.version[:3]))'""" #"
202 PYTHON_INCLUDE = os.popen (command).read ()
203 env.Append (CPPPATH = PYTHON_INCLUDE)
205 headers = ('sys/stat.h', 'assert.h', 'kpathsea/kpathsea.h', 'Python.h')
207 if conf.CheckCHeader (i):
208 key = re.sub ('[./]', '_', 'HAVE_' + string.upper (i))
211 ccheaders = ('sstream',)
213 if conf.CheckCXXHeader (i):
214 key = re.sub ('[./]', '_', 'HAVE_' + string.upper (i))
217 functions = ('gettext', 'isinf', 'memmem', 'snprintf', 'vsnprintf')
219 if 0 or conf.CheckFunc (i):
220 key = re.sub ('[./]', '_', 'HAVE_' + string.upper (i))
223 key = 'HAVE_FLEXLEXER_YY_CURRENT_BUFFER'
225 sys.stdout.write('Checking for yy_current_buffer ... ')
227 res = conf.TryCompile ("""using namespace std;
228 #include <FlexLexer.h>
229 class yy_flex_lexer: public yyFlexLexer
234 yy_current_buffer = 0;
239 sys.stdout.write('yes\n')
241 sys.stdout.write('no\n')
244 if conf.CheckLib ('dl'):
247 if conf.CheckLib ('kpathsea'):
248 defines['KPATHSEA'] = '1'
251 if conf.CheckLib ('kpathsea', 'kpse_find_file'):
252 defines['HAVE_KPSE_FIND_FILE'] = '1'
253 if conf.CheckLib ('kpathsea', 'kpse_find_tfm'):
254 defines['HAVE_KPSE_FIND_TFM'] = '1'
256 #this could happen after flower...
257 env.ParseConfig ('guile-config compile')
259 #this could happen only for compiling pango-*
261 env.ParseConfig ('pkg-config --cflags --libs gtk+-2.0')
262 env.ParseConfig ('pkg-config --cflags --libs pango')
263 if conf.CheckCHeader ('pango/pangofc-fontmap.h'):
264 defines['HAVE_PANGO_PANGOFC_FONTMAP_H'] = '1'
266 if conf.CheckLib ('pango-1.0',
267 'pango_fc_font_map_add_decoder_find_func'):
268 defines['HAVE_PANGO_CVS'] = '1'
269 defines['HAVE_PANGO_FC_FONT_MAP_ADD_DECODER_FIND_FUNC'] = '1'
274 reldir = str (Dir ('.').srcnode ())
276 srcdir = os.getcwd ()
278 env['srcdir'] = srcdir
282 ##reldir = str (Dir ('.').srcnode ())
283 reldir = os.getcwd ()
284 outdir = os.path.join (env['build'], reldir, env['out'])
285 if not os.path.exists (outdir):
293 config = open (os.path.join (outdir, 'config.h'), 'w')
294 for i in list_sort (defines.keys ()):
295 config.write ('#define %s %s\n' % (i, defines[i]))
298 os.system (sys.executable \
299 + ' ./stepmake/bin/make-version.py VERSION > '\
300 + os.path.join (outdir, 'version.hh'))
302 if os.path.exists ('parser'):
303 env.Append (LIBPATH = ['#/flower', '#/lily', '#/parser', '#/gui',],
304 CPPPATH = [outdir, '#',])
306 env.Append (LIBPATH = ['#/flower/' + out,],
307 CPPPATH = [outdir, '#',])
311 print '********************************'
312 print 'Please install required packages'
314 print '%s: %s-%s or newer (found: %s %s)' % i
319 print '*************************************'
320 print 'Consider installing optional packages'
322 print '%s: %s-%s or newer (found: %s %s)' % i
324 #env['tarball'] = os.path.join (outdir,
325 # package.name + '-' + env['version'] + '.tar.gz')
327 env['tarball'] = os.path.join (os.environ['HOME'], 'tmp',
328 package.name + '-' + env['version'] + '.tar.gz')
331 if 'tar' in COMMAND_LINE_TARGETS:
332 #env.Default (env['tarball'])
334 env.Default (env['tarball'])
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'
371 env.Append (PYTHONPATH = [os.path.join (outdir, 'usr/lib/python'),
372 os.path.join (srcdir, 'buildscripts'),
373 os.path.join (srcdir, 'python')])
375 # GS_FONTPATH, GS_LIB?
376 env.Append (ENV = { 'PYTHONPATH' : string.join (env['PYTHONPATH'],
378 # UGHR, lilypond.py uses lilypond-bin from PATH
379 env.Append (ENV = { 'PATH' : os.path.join (outdir, 'usr/bin') })
381 SConscript ('buildscripts/builder.py')
384 #subdirs = ['flower', 'lily', 'parser', 'gui', 'main',]
385 #subdirs = ['flower', 'lily', 'mf', 'scm', 'ly']
386 subdirs = ['flower', 'lily', 'mf', 'scm', 'ly', 'Documentation',
387 'Documentation/user', 'input']
389 b = os.path.join (build, d, out)
390 # Support clean sourctree build (srcdir build)
392 # TODO: figure out SConscript (dir, builddir, duplicate)) feature
393 if (build and build != '.') \
394 or (out and out != '.'):
395 env.BuildDir (b, d, duplicate=0)
396 SConscript (os.path.join (b, 'SConscript'))
398 readme_files = ['ChangeLog', 'COPYING', 'DEDICATION', 'ROADMAP', 'THANKS']
399 readme_txt = ['AUTHORS.txt', 'README.txt', 'INSTALL.txt', 'NEWS.txt']
400 # to be [re]moved after spit
401 patch_files = ['emacsclient.patch', 'server.el.patch', 'darwin.patch']
403 map (lambda x: env.Texi2txt (x, os.path.join ('Documentation/topdocs',
404 os.path.splitext (x)[0])),
408 env.Append (TARFLAGS = '-z --owner=0 --group=0')
409 env.Append (GZIPFLAGS = '-9')
410 all_sources = ['SConstruct',] + subdirs \
411 + ['VERSION', '.cvsignore']\
412 + readme_files + readme_txt + patch_files
414 tar = env.Tar (env['tarball'], all_sources)
417 def symlink_tree (prefix):
423 if not os.path.isdir (dir):
424 if os.path.exists (dir):
428 map (mkdir, string.split (dir, os.sep))
429 #srcdir = os.getcwd ()
430 def symlink (src, dst):
432 dir = os.path.dirname (dst)
435 frm = os.path.join (srcdir, src[1:])
438 depth = len (string.split (dir, '/'))
439 print 'depth: ' + `depth`
440 frm = os.path.join ('../' * depth, src, out)
441 print 'cwd: ' + `os.getcwd ()`
444 os.symlink (frm, os.path.basename (dst))
445 map (lambda x: symlink (x[0], os.path.join (prefix, x[1])),
446 (('python', 'lib/lilypond/python'),
447 # UGHR, lilypond.py uses lilypond-bin from PATH
449 ('#mf', 'share/lilypond/fonts/mf'),
450 ('mf', 'share/lilypond/fonts/afm'),
451 ('mf', 'share/lilypond/fonts/tfm'),
452 ('mf', 'share/lilypond/fonts/type1'),
453 ('#tex', 'share/lilypond/tex/source'),
454 ('mf', 'share/lilypond/tex/generate'),
455 ('#ly', 'share/lilypond/ly'),
456 ('#scm', 'share/lilypond/scm'),
457 ('#ps', 'share/lilypond/ps'),
458 ('elisp', 'share/lilypond/elisp')))
462 prefix = os.path.join (out, 'usr')
463 if not os.path.exists (prefix):
464 symlink_tree (prefix)