3 # This is simple script to detect libraries and configure standard features.
7 from optparse
import OptionParser
10 def header_exists(cfg
, filename
):
11 fpath
= cfg
['include_path'][0] + '/' + filename
13 sys
.stderr
.write("Checking for '%s' ... " % fpath
)
17 sys
.stderr
.write("Yes\n")
20 sys
.stderr
.write("No\n")
23 def c_try_compile(cfg
, code
, 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]))
30 sys
.stderr
.write("No\n")
33 sys
.stderr
.write("Yes\n")
36 def c_compiler_exists(cfg
):
37 return c_try_compile(cfg
, "int main(void) { return 0; }",
38 "Checking for working compiler (%s) ... " %
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" +
47 " #error FORTIFY_SOURCE not usable\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')
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:]
64 sys
.stderr
.write("%s\n" % 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]))
74 sys
.stderr
.write('No\n')
77 sys
.stderr
.write('Yes\n')
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])
86 sys
.stderr
.write('No\n')
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])
97 sys
.stderr
.write('No\n')
98 cfg
['PYTHON_CONFIG'][0] = ''
100 sys
.stderr
.write('Yes\n')
103 # Adds prefix to *dir vars but only if the path does not start with '/'
105 def cfg_get_value(cfg_key
):
106 if (cfg_key
.endswith('dir')):
107 value
= cfg
[cfg_key
][0]
108 if (value
.startswith('/')):
111 prefix
= cfg
['prefix'][0]
112 if (prefix
.endswith('/')):
113 return prefix
+ value
115 return prefix
+ '/' + value
117 return cfg
[cfg_key
][0]
120 # Library checking api
123 def __init__(self
, libraries
, cfg
):
124 self
.libraries
= libraries
126 # Create dictionary for check results
127 self
.results
= dict()
131 def print_summary(self
):
132 sys
.stderr
.write("Settings and variables\n")
133 sys
.stderr
.write("----------------------\n")
136 value
= cfg_get_value(i
)
137 sys
.stderr
.write("%14s : '%s'\n" % (i
, value
))
138 sys
.stderr
.write(" - %s\n\n" % cfg
[i
][1])
140 sys
.stderr
.write("Libraries to link against\n")
141 sys
.stderr
.write("-------------------------\n")
143 for i
in self
.libraries
:
144 sys
.stderr
.write("%10s" % i
[0])
146 if (self
.results
[i
[0]]):
147 sys
.stderr
.write(" : Enabled\n")
149 sys
.stderr
.write(" : Disabled\n")
151 sys
.stderr
.write(" - %s\n\n" % i
[1])
153 # Enable/Disable library
155 def set(self
, name
, val
):
156 if name
not in map(lambda s
: s
[0], self
.libraries
):
157 sys
.stderr
.write("ERROR: Invalid library '%s'\n" % name
)
160 self
.results
[name
] = val
162 # Calls a function on arguments, all is stored in array if
164 # (I know this smells like a lisp, but I can't help myself)
167 sys
.stderr
.write("Checking for libraries\n")
168 sys
.stderr
.write("----------------------\n")
169 for i
in self
.libraries
:
170 if i
[0] not in self
.results
:
171 self
.results
[i
[0]] = i
[2][0](self
.cfg
, *i
[2][1:])
172 sys
.stderr
.write("\n")
174 # Writes '#define HAVE_XXX_H' into passed file
176 def write_config_h(self
, f
):
177 for i
in self
.libraries
:
178 f
.write("/*\n * %s\n */\n" % i
[1])
179 if self
.results
[i
[0]]:
180 f
.write("#define HAVE_%s\n" % i
[0].upper())
182 f
.write("//#define HAVE_%s\n" % i
[0].upper())
186 # Writes LDLIBS and CFLAGS into passed file
188 def write_config_mk(self
, f
):
189 for i
in self
.libraries
:
190 f
.write("# %s - %s\n" % (i
[0], i
[1]))
191 if self
.results
[i
[0]]:
192 f
.write("HAVE_%s=yes\n" % i
[0].upper())
193 # f.write("CFLAGS+=%s\nLDLIBS+=%s\n" % (i[3], i[4]))
195 f
.write("HAVE_%s=no\n" % i
[0].upper())
197 # Write all libraries the library should link with
198 for module
in self
.get_modules():
199 f
.write("# %s linker flags\n" % (module
))
200 f
.write("LDLIBS_%s=" % (module
))
201 f
.write("%s\n" % self
.get_linker_flags(module
))
203 # Return list of linker flags needed to build particular module
204 # (module may be core, loaders, backends, etc...
206 def get_linker_flags(self
, module
):
208 for i
in self
.libraries
:
209 if module
in i
[5] and self
.results
[i
[0]]:
217 # Returns list of cflags needed to build module
219 def get_cflags(self
, module
):
221 for i
in self
.libraries
:
222 if module
in i
[5] and self
.results
[i
[0]]:
227 # Builds a list of GFXprim libraries that may need to be linked against
230 def get_modules(self
):
232 for i
in self
.libraries
:
234 modules
[module
] = True
235 return modules
.keys()
237 def die_screaming(msg
):
238 sys
.stderr
.write("\n************************************\n")
239 sys
.stderr
.write("ERROR: ")
240 sys
.stderr
.write(msg
)
241 sys
.stderr
.write("\n************************************\n")
245 # Check for basic compiling tools
247 def basic_checks(cfg
):
248 sys
.stderr
.write("Basic checks\n")
249 sys
.stderr
.write("------------\n")
251 if not c_compiler_exists(cfg
):
252 die_screaming("No C compiler found")
254 if not python_module_installed(cfg
, 'jinja2'):
255 die_screaming("No jinja2 python module found")
258 check_for_python_config(cfg
)
260 if define_fortify_source(cfg
):
261 cfg
['CFLAGS'][0] = cfg
['CFLAGS'][0] + " -D_FORTIFY_SOURCE=2"
263 cfg
['PYTHON_VER'][0] = python_version(cfg
)
265 if cfg
['libdir'][0] == '':
266 sys
.stderr
.write("Checking for lib directory ... ")
268 if os
.path
.isdir('/usr/lib64'):
269 cfg
['libdir'][0] = 'lib64'
271 cfg
['libdir'][0] = 'lib'
273 sys
.stderr
.write(cfg
['libdir'][0] + '\n');
275 sys
.stderr
.write('\n')
278 # Write configuration files
280 def write_config_h(cfg
, libs
):
281 f
= open("config.h", "w")
282 f
.write("/*\n * This file is genereated by configure script\n */\n");
283 f
.write("#ifndef CONFIG_H\n#define CONFIG_H\n\n")
284 libs
.write_config_h(f
);
285 f
.write("#endif /* CONFIG_H */\n");
286 sys
.stderr
.write("Config 'config.h' written\n")
289 def write_config_mk(cfg
, libs
):
290 f
= open('config.gen.mk', 'w')
293 f
.write("# %s\n%s=%s\n" % (cfg
[i
][1], i
, cfg_get_value(i
)))
295 libs
.write_config_mk(f
);
297 sys
.stderr
.write("Config 'config.gen.mk' written\n")
300 # Generate app compilation helper
302 def write_gfxprim_config(cfg
, libs
):
303 modules
= libs
.get_modules()
304 f
= open('gfxprim-config', 'w')
305 f
.write('#!/bin/sh\n'
306 '#\n# Generated by configure, do not edit directly\n#\n\n'
307 'USAGE="Usage: $0 --list-modules --cflags --libs --libs-module_foo"\n'
308 '\nif test $# -eq 0; then\n'
312 'while test -n "$1"; do\n'
315 # General switches cflags and ldflags
316 f
.write('\t--help) echo "$USAGE"; exit 0;;\n')
317 f
.write('\t--list-modules) echo "%s"; exit 0;;\n' % ' '.join(modules
))
318 f
.write('\t--cflags) echo -n "-I/usr/include/GP/%s";;\n' %
319 libs
.get_cflags('core'))
320 f
.write('\t--libs) echo -n "-lgfxprim -lrt -lm %s ";;\n' % libs
.get_linker_flags('core'))
322 # ldflags for specific modules
326 ldflags
+= '-lgfxprim-backends '
328 ldflags
+= '-lgfxprim-grabbers '
330 ldflags
+= '-lgfxprim-loaders '
331 ldflags
+= libs
.get_linker_flags(i
)
332 f
.write('\t--libs-%s) echo -n "%s ";;\n' % (i
, ldflags
))
334 f
.write('\t*) echo "Invalid option \'$1\'"; echo $USAGE; exit 1;;\n')
336 f
.write('\tesac\n\tshift\ndone\necho\n')
338 os
.system('chmod +x gfxprim-config')
340 def cfg_parse_args(cfg
, args
):
344 die_screaming('Invalid argument %s' % i
)
346 if (par
[0] not in cfg
):
347 die_screaming('Invalid config key %s' % i
)
349 cfg
[par
[0]][0] = par
[1]
351 if __name__
== '__main__':
353 # Dictionary for default configuration parameters
355 cfg
= {'CC' : ['gcc', 'Path/name of the C compiler'],
356 'CFLAGS' : ['-W -Wall -Wextra -O2 -ggdb', 'C compiler flags'],
357 'PYTHON_BIN' : ['python', 'Path/name of python interpreter'],
358 'SWIG' : ['swig', 'Simplified Wrapper and Interface Generator'],
359 'PYTHON_CONFIG' : ['python-config', 'Python config helper'],
360 'PYTHON_VER' : ['', 'Python version (derived from python config)'],
361 'include_path' : ['/usr/include', 'Path to the system headers'],
362 'prefix' : ['/usr/local/', 'Installation prefix'],
363 'bindir' : ['bin', 'Where to install binaries'],
364 'libdir' : ['', 'Where to install libraries'],
365 'includedir' : ['include', 'Where to install headers'],
366 'mandir' : ['share/man', 'Where to install man pages'],
367 'docdir' : ['share/doc/', 'Where to install documentation'],
368 # Here comes autoconf compatibility cruft, not used for anything yet
369 'infodir' : ['share/info', 'Where to install info pages'],
370 'datadir' : ['share', 'Where to place readonly arch independend datafiles'],
371 'sysconfdir' : ['etc', 'Where to place configuration'],
372 'localstatedir' : ['local/var/', 'Where to place runtime modified datafiles'],
373 'build' : ['', 'WARNING not used'],
374 'host' : ['', 'WARNING not used'],
378 # Library detection/enable disable
380 # name, description, [detection], cflags, ldflags, list of modules library is needed for
382 l
= libraries([["libpng",
383 "Portable Network Graphics Library",
384 [header_exists
, "png.h"], "", "-lpng", ["loaders"]],
386 "Simple Direct Media Layer",
387 [header_exists
, "SDL/SDL.h"], "", "`sdl-config --libs`", ["backends"]],
389 "Library to load, handle and manipulate images in the JPEG format",
390 [header_exists
, "jpeglib.h"], "", "-ljpeg", ["loaders"]],
392 "An open-source JPEG 2000 library",
393 [header_exists
, "openjpeg-2.0/openjpeg.h"], "", "-lopenjp2", ["loaders"]],
395 "Library to handle, display and manipulate GIF images",
396 [header_exists
, "gif_lib.h"], "", "-lgif", ["loaders"]],
398 "Tag Image File Format (TIFF) library",
399 [header_exists
, "tiffio.h"], "", "-ltiff", ["loaders"]],
401 "Standard (de)compression library",
402 [header_exists
, "zlib.h"], "", "-lz", ["loaders"]],
405 [header_exists
, "X11/Xlib.h"], "", "-lX11", ["backends"]],
407 "MIT-SHM X Extension",
408 [header_exists
, "X11/extensions/XShm.h"], "", "-lXext", ["backends"]],
410 "Portable ascii art GFX library",
411 [header_exists
, "aalib.h"], "", "-laa", ["backends"]],
413 "A high-quality and portable font engine",
414 [header_exists
, "ft2build.h"], "", "`freetype-config --libs`", ["core"]],
417 [header_exists
, "dlfcn.h"], "", "-ldl", ["core"]],
420 [header_exists
, "linux/videodev2.h"], "", "", ["grabbers"]],
423 [header_exists
, "pthread.h"], "-pthread", "-pthread", ["core"]],
425 "C stack trace writeout",
426 [c_try_compile
, "#include <execinfo.h>\nint main(void) { backtrace(0, 0); }",
427 "Checking for backtrace() ... "], "", "", ["core"]]], cfg
)
429 parser
= OptionParser();
431 # Get configuration parameters from environment variables
434 cfg
[i
][0] = os
.environ
[i
]
436 # Enable disable libraries for linking
437 parser
.add_option("-e", "--enable", dest
="enable", action
="append",
438 help="force enable library linking", metavar
="libfoo")
439 parser
.add_option("-d", "--disable", dest
="disable", action
="append",
440 help="disable library linking", metavar
="libfoo")
442 # Add cfg config options
444 parser
.add_option("", "--"+i
, dest
=i
, metavar
=cfg
[i
][0], help=cfg
[i
][1])
446 (options
, args
) = parser
.parse_args();
449 # Enable/Disable libraries as user requested
450 # These are not checked later
453 for i
in options
.enable
:
456 for i
in options
.disable
:
460 if getattr(options
, i
) is not None:
461 cfg
[i
][0] = getattr(options
, i
)
464 # Handle args such as CC=gcc passed after options
466 cfg_parse_args(cfg
, args
)
473 write_config_h(cfg
, l
)
474 write_config_mk(cfg
, l
)
475 write_gfxprim_config(cfg
, l
)