]> git.donarmstrong.com Git - lilypond.git/blob - SConstruct
* lily/main.cc (dir_info): Print variables in sh format.
[lilypond.git] / SConstruct
1 # -*-python-*-
2
3 '''
4 Experimental scons (www.scons.org) building:
5
6 Usage:
7     scons
8     scons install
9     scons -c              # clean
10     scons -h              # help
11
12     scons build=DIR       # scrdir build, write to new tree =build
13     scons out=DIR         # write output to deeper dir DIR
14
15 Optionally, make a custom.py.  I have
16
17 import os
18 out='out-scons'
19 optimising=0
20 debugging=1
21 gui=1
22 os.path.join (os.getcwd (), '=install')
23
24 '''
25
26
27 # TODO:
28 #   * running from build-dir, without installing?
29 #     - scons will not install, if PREFIX lives outside of CWD
30 #     - build symlink tree
31 #       + mimicking regular installation setup?
32 #       + use tweaked scons 'install' target?
33 #   * commandline targets:
34 #      - clean => -c
35 #      - dist, tar => env.Tar
36 #   * Documentation, scripts
37 #   * env.Tar
38 #   * more fine-grained config.h -- move lilypondprefix to version.hh?
39 #     - config.h:   changes after system upgrades, affects all files
40 #     - version.hh:  prefix, version etc?  affects few
41
42 import re
43 import glob
44 import os
45 import sys
46 import string
47
48 env = Environment ()
49
50 # put your favourite stuff in custom.py
51 opts = Options ('custom.py', ARGUMENTS)
52 opts.Add ('prefix', 'Install prefix', '/usr/')
53 opts.Add ('out', 'Output directory', 'out-scons')
54 opts.Add ('build', 'Build directory', '.')
55 opts.AddOptions (
56         BoolOption ('warnings', 'compile with -Wall and similiar',
57                    1),
58         BoolOption ('debugging', 'compile with debugging symbols',
59                     0),
60         BoolOption ('optimising', 'compile with optimising',
61                     1),
62         BoolOption ('shared', 'build shared libraries',
63                     0),
64         BoolOption ('static', 'build static libraries',
65                     1),
66         BoolOption ('gui', 'build with GNOME backend (EXPERIMENTAL)',
67                     1),
68         BoolOption ('verbose', 'run commands with verbose flag',
69                     0),
70         )
71
72 Help (opts.GenerateHelpText (env))
73
74 env = Environment (options = opts)
75
76 env.CacheDir (os.path.join (env['build'], '=build-cache'))
77
78 #ugh
79 sys.path.append (os.path.join ('.', 'stepmake', 'bin'))
80 import packagepython
81 package = packagepython.Package ('.')
82
83 env['version'] = packagepython.version_tuple_to_str (package.version)
84 env['bindir'] = os.path.join (env['prefix'], 'bin')
85 env['sharedir'] = os.path.join (env['prefix'], 'share')
86 env['libdir'] = os.path.join (env['prefix'], 'lib')
87 env['localedir'] = os.path.join (env['sharedir'], 'locale')
88
89 env['sharedir_package'] = os.path.join (env['sharedir'], package.name)
90 env['sharedir_package_version'] = os.path.join (env['sharedir_package'],
91                                                  env['version'])
92 env['lilypondprefix'] = os.path.join (env['sharedir_package_version'])
93
94
95 if env['debugging']:
96         env.Append (CFLAGS = '-g')
97         env.Append (CXXFLAGS = '-g')
98 if env['optimising']:
99         env.Append (CFLAGS = '-O2')
100         env.Append (CXXFLAGS = '-O2')
101         env.Append (CXXFLAGS = '-DSTRING_UTILS_INLINED')
102 if env['warnings']:
103         env.Append (CFLAGS = '-W ')
104         env.Append (CFLAGS = '-Wall')
105         # what about = ['-W', '-Wall', ...]?
106         env.Append (CXXFLAGS = '-W')
107         env.Append (CXXFLAGS = '-Wall')
108         env.Append (CXXFLAGS = '-Wconversion')
109
110 env['MFMODE'] = 'ljfour'
111
112 conf = Configure (env)
113
114 defines = {
115    'DIRSEP' : "'/'",
116    'PATHSEP' : "':'",
117    'TOPLEVEL_VERSION' : '"' + env['version'] + '"',
118    'PACKAGE': '"' + package.name + '"',
119    'DATADIR' : '"' + env['sharedir'] + '"',
120    'LILYPOND_DATADIR' : '"' + env['sharedir_package'] + '"',
121    'LOCAL_LILYPOND_DATADIR' : '"' + env['sharedir_package_version'] + '"',
122    'LOCALEDIR' : '"' + env['localedir'] + '"',
123 }
124
125
126 command = r"""python -c 'import sys; sys.stdout.write ("%s/include/python%s" % (sys.prefix, sys.version[:3]))'""" #"
127 print command
128 PYTHON_INCLUDE = os.popen (command).read ()
129 env.Append (CPPPATH = PYTHON_INCLUDE)
130
131
132 headers = ('sys/stat.h', 'assert.h', 'kpathsea/kpathsea.h', 'Python.h')
133 for i in headers:
134         if conf.CheckCHeader (i):
135                 key = re.sub ('[./]', '_', 'HAVE_' + string.upper (i))
136                 defines[key] = '1'
137
138 ccheaders = ('sstream',)
139 for i in ccheaders:
140         if conf.CheckCXXHeader (i):
141                 key = re.sub ('[./]', '_', 'HAVE_' + string.upper (i))
142                 defines[key] = '1'
143
144 functions = ('gettext', 'isinf', 'memmem', 'snprintf', 'vsnprintf')
145 for i in functions:
146         if 0 or conf.CheckFunc (i):
147                 key = re.sub ('[./]', '_', 'HAVE_' + string.upper (i))
148                 defines[key] = '1'
149
150
151 key = 'HAVE_FLEXLEXER_YY_CURRENT_BUFFER'
152 defines[key] = conf.TryCompile ("""using namespace std;
153 #include <FlexLexer.h>
154 class yy_flex_lexer: public yyFlexLexer
155 {
156   public:
157     yy_flex_lexer ()
158     {
159       yy_current_buffer = 0;
160     }
161 };""", 'cc')
162
163 if conf.CheckLib ('dl'):
164         pass
165
166 if conf.CheckLib ('kpathsea'):
167         defines['KPATHSEA'] = '1'
168
169 # huh? 
170 if conf.CheckLib ('kpathsea', 'kpse_find_file'):
171         defines['HAVE_KPSE_FIND_FILE'] = '1'
172 if conf.CheckLib ('kpathsea', 'kpse_find_tfm'):
173         defines['HAVE_KPSE_FIND_TFM'] = '1'
174
175 #this could happen after flower...
176 env.ParseConfig ('guile-config compile')
177
178 #this could happen only for compiling pango-*
179 if env['gui']:
180         env.ParseConfig ('pkg-config --cflags --libs gtk+-2.0')
181         env.ParseConfig ('pkg-config --cflags --libs pango')
182         if conf.CheckCHeader ('pango/pangofc-fontmap.h'):
183                 defines['HAVE_PANGO_PANGOFC_FONTMAP_H'] = '1'
184
185         if conf.CheckLib ('pango-1.0',
186                           'pango_fc_font_map_add_decoder_find_func'):
187                 defines['HAVE_PANGO_CVS'] = '1'
188                 defines['HAVE_PANGO_FC_FONT_MAP_ADD_DECODER_FIND_FUNC'] = '1'
189
190 env = conf.Finish ()
191
192 build = env['build']
193 out = env['out']
194 ##reldir = str (Dir ('.').srcnode ())
195 reldir = os.getcwd ()
196 outdir = os.path.join (env['build'], reldir, env['out'])
197 if not os.path.exists (outdir):
198         os.mkdir (outdir)
199
200 def list_sort (lst):
201         sorted = lst
202         sorted.sort ()
203         return sorted
204         
205 config = open (os.path.join (outdir, 'config.h'), 'w')
206 for i in list_sort (defines.keys ()):
207         config.write ('#define %s %s\n' % (i, defines[i]))
208 config.close ()
209
210 os.system (sys.executable \
211            + ' ./stepmake/bin/make-version.py VERSION > '\
212            + os.path.join (outdir, 'version.hh'))
213
214 if os.path.exists ('parser'):
215         env.Append (LIBPATH = ['#/flower', '#/lily', '#/parser', '#/gui',],
216                     CPPPATH = [outdir, '#',])
217 else:   
218         env.Append (LIBPATH = ['#/flower/' + out,],
219                     CPPPATH = [outdir, '#',])
220
221 vre = re.compile ('^.*[^-.0-9]([0-9][0-9]*\.[0-9][.0-9]*).*$', re.DOTALL)
222 def get_version (program):
223         command = '(%(program)s --version || %(program)s -V) 2>&1' % vars ()
224         output = os.popen (command).read ()
225         v = re.sub (vre, '\\1', output)
226         return string.split (v, '.')
227
228 def assert_version (lst, program, minimal, description, package):
229         global required
230         sys.stdout.write ('Checking %s version... ' % program)
231         actual = get_version (program)
232         sys.stdout.write (string.join (actual, '.'))
233         sys.stdout.write ('\n')
234         if actual < string.split (minimal, '.'):
235                 lst.append ((description, package, minimal, program,
236                              string.join (actual, '.')))
237
238 required = []
239 assert_version (required, 'gcc', '2.8', 'GNU C compiler', 'gcc')
240 assert_version (required, 'g++', '3.0.5', 'GNU C++ compiler', 'g++')
241 assert_version (required, 'python', '2.1', 'Python (www.python.org)', 'python')
242 assert_version (required, 'guile-config', '1.6', 'GUILE development',
243                 'libguile-dev or guile-devel')
244 # Do not use bison 1.50 and 1.75.
245 assert_version (required, 'bison', '1.25', 'Bison -- parser generator',
246                 'bison')
247 assert_version (required, 'flex', '0.0', 'Flex -- lexer generator', 'flex')
248
249
250 optional = []
251 assert_version (optional, 'makeinfo', '4.7', 'Makeinfo tool', 'texinfo')
252 assert_version (optional, 'guile', '1.6', 'GUILE scheme',
253                 'libguile-dev or guile-devel')
254 assert_version (optional, 'mftrace', '1.0.27', 'Metafont tracing Type1',
255                 'mftrace')
256 assert_version (optional, 'perl', '4.0',
257                 'Perl practical efficient readonly language', 'perl')
258
259 if required:
260         print
261         print '********************************'
262         print 'Please install required packages'
263         for i in required:
264                 print '%s:      %s-%s or newer (found: %s-%s)' % i
265
266 if optional:
267         print
268         print '*************************************'
269         print 'Consider installing optional packages'
270         for i in optional:
271                 print '%s:      %s-%s or newer (found: %s-%s)' % i
272
273 #env['tarball'] = os.path.join (outdir,
274 #                              package.name + '-' + env['version'] + '.tar.gz')
275
276 env['tarball'] = os.path.join ('~/tmp',
277                                package.name + '-' + env['version'] + '.tar.gz')
278
279 Export ('env')
280
281 #subdirs = ['mf',]
282 #subdirs = ['flower', 'lily', 'parser', 'gui', 'main',]
283 subdirs = ['flower', 'lily', 'mf', 'scm', 'ly']
284 for d in subdirs:
285         b = os.path.join (build, d, out)
286         # Support clean sourctree build (srcdir build)
287         # and outdir build.
288         # TODO: figure out SConscript (dir, builddir, duplicate)) feature
289         if (build and build != '.') \
290            or (out and out != '.'):
291                 env.BuildDir (b, d, duplicate=0)
292         SConscript (os.path.join (b, 'SConscript'))
293
294
295 readmes = ['AUTHORS.txt', 'ChangeLog', 'NEWS.txt']
296
297 #testing
298 env.Append (TARFLAGS = '-z --owner=0 --group=0')
299 env.Append (GZIPFLAGS = '-9')
300 all_sources = ['SConstruct',] + readmes + subdirs
301 x = env.Tar (env['tarball'], all_sources)
302
303