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['LILYPOND_BOOK_FLAGS'] = ''
337 env['LILYPOND_BOOK_FORMAT'] = 'texi-html'
338 env['LILYPOND_BOOK_PATH'] = ['.', '#/input', '#/input/regression',
339 '#/input/test', '#/input/tutorial',
340 os.path.join (absbuild, 'mf', out),
341 '#/Documentation/user',
342 os.path.join (absbuild, 'Documentation', out)]
344 env['MAKEINFO_PATH'] = ['.', '#/Documentation/user',
345 os.path.join (absbuild, 'Documentation', out)]
347 ## TEXINFO_PAPERSIZE_OPTION= $(if $(findstring $(PAPERSIZE),a4),,-t @afourpaper)
348 env['TEXINFO_PAPERSIZE_OPTION'] = '-t @afourpaper'
350 SConscript ('buildscripts/builder.py')
353 #subdirs = ['flower', 'lily', 'parser', 'gui', 'main',]
354 #subdirs = ['flower', 'lily', 'mf', 'scm', 'ly']
355 subdirs = ['flower', 'lily', 'mf', 'scm', 'ly', 'Documentation']
357 b = os.path.join (build, d, out)
358 # Support clean sourctree build (srcdir build)
360 # TODO: figure out SConscript (dir, builddir, duplicate)) feature
361 if (build and build != '.') \
362 or (out and out != '.'):
363 env.BuildDir (b, d, duplicate=0)
364 SConscript (os.path.join (b, 'SConscript'))
366 readme_files = ['ChangeLog', 'COPYING', 'DEDICATION', 'ROADMAP', 'THANKS']
367 readme_txt = ['AUTHORS.txt', 'README.txt', 'INSTALL.txt', 'NEWS.txt']
368 # to be [re]moved after spit
369 patch_files = ['emacsclient.patch', 'server.el.patch', 'darwin.patch']
371 map (lambda x: env.Texi2txt (x, os.path.join ('Documentation/topdocs',
372 os.path.splitext (x)[0])),
376 env.Append (TARFLAGS = '-z --owner=0 --group=0')
377 env.Append (GZIPFLAGS = '-9')
378 all_sources = ['SConstruct',] + subdirs \
379 + ['VERSION', '.cvsignore']\
380 + readme_files + readme_txt + patch_files
382 tar = env.Tar (env['tarball'], all_sources)
385 def symlink_tree (prefix):
391 if not os.path.isdir (dir):
392 if os.path.exists (dir):
396 map (mkdir, string.split (dir, os.sep))
397 #srcdir = os.getcwd ()
398 def symlink (src, dst):
399 dir = os.path.dirname (dst)
402 frm = os.path.join (srcdir, src[1:])
404 depth = len (string.split (dir))
405 frm = os.path.join ('../' * depth, src, out)
406 os.symlink (frm, os.path.basename (dst))
408 map (lambda x: symlink (x[0], os.path.join (prefix, x[1])),
409 (('python', 'lib/lilypond/python'),
410 ('#mf', 'share/lilypond/fonts/mf'),
411 ('mf', 'share/lilypond/fonts/amf'),
412 ('mf', 'share/lilypond/fonts/tfm'),
413 ('mf', 'share/lilypond/fonts/type1'),
414 ('#tex', 'share/lilypond/tex/source'),
415 ('mf', 'share/lilypond/tex/generate'),
416 ('#ly', 'share/lilypond/ly'),
417 ('#scm', 'share/lilypond/scm'),
418 ('#ps', 'share/lilypond/ps'),
419 ('elisp', 'share/lilypond/elisp')))
422 prefix = os.path.join (outdir, 'usr')
423 if not os.path.exists (prefix):
424 symlink_tree (prefix)