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 # * running from build-dir, without installing?
32 # - scons will not install, if PREFIX lives outside of CWD
33 # - build symlink tree
34 # + mimicking regular installation setup?
35 # + use tweaked scons 'install' target?
36 # * commandline targets:
38 # - dist, tar => env.Tar
39 # * Documentation, scripts
41 # * more fine-grained config.h -- move lilypondprefix to version.hh?
42 # - config.h: changes after system upgrades, affects all files
43 # - version.hh: prefix, version etc? affects few
53 # put your favourite stuff in custom.py
54 opts = Options ('custom.py', ARGUMENTS)
55 opts.Add ('prefix', 'Install prefix', '/usr/')
56 opts.Add ('out', 'Output directory', 'out-scons')
57 opts.Add ('build', 'Build directory', '.')
59 BoolOption ('warnings', 'compile with -Wall and similiar',
61 BoolOption ('debugging', 'compile with debugging symbols',
63 BoolOption ('optimising', 'compile with optimising',
65 BoolOption ('shared', 'build shared libraries',
67 BoolOption ('static', 'build static libraries',
69 BoolOption ('gui', 'build with GNOME backend (EXPERIMENTAL)',
71 BoolOption ('verbose', 'run commands with verbose flag',
75 Help (opts.GenerateHelpText (env))
77 env = Environment (options = opts)
79 env.CacheDir (os.path.join (env['build'], '=build-cache'))
82 sys.path.append (os.path.join ('.', 'stepmake', 'bin'))
84 package = packagepython.Package ('.')
86 env['version'] = packagepython.version_tuple_to_str (package.version)
87 env['bindir'] = os.path.join (env['prefix'], 'bin')
88 env['sharedir'] = os.path.join (env['prefix'], 'share')
89 env['libdir'] = os.path.join (env['prefix'], 'lib')
90 env['localedir'] = os.path.join (env['sharedir'], 'locale')
92 env['sharedir_package'] = os.path.join (env['sharedir'], package.name)
93 env['sharedir_package_version'] = os.path.join (env['sharedir_package'],
95 env['lilypondprefix'] = os.path.join (env['sharedir_package_version'])
99 env.Append (CFLAGS = '-g')
100 env.Append (CXXFLAGS = '-g')
101 if env['optimising']:
102 env.Append (CFLAGS = '-O2')
103 env.Append (CXXFLAGS = '-O2')
104 env.Append (CXXFLAGS = '-DSTRING_UTILS_INLINED')
106 env.Append (CFLAGS = '-W ')
107 env.Append (CFLAGS = '-Wall')
108 # what about = ['-W', '-Wall', ...]?
109 env.Append (CXXFLAGS = '-W')
110 env.Append (CXXFLAGS = '-Wall')
111 env.Append (CXXFLAGS = '-Wconversion')
113 env['MFMODE'] = 'ljfour'
116 conf = Configure (env)
119 vre = re.compile ('^.*[^-.0-9]([0-9][0-9]*\.[0-9][.0-9]*).*$', re.DOTALL)
120 def get_version (program):
121 command = '(%(program)s --version || %(program)s -V) 2>&1' % vars ()
122 pipe = os.popen (command)
123 output = pipe.read ()
126 v = re.sub (vre, '\\1', output)
127 return string.split (v, '.')
129 def assert_version (lst, program, minimal, description, package):
131 sys.stdout.write ('Checking %s version... ' % program)
132 actual = get_version (program)
135 lst.append ((description, package, minimal, program,
138 sys.stdout.write (string.join (actual, '.'))
139 sys.stdout.write ('\n')
140 if actual < string.split (minimal, '.'):
141 lst.append ((description, package, minimal, program,
142 string.join (actual, '.')))
145 assert_version (required, 'gcc', '2.8', 'GNU C compiler', 'gcc')
146 assert_version (required, 'g++', '3.0.5', 'GNU C++ compiler', 'g++')
147 assert_version (required, 'python', '2.1', 'Python (www.python.org)', 'python')
148 assert_version (required, 'guile-config', '1.6', 'GUILE development',
149 'libguile-dev or guile-devel')
150 # Do not use bison 1.50 and 1.75.
151 assert_version (required, 'bison', '1.25', 'Bison -- parser generator',
153 assert_version (required, 'flex', '0.0', 'Flex -- lexer generator', 'flex')
157 assert_version (optional, 'makeinfo', '4.7', 'Makeinfo tool', 'texinfo')
158 assert_version (optional, 'guile', '1.6', 'GUILE scheme',
159 'libguile-dev or guile-devel')
160 assert_version (optional, 'mftrace', '1.0.27', 'Metafont tracing Type1',
162 assert_version (optional, 'perl', '4.0',
163 'Perl practical efficient readonly language', 'perl')
164 #assert_version (optional, 'foo', '2.0', 'Foomatic tester', 'bar')
170 'TOPLEVEL_VERSION' : '"' + env['version'] + '"',
171 'PACKAGE': '"' + package.name + '"',
172 'DATADIR' : '"' + env['sharedir'] + '"',
173 'LILYPOND_DATADIR' : '"' + env['sharedir_package'] + '"',
174 'LOCAL_LILYPOND_DATADIR' : '"' + env['sharedir_package_version'] + '"',
175 'LOCALEDIR' : '"' + env['localedir'] + '"',
179 command = r"""python -c 'import sys; sys.stdout.write ("%s/include/python%s" % (sys.prefix, sys.version[:3]))'""" #"
180 PYTHON_INCLUDE = os.popen (command).read ()
181 env.Append (CPPPATH = PYTHON_INCLUDE)
184 headers = ('sys/stat.h', 'assert.h', 'kpathsea/kpathsea.h', 'Python.h')
186 if conf.CheckCHeader (i):
187 key = re.sub ('[./]', '_', 'HAVE_' + string.upper (i))
190 ccheaders = ('sstream',)
192 if conf.CheckCXXHeader (i):
193 key = re.sub ('[./]', '_', 'HAVE_' + string.upper (i))
196 functions = ('gettext', 'isinf', 'memmem', 'snprintf', 'vsnprintf')
198 if 0 or conf.CheckFunc (i):
199 key = re.sub ('[./]', '_', 'HAVE_' + string.upper (i))
203 key = 'HAVE_FLEXLEXER_YY_CURRENT_BUFFER'
204 defines[key] = conf.TryCompile ("""using namespace std;
205 #include <FlexLexer.h>
206 class yy_flex_lexer: public yyFlexLexer
211 yy_current_buffer = 0;
215 if conf.CheckLib ('dl'):
218 if conf.CheckLib ('kpathsea'):
219 defines['KPATHSEA'] = '1'
222 if conf.CheckLib ('kpathsea', 'kpse_find_file'):
223 defines['HAVE_KPSE_FIND_FILE'] = '1'
224 if conf.CheckLib ('kpathsea', 'kpse_find_tfm'):
225 defines['HAVE_KPSE_FIND_TFM'] = '1'
227 #this could happen after flower...
228 env.ParseConfig ('guile-config compile')
230 #this could happen only for compiling pango-*
232 env.ParseConfig ('pkg-config --cflags --libs gtk+-2.0')
233 env.ParseConfig ('pkg-config --cflags --libs pango')
234 if conf.CheckCHeader ('pango/pangofc-fontmap.h'):
235 defines['HAVE_PANGO_PANGOFC_FONTMAP_H'] = '1'
237 if conf.CheckLib ('pango-1.0',
238 'pango_fc_font_map_add_decoder_find_func'):
239 defines['HAVE_PANGO_CVS'] = '1'
240 defines['HAVE_PANGO_FC_FONT_MAP_ADD_DECODER_FIND_FUNC'] = '1'
246 ##reldir = str (Dir ('.').srcnode ())
247 reldir = os.getcwd ()
248 outdir = os.path.join (env['build'], reldir, env['out'])
249 if not os.path.exists (outdir):
257 config = open (os.path.join (outdir, 'config.h'), 'w')
258 for i in list_sort (defines.keys ()):
259 config.write ('#define %s %s\n' % (i, defines[i]))
262 os.system (sys.executable \
263 + ' ./stepmake/bin/make-version.py VERSION > '\
264 + os.path.join (outdir, 'version.hh'))
266 if os.path.exists ('parser'):
267 env.Append (LIBPATH = ['#/flower', '#/lily', '#/parser', '#/gui',],
268 CPPPATH = [outdir, '#',])
270 env.Append (LIBPATH = ['#/flower/' + out,],
271 CPPPATH = [outdir, '#',])
275 print '********************************'
276 print 'Please install required packages'
278 print '%s: %s-%s or newer (found: %s %s)' % i
283 print '*************************************'
284 print 'Consider installing optional packages'
286 print '%s: %s-%s or newer (found: %s %s)' % i
288 #env['tarball'] = os.path.join (outdir,
289 # package.name + '-' + env['version'] + '.tar.gz')
291 env['tarball'] = os.path.join (os.environ['HOME'], 'tmp',
292 package.name + '-' + env['version'] + '.tar.gz')
295 if 'tar' in COMMAND_LINE_TARGETS:
296 #env.Default (env['tarball'])
298 env.Default (env['tarball'])
305 #subdirs = ['flower', 'lily', 'parser', 'gui', 'main',]
306 subdirs = ['flower', 'lily', 'mf', 'scm', 'ly']
308 b = os.path.join (build, d, out)
309 # Support clean sourctree build (srcdir build)
311 # TODO: figure out SConscript (dir, builddir, duplicate)) feature
312 if (build and build != '.') \
313 or (out and out != '.'):
314 env.BuildDir (b, d, duplicate=0)
315 SConscript (os.path.join (b, 'SConscript'))
317 readme_files = ['ChangeLog', 'COPYING', 'DEDICATION', 'ROADMAP', 'THANKS']
318 readme_txt = ['AUTHORS.txt', 'README.txt', 'INSTALL.txt', 'NEWS.txt']
319 # to be [re]moved after spit
320 patch_files = ['emacsclient.patch', 'server.el.patch', 'darwin.patch']
323 env.Append (TARFLAGS = '-z --owner=0 --group=0')
324 env.Append (GZIPFLAGS = '-9')
325 all_sources = ['SConstruct',] + subdirs \
326 + ['VERSION', '.cvsignore']\
327 + readme_files + readme_txt + patch_files
329 tar = env.Tar (env['tarball'], all_sources)
331 def symlink_tree (prefix):
337 if not os.path.isdir (dir):
338 if os.path.exists (dir):
342 map (mkdir, string.split (dir, os.sep))
343 srcdir = os.getcwd ()
344 def symlink (src, dst):
345 dir = os.path.dirname (dst)
348 frm = os.path.join (srcdir, src[1:])
350 depth = len (string.split (dir))
351 frm = os.path.join ('../' * depth, src, out)
352 os.symlink (frm, os.path.basename (dst))
354 map (lambda x: symlink (x[0], os.path.join (prefix, x[1])),
355 (('python', 'lib/lilypond/python'),
356 ('#mf', 'share/lilypond/fonts/mf'),
357 ('mf', 'share/lilypond/fonts/amf'),
358 ('mf', 'share/lilypond/fonts/tfm'),
359 ('mf', 'share/lilypond/fonts/type1'),
360 ('#tex', 'share/lilypond/tex/source'),
361 ('mf', 'share/lilypond/tex/generate'),
362 ('#ly', 'share/lilypond/ly'),
363 ('#scm', 'share/lilypond/scm'),
364 ('#ps', 'share/lilypond/ps'),
365 ('elisp', 'share/lilypond/elisp')))
368 prefix = os.path.join (outdir, 'usr')
369 if not os.path.exists (prefix):
370 symlink_tree (prefix)