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 (None, 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)
84 env.CacheDir (os.path.join (env['build'], '=build-cache'))
87 sys.path.append (os.path.join ('.', 'stepmake', 'bin'))
89 package = packagepython.Package ('.')
91 env['version'] = packagepython.version_tuple_to_str (package.version)
92 env['bindir'] = os.path.join (env['prefix'], 'bin')
93 env['sharedir'] = os.path.join (env['prefix'], 'share')
94 env['libdir'] = os.path.join (env['prefix'], 'lib')
95 env['localedir'] = os.path.join (env['sharedir'], 'locale')
97 env['sharedir_package'] = os.path.join (env['sharedir'], package.name)
98 env['sharedir_package_version'] = os.path.join (env['sharedir_package'],
100 env['lilypondprefix'] = os.path.join (env['sharedir_package_version'])
104 env.Append (CFLAGS = '-g')
105 env.Append (CXXFLAGS = '-g')
106 if env['optimising']:
107 env.Append (CFLAGS = '-O2')
108 env.Append (CXXFLAGS = '-O2')
109 env.Append (CXXFLAGS = '-DSTRING_UTILS_INLINED')
111 env.Append (CFLAGS = '-W ')
112 env.Append (CFLAGS = '-Wall')
113 # what about = ['-W', '-Wall', ...]?
114 env.Append (CXXFLAGS = '-W')
115 env.Append (CXXFLAGS = '-Wall')
116 env.Append (CXXFLAGS = '-Wconversion')
118 env['MFMODE'] = 'ljfour'
121 conf = Configure (env)
124 vre = re.compile ('^.*[^-.0-9]([0-9][0-9]*\.[0-9][.0-9]*).*$', re.DOTALL)
125 def get_version (program):
126 command = '(%(program)s --version || %(program)s -V) 2>&1' % vars ()
127 pipe = os.popen (command)
128 output = pipe.read ()
131 v = re.sub (vre, '\\1', output)
132 return string.split (v, '.')
134 def assert_version (lst, program, minimal, description, package):
136 sys.stdout.write ('Checking %s version... ' % program)
137 actual = get_version (program)
140 lst.append ((description, package, minimal, program,
143 sys.stdout.write (string.join (actual, '.'))
144 sys.stdout.write ('\n')
145 if actual < string.split (minimal, '.'):
146 lst.append ((description, package, minimal, program,
147 string.join (actual, '.')))
150 assert_version (required, 'gcc', '2.8', 'GNU C compiler', 'gcc')
151 assert_version (required, 'g++', '3.0.5', 'GNU C++ compiler', 'g++')
152 assert_version (required, 'python', '2.1', 'Python (www.python.org)', 'python')
153 assert_version (required, 'guile-config', '1.6', 'GUILE development',
154 'libguile-dev or guile-devel')
155 # Do not use bison 1.50 and 1.75.
156 assert_version (required, 'bison', '1.25', 'Bison -- parser generator',
158 assert_version (required, 'flex', '0.0', 'Flex -- lexer generator', 'flex')
162 assert_version (optional, 'makeinfo', '4.7', 'Makeinfo tool', 'texinfo')
163 assert_version (optional, 'guile', '1.6', 'GUILE scheme',
164 'libguile-dev or guile-devel')
165 assert_version (optional, 'mftrace', '1.0.27', 'Metafont tracing Type1',
167 assert_version (optional, 'perl', '4.0',
168 'Perl practical efficient readonly language', 'perl')
169 #assert_version (optional, 'foo', '2.0', 'Foomatic tester', 'bar')
175 'TOPLEVEL_VERSION' : '"' + env['version'] + '"',
176 'PACKAGE': '"' + package.name + '"',
177 'DATADIR' : '"' + env['sharedir'] + '"',
178 'LILYPOND_DATADIR' : '"' + env['sharedir_package'] + '"',
179 'LOCAL_LILYPOND_DATADIR' : '"' + env['sharedir_package_version'] + '"',
180 'LOCALEDIR' : '"' + env['localedir'] + '"',
184 command = r"""python -c 'import sys; sys.stdout.write ("%s/include/python%s" % (sys.prefix, sys.version[:3]))'""" #"
185 PYTHON_INCLUDE = os.popen (command).read ()
186 env.Append (CPPPATH = PYTHON_INCLUDE)
189 headers = ('sys/stat.h', 'assert.h', 'kpathsea/kpathsea.h', 'Python.h')
191 if conf.CheckCHeader (i):
192 key = re.sub ('[./]', '_', 'HAVE_' + string.upper (i))
195 ccheaders = ('sstream',)
197 if conf.CheckCXXHeader (i):
198 key = re.sub ('[./]', '_', 'HAVE_' + string.upper (i))
201 functions = ('gettext', 'isinf', 'memmem', 'snprintf', 'vsnprintf')
203 if 0 or conf.CheckFunc (i):
204 key = re.sub ('[./]', '_', 'HAVE_' + string.upper (i))
207 key = 'HAVE_FLEXLEXER_YY_CURRENT_BUFFER'
209 sys.stdout.write('Checking for yy_current_buffer ... ')
211 res = conf.TryCompile ("""using namespace std;
212 #include <FlexLexer.h>
213 class yy_flex_lexer: public yyFlexLexer
218 yy_current_buffer = 0;
223 sys.stdout.write('yes\n')
225 sys.stdout.write('no\n')
228 if conf.CheckLib ('dl'):
231 if conf.CheckLib ('kpathsea'):
232 defines['KPATHSEA'] = '1'
235 if conf.CheckLib ('kpathsea', 'kpse_find_file'):
236 defines['HAVE_KPSE_FIND_FILE'] = '1'
237 if conf.CheckLib ('kpathsea', 'kpse_find_tfm'):
238 defines['HAVE_KPSE_FIND_TFM'] = '1'
240 #this could happen after flower...
241 env.ParseConfig ('guile-config compile')
243 #this could happen only for compiling pango-*
245 env.ParseConfig ('pkg-config --cflags --libs gtk+-2.0')
246 env.ParseConfig ('pkg-config --cflags --libs pango')
247 if conf.CheckCHeader ('pango/pangofc-fontmap.h'):
248 defines['HAVE_PANGO_PANGOFC_FONTMAP_H'] = '1'
250 if conf.CheckLib ('pango-1.0',
251 'pango_fc_font_map_add_decoder_find_func'):
252 defines['HAVE_PANGO_CVS'] = '1'
253 defines['HAVE_PANGO_FC_FONT_MAP_ADD_DECODER_FIND_FUNC'] = '1'
258 reldir = str (Dir ('.').srcnode ())
260 srcdir = os.getcwd ()
262 env['srcdir'] = srcdir
266 ##reldir = str (Dir ('.').srcnode ())
267 reldir = os.getcwd ()
268 outdir = os.path.join (env['build'], reldir, env['out'])
269 if not os.path.exists (outdir):
277 config = open (os.path.join (outdir, 'config.h'), 'w')
278 for i in list_sort (defines.keys ()):
279 config.write ('#define %s %s\n' % (i, defines[i]))
282 os.system (sys.executable \
283 + ' ./stepmake/bin/make-version.py VERSION > '\
284 + os.path.join (outdir, 'version.hh'))
286 if os.path.exists ('parser'):
287 env.Append (LIBPATH = ['#/flower', '#/lily', '#/parser', '#/gui',],
288 CPPPATH = [outdir, '#',])
290 env.Append (LIBPATH = ['#/flower/' + out,],
291 CPPPATH = [outdir, '#',])
295 print '********************************'
296 print 'Please install required packages'
298 print '%s: %s-%s or newer (found: %s %s)' % i
303 print '*************************************'
304 print 'Consider installing optional packages'
306 print '%s: %s-%s or newer (found: %s %s)' % i
308 #env['tarball'] = os.path.join (outdir,
309 # package.name + '-' + env['version'] + '.tar.gz')
311 env['tarball'] = os.path.join (os.environ['HOME'], 'tmp',
312 package.name + '-' + env['version'] + '.tar.gz')
315 if 'tar' in COMMAND_LINE_TARGETS:
316 #env.Default (env['tarball'])
318 env.Default (env['tarball'])
325 absbuild = os.getcwd ()
328 env['absbuild'] = absbuild
331 env['MAKEINFO'] = 'LANG= makeinfo'
332 env['PYTHON'] = 'python'
333 env['LILYPOND_BIN'] = os.path.join (absbuild, 'lily', out, 'lilypond-bin')
334 env['LILYPONDPREFIX'] = os.path.join (outdir, 'usr/share/lilypond')
335 env['LILYPOND_BOOK'] = srcdir + '/scripts/lilypond-book.py'
336 env['ABC2LY_PY'] = srcdir + '/scripts/abc2ly.py'
337 env['MF_TO_TABLE_PY'] = srcdir + '/buildscripts/mf-to-table.py'
338 env['LILYPOND_PY'] = srcdir + '/scripts/lilypond.py'
339 env['LILYPOND_BOOK_FLAGS'] = ''
340 env['LILYPOND_BOOK_FORMAT'] = 'texi-html'
342 env['LILYPOND_BOOK_PATH'] = ['.', '#/input', '#/input/regression',
343 '#/input/test', '#/input/tutorial',
344 os.path.join (absbuild, 'mf', out),
345 '#/Documentation/user',
346 os.path.join (absbuild, 'Documentation', out),
347 os.path.join (absbuild, 'Documentation/user', out),
350 env['MAKEINFO_PATH'] = ['.', '#/Documentation/user',
351 os.path.join (absbuild, 'Documentation/user', out)]
353 ## TEXINFO_PAPERSIZE_OPTION= $(if $(findstring $(PAPERSIZE),a4),,-t @afourpaper)
354 env['TEXINFO_PAPERSIZE_OPTION'] = '-t @afourpaper'
356 SConscript ('buildscripts/builder.py')
359 #subdirs = ['flower', 'lily', 'parser', 'gui', 'main',]
360 #subdirs = ['flower', 'lily', 'mf', 'scm', 'ly']
361 subdirs = ['flower', 'lily', 'mf', 'scm', 'ly', 'Documentation',
362 'Documentation/user', 'input']
364 b = os.path.join (build, d, out)
365 # Support clean sourctree build (srcdir build)
367 # TODO: figure out SConscript (dir, builddir, duplicate)) feature
368 if (build and build != '.') \
369 or (out and out != '.'):
370 env.BuildDir (b, d, duplicate=0)
371 SConscript (os.path.join (b, 'SConscript'))
373 readme_files = ['ChangeLog', 'COPYING', 'DEDICATION', 'ROADMAP', 'THANKS']
374 readme_txt = ['AUTHORS.txt', 'README.txt', 'INSTALL.txt', 'NEWS.txt']
375 # to be [re]moved after spit
376 patch_files = ['emacsclient.patch', 'server.el.patch', 'darwin.patch']
378 map (lambda x: env.Texi2txt (x, os.path.join ('Documentation/topdocs',
379 os.path.splitext (x)[0])),
383 env.Append (TARFLAGS = '-z --owner=0 --group=0')
384 env.Append (GZIPFLAGS = '-9')
385 all_sources = ['SConstruct',] + subdirs \
386 + ['VERSION', '.cvsignore']\
387 + readme_files + readme_txt + patch_files
389 tar = env.Tar (env['tarball'], all_sources)
392 def symlink_tree (prefix):
398 if not os.path.isdir (dir):
399 if os.path.exists (dir):
403 map (mkdir, string.split (dir, os.sep))
404 #srcdir = os.getcwd ()
405 def symlink (src, dst):
406 dir = os.path.dirname (dst)
409 frm = os.path.join (srcdir, src[1:])
411 depth = len (string.split (dir))
412 frm = os.path.join ('../' * depth, src, out)
413 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 ('#mf', 'share/lilypond/fonts/mf'),
418 ('mf', 'share/lilypond/fonts/amf'),
419 ('mf', 'share/lilypond/fonts/tfm'),
420 ('mf', 'share/lilypond/fonts/type1'),
421 ('#tex', 'share/lilypond/tex/source'),
422 ('mf', 'share/lilypond/tex/generate'),
423 ('#ly', 'share/lilypond/ly'),
424 ('#scm', 'share/lilypond/scm'),
425 ('#ps', 'share/lilypond/ps'),
426 ('elisp', 'share/lilypond/elisp')))
429 prefix = os.path.join (outdir, 'usr')
430 if not os.path.exists (prefix):
431 symlink_tree (prefix)