loaders: PNM: Optimize Save()
[gfxprim/pasky.git] / configure
blob2e8164baf2de9ad8c2ded207166be34b4607145d
1 #!/usr/bin/env python
3 # This is simple script to detect libraries and configure standard features.
5 import os
6 import sys
7 from optparse import OptionParser
8 import subprocess
10 def header_exists(cfg, filename):
11 fpath = cfg['include_path'][0] + '/' + filename
13 sys.stderr.write("Checking for '%s' ... " % fpath)
15 try:
16 st = os.stat(fpath)
17 sys.stderr.write("Yes\n")
18 return True
19 except os.error:
20 sys.stderr.write("No\n")
21 return False
23 def c_try_compile(cfg, code, msg):
24 sys.stderr.write(msg)
26 ret = os.system("echo '%s' | %s %s -x c -o /dev/null - > /dev/null 2>&1" %
27 (code, cfg['CC'][0], cfg['CFLAGS'][0]))
29 if ret:
30 sys.stderr.write("No\n")
31 return False
32 else:
33 sys.stderr.write("Yes\n")
34 return True
36 def c_compiler_exists(cfg):
37 return c_try_compile(cfg, "int main(void) { return 0; }",
38 "Checking for working compiler (%s) ... " %
39 cfg["CC"][0])
41 def define_fortify_source(cfg):
42 return c_try_compile(cfg, "int main(void) {\n" +
43 "#if !defined _FORTIFY_SOURCE &&" +
44 "defined __OPTIMIZE__ && __OPTIMIZE__\n" +
45 " return 0;\n" +
46 "#else\n" +
47 " #error FORTIFY_SOURCE not usable\n" +
48 "#endif\n" +
49 "}", "Whether to define _FORTIFY_SOURCE ... ");
51 def python_version(cfg):
52 sys.stderr.write("Checking for python-config Python version ... ")
54 if (cfg['PYTHON_CONFIG'][0] is ''):
55 sys.stderr.write('NA\n')
56 return ''
58 cmd = subprocess.Popen([cfg['PYTHON_CONFIG'][0], '--ldflags'],
59 stdout=subprocess.PIPE, stderr=subprocess.PIPE)
60 res = str(cmd.communicate())
61 res = res[res.find('-lpython')+8:]
62 res = res[:3]
64 sys.stderr.write("%s\n" % res)
65 return res
67 def python_module_installed(cfg, module):
68 sys.stderr.write("Checking for python module %s ... " % module)
70 ret = os.system("echo 'import %s' | %s > /dev/null 2>&1" %
71 (module, cfg['PYTHON_BIN'][0]))
73 if ret:
74 sys.stderr.write('No\n')
75 return False
76 else:
77 sys.stderr.write('Yes\n')
78 return True
80 def check_for_swig(cfg):
81 sys.stderr.write("Checking for working swig ... ")
83 ret = os.system("%s -version > /dev/null 2>&1" % cfg['SWIG'][0])
85 if ret:
86 sys.stderr.write('No\n')
87 cfg['SWIG'][0] = ''
88 else:
89 sys.stderr.write('Yes\n')
91 def check_for_python_config(cfg):
92 sys.stderr.write("Checking for python-config ... ")
94 ret = os.system("%s --libs > /dev/null 2>&1" % cfg['PYTHON_CONFIG'][0])
96 if ret:
97 sys.stderr.write('No\n')
98 cfg['PYTHON_CONFIG'][0] = ''
99 else:
100 sys.stderr.write('Yes\n')
103 # Library checking api
105 class libraries:
106 def __init__(self, libraries, cfg):
107 self.libraries = libraries
108 self.cfg = cfg;
109 # Create dictionary for check results
110 self.results = dict()
112 # Print summary
114 def print_summary(self):
115 sys.stderr.write("Settings and variables\n")
116 sys.stderr.write("----------------------\n")
118 for i in cfg:
119 sys.stderr.write("%14s : %s\n" % (i, cfg[i][0]))
120 sys.stderr.write(" - %s\n\n" % cfg[i][1])
122 sys.stderr.write("Libraries to link against\n")
123 sys.stderr.write("-------------------------\n")
125 for i in self.libraries:
126 sys.stderr.write("%10s" % i[0])
128 if (self.results[i[0]]):
129 sys.stderr.write(" : Enabled\n")
130 else:
131 sys.stderr.write(" : Disabled\n")
133 sys.stderr.write(" - %s\n\n" % i[1])
135 # Enable/Disable library
137 def set(self, name, val):
138 if name not in map(lambda s: s[0], self.libraries):
139 sys.stderr.write("ERROR: Invalid library '%s'\n" % name)
140 exit(1)
141 else:
142 self.results[name] = val
144 # Calls a function on arguments, all is stored in array if
145 # not set previously
146 # (I know this smells like a lisp, but I can't help myself)
148 def check(self):
149 sys.stderr.write("Checking for libraries\n")
150 sys.stderr.write("----------------------\n")
151 for i in self.libraries:
152 if i[0] not in self.results:
153 self.results[i[0]] = i[2][0](self.cfg, *i[2][1:])
154 sys.stderr.write("\n")
156 # Writes '#define HAVE_XXX_H' into passed file
158 def write_config_h(self, f):
159 for i in self.libraries:
160 f.write("/*\n * %s\n */\n" % i[1])
161 if self.results[i[0]]:
162 f.write("#define HAVE_%s\n" % i[0].upper())
163 else:
164 f.write("//#define HAVE_%s\n" % i[0].upper())
165 f.write("\n")
168 # Writes LDLIBS and CFLAGS into passed file
170 def write_config_mk(self, f):
171 for i in self.libraries:
172 f.write("# %s - %s\n" % (i[0], i[1]))
173 if self.results[i[0]]:
174 f.write("HAVE_%s=yes\n" % i[0].upper())
175 # f.write("CFLAGS+=%s\nLDLIBS+=%s\n" % (i[3], i[4]))
176 else:
177 f.write("HAVE_%s=no\n" % i[0].upper())
180 # Return list of linker flags needed to build particular module
181 # (module may be core, loaders, backends, etc...
183 def get_linker_flags(self, module):
184 res = ''
185 for i in self.libraries:
186 if module in i[5] and self.results[i[0]]:
187 res += ' ' + i[4]
188 return res
190 # Returns list of cflags needed to build module
192 def get_cflags(self, module):
193 res = ''
194 for i in self.libraries:
195 if module in i[5] and self.results[i[0]]:
196 res += ' ' + i[3]
197 return res
199 def die_screaming(msg):
200 sys.stderr.write("\n************************************\n")
201 sys.stderr.write("ERROR: ")
202 sys.stderr.write(msg)
203 sys.stderr.write("\n************************************\n")
204 exit(1)
207 # Check for basic compiling tools
209 def basic_checks(cfg):
210 sys.stderr.write("Basic checks\n")
211 sys.stderr.write("------------\n")
213 if not c_compiler_exists(cfg):
214 die_screaming("No C compiler found")
216 if not python_module_installed(cfg, 'jinja2'):
217 die_screaming("No jinja2 python module found")
219 check_for_swig(cfg)
220 check_for_python_config(cfg)
222 if define_fortify_source(cfg):
223 cfg['CFLAGS'][0] = cfg['CFLAGS'][0] + " -D_FORTIFY_SOURCE=2"
225 cfg['PYTHON_VER'][0] = python_version(cfg)
227 if cfg['libdir'][0] == '':
228 sys.stderr.write("Checking for lib directory ... ")
230 if os.path.isdir(cfg['prefix'][0] + '/usr/lib64'):
231 cfg['libdir'][0] = '/usr/lib64'
232 else:
233 cfg['libdir'][0] = '/usr/lib'
235 sys.stderr.write(cfg['libdir'][0] + '\n');
237 sys.stderr.write('\n')
240 # Write configuration files
242 def write_config_h(cfg, libs):
243 f = open("config.h", "w")
244 f.write("/*\n * This file is genereated by configure script\n */\n");
245 f.write("#ifndef CONFIG_H\n#define CONFIG_H\n\n")
246 libs.write_config_h(f);
247 f.write("#endif /* CONFIG_H */\n");
248 sys.stderr.write("Config 'config.h' written\n")
249 f.close()
251 def write_config_mk(cfg, libs):
252 f = open('config.gen.mk', 'w')
253 for i in cfg:
254 f.write("# %s\n%s=%s\n" % (cfg[i][1], i, cfg[i][0]))
255 libs.write_config_mk(f);
256 f.close()
257 sys.stderr.write("Config 'config.gen.mk' written\n")
260 # Generate app compilation helper
262 def write_gfxprim_config(cfg, libs):
263 modules = ['loaders', 'backends', 'grabbers']
265 f = open('gfxprim-config', 'w')
266 f.write('#!/bin/sh\n'
267 '#\n# Generated by configure, do not edit directly\n#\n\n'
268 'USAGE="Usage: $0 --list-modules --cflags --libs --libs-module_foo"\n'
269 '\nif test $# -eq 0; then\n'
270 '\techo "$USAGE"\n'
271 '\texit 1\n'
272 'fi\n\n'
273 'while test -n "$1"; do\n'
274 '\tcase "$1" in\n')
276 # General switches cflags and ldflags
277 f.write('\t--help) echo "$USAGE"; exit 0;;\n')
278 f.write('\t--list-modules) echo "%s"; exit 0;;\n' % ' '.join(modules))
279 f.write('\t--cflags) echo -n "-I/usr/include/GP/%s";;\n' %
280 libs.get_cflags('core'))
281 f.write('\t--libs) echo -n "-lGP -lrt -lm %s ";;\n' % libs.get_linker_flags('core'))
283 # ldflags for specific modules
284 for i in modules:
285 ldflags = ''
286 if i == 'backends':
287 ldflags += '-lGP_backends '
288 if i == 'grabbers':
289 ldflags += '-lGP_grabbers '
290 if i == 'loaders':
291 ldflags += '-lGP_loaders '
292 ldflags += libs.get_linker_flags(i)
293 f.write('\t--libs-%s) echo -n "%s ";;\n' % (i, ldflags))
295 f.write('\t*) echo "Invalid option \'$1\'"; echo $USAGE; exit 1;;\n')
297 f.write('\tesac\n\tshift\ndone\necho\n')
298 f.close()
299 os.system('chmod +x gfxprim-config')
301 if __name__ == '__main__':
303 # Dictionary for default configuration parameters
305 cfg = {'CC' : ['gcc', 'Path/name of the C compiler'],
306 'CFLAGS' : ['-pthread -W -Wall -Wextra -fPIC -O2 -ggdb', 'C compiler flags'],
307 'PYTHON_BIN' : ['python', 'Path/name of python interpreter'],
308 'SWIG' : ['swig', 'Simplified Wrapper and Interface Generator'],
309 'PYTHON_CONFIG' : ['python-config', 'Python config helper'],
310 'PYTHON_VER' : ['', 'Python version (derived from python config)'],
311 'include_path' : ['/usr/include', 'Path to the system headers'],
312 'prefix' : ['', 'Installation prefix'],
313 'bindir' : ['/usr/bin', 'Where to install binaries'],
314 'libdir' : ['', 'Where to install libraries'],
315 'includedir' : ['/usr/include', 'Where to install headers'],
316 'mandir' : ['/usr/share/man', 'Where to install man pages']}
319 # Library detection/enable disable
321 # name, description, [detection], cflags, ldflags, list of modules library is needed for
323 l = libraries([["libpng",
324 "Portable Network Graphics Library",
325 [header_exists, "png.h"], "", "-lpng", ["loaders"]],
326 ["libsdl",
327 "Simple Direct Media Layer",
328 [header_exists, "SDL/SDL.h"], "", "`sdl-config --libs`", ["backends"]],
329 ["jpeg",
330 "Library to load, handle and manipulate images in the JPEG format",
331 [header_exists, "jpeglib.h"], "", "-ljpeg", ["loaders"]],
332 ["openjpeg",
333 "An open-source JPEG 2000 library",
334 [header_exists, "openjpeg-2.0/openjpeg.h"], "", "-lopenjp2", ["loaders"]],
335 ["giflib",
336 "Library to handle, display and manipulate GIF images",
337 [header_exists, "gif_lib.h"], "", "-lgif", ["loaders"]],
338 ["tiff",
339 "Tag Image File Format (TIFF) library",
340 [header_exists, "tiffio.h"], "", "-ltiff", ["loaders"]],
341 ["zlib",
342 "Standard (de)compression library",
343 [header_exists, "zlib.h"], "", "-lz", ["loaders"]],
344 ["libX11",
345 "X11 library",
346 [header_exists, "X11/Xlib.h"], "", "-lX11", ["backends"]],
347 ["X_SHM",
348 "MIT-SHM X Extension",
349 [header_exists, "X11/extensions/XShm.h"], "", "-lXext", ["backends"]],
350 ["aalib",
351 "Portable ascii art GFX library",
352 [header_exists, "aalib.h"], "", "-laa", ["backends"]],
353 ["freetype",
354 "A high-quality and portable font engine",
355 [header_exists, "ft2build.h"], "", "`freetype-config --libs`", ["core"]],
356 ["dl",
357 "Dynamic linker",
358 [header_exists, "dlfcn.h"], "", "-ldl", ["core"]],
359 ["V4L2",
360 "Video for linux 2",
361 [header_exists, "linux/videodev2.h"], "", "", ["grabbers"]],
362 ["pthread",
363 "Posix Threads",
364 [header_exists, "pthread.h"], "-pthread", "-pthread", ["core"]],
365 ["backtrace",
366 "C stack trace writeout",
367 [c_try_compile, "#include <execinfo.h>\nint main(void) { backtrace(0, 0); }",
368 "Checking for backtrace() ... "], "", "", ["core"]]], cfg)
370 parser = OptionParser();
372 # Get configuration parameters from environment variables
373 for i in cfg:
374 if i in os.environ:
375 cfg[i][0] = os.environ[i]
377 # Enable disable libraries for linking
378 parser.add_option("-e", "--enable", dest="enable", action="append",
379 help="force enable library linking", metavar="libfoo")
380 parser.add_option("-d", "--disable", dest="disable", action="append",
381 help="disable library linking", metavar="libfoo")
383 # Add cfg config options
384 for i in cfg:
385 parser.add_option("", "--"+i, dest=i, metavar=cfg[i][0], help=cfg[i][1])
387 (options, args) = parser.parse_args();
390 # Enable/Disable libraries as user requested
391 # These are not checked later
393 if options.enable:
394 for i in options.enable:
395 l.set(i, True);
396 if options.disable:
397 for i in options.disable:
398 l.set(i, False);
400 for i in cfg:
401 if getattr(options, i):
402 cfg[i][0] = getattr(options, i)
404 basic_checks(cfg);
406 l.check()
407 l.print_summary()
409 write_config_h(cfg, l)
410 write_config_mk(cfg, l)
411 write_gfxprim_config(cfg, l)