4 Experimental scons (www.scons.org) building:
8 LILYPONDPREFIX=out-scons/usr/share/lilypond lily/out-scons/lilypond-bin
14 scons build=DIR # scrdir build, write to new tree =build
15 scons out=DIR # write output to deeper dir DIR
17 Optionally, make a custom.py. I have
24 os.path.join (os.getcwd (), '=install')
25 prefix=os.path.join (os.environ['HOME'], 'usr', 'pkg', 'lilypond')
31 # * separate environments?
32 # - compile environment checks headers and libraries
33 # - doc environment checks doc stuff
35 # * running from build-dir, without installing?
36 # - scons will not install, if PREFIX lives outside of CWD
37 # - build symlink tree
38 # + mimicking regular installation setup?
39 # + use tweaked scons 'install' target?
40 # * commandline targets:
42 # - dist, tar => env.Tar
43 # * Documentation, scripts
45 # * more fine-grained config.h -- move lilypondprefix to version.hh?
46 # - config.h: changes after system upgrades, affects all files
47 # - version.hh: prefix, version etc? affects few
57 # put your favourite stuff in custom.py
58 opts = Options ('custom.py', ARGUMENTS)
59 #opts = Options (['config.cache', 'custom.py'], ARGUMENTS)
60 opts.Add ('prefix', 'Install prefix', '/usr/')
61 opts.Add ('out', 'Output directory', 'out-scons')
62 opts.Add ('build', 'Build directory', '.')
64 BoolOption ('warnings', 'compile with -Wall and similiar',
66 BoolOption ('debugging', 'compile with debugging symbols',
68 BoolOption ('optimising', 'compile with optimising',
70 BoolOption ('shared', 'build shared libraries',
72 BoolOption ('static', 'build static libraries',
74 BoolOption ('gui', 'build with GNOME backend (EXPERIMENTAL)',
76 BoolOption ('verbose', 'run commands with verbose flag',
80 Help (opts.GenerateHelpText (env))
82 env = Environment (options = opts)
85 #opts.Save ('config.cache', env)
88 env.CacheDir (os.path.join (env['build'], '=build-cache'))
91 sys.path.append (os.path.join ('.', 'stepmake', 'bin'))
93 package = packagepython.Package ('.')
95 env['version'] = packagepython.version_tuple_to_str (package.version)
96 env['bindir'] = os.path.join (env['prefix'], 'bin')
97 env['sharedir'] = os.path.join (env['prefix'], 'share')
98 env['libdir'] = os.path.join (env['prefix'], 'lib')
99 env['localedir'] = os.path.join (env['sharedir'], 'locale')
101 env['sharedir_package'] = os.path.join (env['sharedir'], package.name)
102 env['sharedir_package_version'] = os.path.join (env['sharedir_package'],
104 env['lilypondprefix'] = os.path.join (env['sharedir_package_version'])
108 env.Append (CFLAGS = '-g')
109 env.Append (CXXFLAGS = '-g')
110 if env['optimising']:
111 env.Append (CFLAGS = '-O2')
112 env.Append (CXXFLAGS = '-O2')
113 env.Append (CXXFLAGS = '-DSTRING_UTILS_INLINED')
115 env.Append (CFLAGS = '-W ')
116 env.Append (CFLAGS = '-Wall')
117 # what about = ['-W', '-Wall', ...]?
118 env.Append (CXXFLAGS = '-W')
119 env.Append (CXXFLAGS = '-Wall')
120 env.Append (CXXFLAGS = '-Wconversion')
122 env['MFMODE'] = 'ljfour'
125 conf = Configure (env)
128 vre = re.compile ('^.*[^-.0-9]([0-9][0-9]*\.[0-9][.0-9]*).*$', re.DOTALL)
129 def get_version (program):
130 command = '(%(program)s --version || %(program)s -V) 2>&1' % vars ()
131 pipe = os.popen (command)
132 output = pipe.read ()
135 v = re.sub (vre, '\\1', output)
136 return string.split (v, '.')
138 def assert_version (lst, program, minimal, description, package):
140 sys.stdout.write ('Checking %s version... ' % program)
141 actual = get_version (program)
144 lst.append ((description, package, minimal, program,
147 sys.stdout.write (string.join (actual, '.'))
148 sys.stdout.write ('\n')
149 if actual < string.split (minimal, '.'):
150 lst.append ((description, package, minimal, program,
151 string.join (actual, '.')))
154 assert_version (required, 'gcc', '2.8', 'GNU C compiler', 'gcc')
155 assert_version (required, 'g++', '3.0.5', 'GNU C++ compiler', 'g++')
156 assert_version (required, 'python', '2.1', 'Python (www.python.org)', 'python')
157 assert_version (required, 'guile-config', '1.6', 'GUILE development',
158 'libguile-dev or guile-devel')
159 # Do not use bison 1.50 and 1.75.
160 assert_version (required, 'bison', '1.25', 'Bison -- parser generator',
162 assert_version (required, 'flex', '0.0', 'Flex -- lexer generator', 'flex')
166 assert_version (optional, 'makeinfo', '4.7', 'Makeinfo tool', 'texinfo')
167 assert_version (optional, 'guile', '1.6', 'GUILE scheme',
168 'libguile-dev or guile-devel')
169 assert_version (optional, 'mftrace', '1.0.27', 'Metafont tracing Type1',
171 assert_version (optional, 'perl', '4.0',
172 'Perl practical efficient readonly language', 'perl')
173 #assert_version (optional, 'foo', '2.0', 'Foomatic tester', 'bar')
179 'TOPLEVEL_VERSION' : '"' + env['version'] + '"',
180 'PACKAGE': '"' + package.name + '"',
181 'DATADIR' : '"' + env['sharedir'] + '"',
182 'LILYPOND_DATADIR' : '"' + env['sharedir_package'] + '"',
183 'LOCAL_LILYPOND_DATADIR' : '"' + env['sharedir_package_version'] + '"',
184 'LOCALEDIR' : '"' + env['localedir'] + '"',
188 command = r"""python -c 'import sys; sys.stdout.write ("%s/include/python%s" % (sys.prefix, sys.version[:3]))'""" #"
189 PYTHON_INCLUDE = os.popen (command).read ()
190 env.Append (CPPPATH = PYTHON_INCLUDE)
192 headers = ('sys/stat.h', 'assert.h', 'kpathsea/kpathsea.h', 'Python.h')
194 if conf.CheckCHeader (i):
195 key = re.sub ('[./]', '_', 'HAVE_' + string.upper (i))
198 ccheaders = ('sstream',)
200 if conf.CheckCXXHeader (i):
201 key = re.sub ('[./]', '_', 'HAVE_' + string.upper (i))
204 functions = ('gettext', 'isinf', 'memmem', 'snprintf', 'vsnprintf')
206 if 0 or conf.CheckFunc (i):
207 key = re.sub ('[./]', '_', 'HAVE_' + string.upper (i))
210 key = 'HAVE_FLEXLEXER_YY_CURRENT_BUFFER'
212 sys.stdout.write('Checking for yy_current_buffer ... ')
214 res = conf.TryCompile ("""using namespace std;
215 #include <FlexLexer.h>
216 class yy_flex_lexer: public yyFlexLexer
221 yy_current_buffer = 0;
226 sys.stdout.write('yes\n')
228 sys.stdout.write('no\n')
231 if conf.CheckLib ('dl'):
234 if conf.CheckLib ('kpathsea'):
235 defines['KPATHSEA'] = '1'
238 if conf.CheckLib ('kpathsea', 'kpse_find_file'):
239 defines['HAVE_KPSE_FIND_FILE'] = '1'
240 if conf.CheckLib ('kpathsea', 'kpse_find_tfm'):
241 defines['HAVE_KPSE_FIND_TFM'] = '1'
243 #this could happen after flower...
244 env.ParseConfig ('guile-config compile')
246 #this could happen only for compiling pango-*
248 env.ParseConfig ('pkg-config --cflags --libs gtk+-2.0')
249 env.ParseConfig ('pkg-config --cflags --libs pango')
250 if conf.CheckCHeader ('pango/pangofc-fontmap.h'):
251 defines['HAVE_PANGO_PANGOFC_FONTMAP_H'] = '1'
253 if conf.CheckLib ('pango-1.0',
254 'pango_fc_font_map_add_decoder_find_func'):
255 defines['HAVE_PANGO_CVS'] = '1'
256 defines['HAVE_PANGO_FC_FONT_MAP_ADD_DECODER_FIND_FUNC'] = '1'
261 reldir = str (Dir ('.').srcnode ())
263 srcdir = os.getcwd ()
265 env['srcdir'] = srcdir
269 ##reldir = str (Dir ('.').srcnode ())
270 reldir = os.getcwd ()
271 outdir = os.path.join (env['build'], reldir, env['out'])
272 if not os.path.exists (outdir):
280 config = open (os.path.join (outdir, 'config.h'), 'w')
281 for i in list_sort (defines.keys ()):
282 config.write ('#define %s %s\n' % (i, defines[i]))
285 os.system (sys.executable \
286 + ' ./stepmake/bin/make-version.py VERSION > '\
287 + os.path.join (outdir, 'version.hh'))
289 if os.path.exists ('parser'):
290 env.Append (LIBPATH = ['#/flower', '#/lily', '#/parser', '#/gui',],
291 CPPPATH = [outdir, '#',])
293 env.Append (LIBPATH = ['#/flower/' + out,],
294 CPPPATH = [outdir, '#',])
298 print '********************************'
299 print 'Please install required packages'
301 print '%s: %s-%s or newer (found: %s %s)' % i
306 print '*************************************'
307 print 'Consider installing optional packages'
309 print '%s: %s-%s or newer (found: %s %s)' % i
311 #env['tarball'] = os.path.join (outdir,
312 # package.name + '-' + env['version'] + '.tar.gz')
314 env['tarball'] = os.path.join (os.environ['HOME'], 'tmp',
315 package.name + '-' + env['version'] + '.tar.gz')
318 if 'tar' in COMMAND_LINE_TARGETS:
319 #env.Default (env['tarball'])
321 env.Default (env['tarball'])
328 absbuild = os.getcwd ()
331 env['absbuild'] = absbuild
334 env['MAKEINFO'] = 'LANG= makeinfo'
335 env['PYTHON'] = 'python'
336 env['LILYPOND_BIN'] = os.path.join (absbuild, 'lily', out, 'lilypond-bin')
337 env['LILYPONDPREFIX'] = os.path.join (outdir, 'usr/share/lilypond')
338 env['LILYPOND_BOOK'] = srcdir + '/scripts/lilypond-book.py'
339 env['ABC2LY_PY'] = srcdir + '/scripts/abc2ly.py'
340 env['MF_TO_TABLE_PY'] = srcdir + '/buildscripts/mf-to-table.py'
341 env['LILYPOND_PY'] = srcdir + '/scripts/lilypond.py'
342 env['LILYPOND_BOOK_FLAGS'] = ''
343 env['LILYPOND_BOOK_FORMAT'] = 'texi-html'
345 env['LILYPOND_BOOK_PATH'] = ['.', '#/input', '#/input/regression',
346 '#/input/test', '#/input/tutorial',
347 os.path.join (absbuild, 'mf', out),
348 '#/Documentation/user',
349 os.path.join (absbuild, 'Documentation', out),
350 os.path.join (absbuild, 'Documentation/user', out),
353 env['MAKEINFO_PATH'] = ['.', '#/Documentation/user',
354 os.path.join (absbuild, 'Documentation/user', out)]
356 ## TEXINFO_PAPERSIZE_OPTION= $(if $(findstring $(PAPERSIZE),a4),,-t @afourpaper)
357 env['TEXINFO_PAPERSIZE_OPTION'] = '-t @afourpaper'
358 env.Append (PYTHONPATH = [os.path.join (outdir, 'usr/lib/python'),
359 os.path.join (srcdir, 'buildscripts'),
360 os.path.join (srcdir, 'python')])
362 # GS_FONTPATH, GS_LIB?
363 env.Append (ENV = { 'PYTHONPATH' : string.join (env['PYTHONPATH'],
365 # UGHR, lilypond.py uses lilypond-bin from PATH
366 env.Append (ENV = { 'PATH' : os.path.join (outdir, 'usr/bin') })
368 SConscript ('buildscripts/builder.py')
371 #subdirs = ['flower', 'lily', 'parser', 'gui', 'main',]
372 #subdirs = ['flower', 'lily', 'mf', 'scm', 'ly']
373 subdirs = ['flower', 'lily', 'mf', 'scm', 'ly', 'Documentation',
374 'Documentation/user', 'input']
376 b = os.path.join (build, d, out)
377 # Support clean sourctree build (srcdir build)
379 # TODO: figure out SConscript (dir, builddir, duplicate)) feature
380 if (build and build != '.') \
381 or (out and out != '.'):
382 env.BuildDir (b, d, duplicate=0)
383 SConscript (os.path.join (b, 'SConscript'))
385 readme_files = ['ChangeLog', 'COPYING', 'DEDICATION', 'ROADMAP', 'THANKS']
386 readme_txt = ['AUTHORS.txt', 'README.txt', 'INSTALL.txt', 'NEWS.txt']
387 # to be [re]moved after spit
388 patch_files = ['emacsclient.patch', 'server.el.patch', 'darwin.patch']
390 map (lambda x: env.Texi2txt (x, os.path.join ('Documentation/topdocs',
391 os.path.splitext (x)[0])),
395 env.Append (TARFLAGS = '-z --owner=0 --group=0')
396 env.Append (GZIPFLAGS = '-9')
397 all_sources = ['SConstruct',] + subdirs \
398 + ['VERSION', '.cvsignore']\
399 + readme_files + readme_txt + patch_files
401 tar = env.Tar (env['tarball'], all_sources)
404 def symlink_tree (prefix):
410 if not os.path.isdir (dir):
411 if os.path.exists (dir):
415 map (mkdir, string.split (dir, os.sep))
416 #srcdir = os.getcwd ()
417 def symlink (src, dst):
419 dir = os.path.dirname (dst)
422 frm = os.path.join (srcdir, src[1:])
425 depth = len (string.split (dir, '/'))
426 print 'depth: ' + `depth`
427 frm = os.path.join ('../' * depth, src, out)
428 print 'cwd: ' + `os.getcwd ()`
431 os.symlink (frm, os.path.basename (dst))
432 map (lambda x: symlink (x[0], os.path.join (prefix, x[1])),
433 (('python', 'lib/lilypond/python'),
434 # UGHR, lilypond.py uses lilypond-bin from PATH
436 ('#mf', 'share/lilypond/fonts/mf'),
437 ('mf', 'share/lilypond/fonts/afm'),
438 ('mf', 'share/lilypond/fonts/tfm'),
439 ('mf', 'share/lilypond/fonts/type1'),
440 ('#tex', 'share/lilypond/tex/source'),
441 ('mf', 'share/lilypond/tex/generate'),
442 ('#ly', 'share/lilypond/ly'),
443 ('#scm', 'share/lilypond/scm'),
444 ('#ps', 'share/lilypond/ps'),
445 ('elisp', 'share/lilypond/elisp')))
449 prefix = os.path.join (out, 'usr')
450 if not os.path.exists (prefix):
451 symlink_tree (prefix)