3 Autoconf-like configuration support; low level implementation of tests.
7 # Copyright (c) 2003 Stichting NLnet Labs
8 # Copyright (c) 2001, 2002, 2003 Steven Knight
10 # Permission is hereby granted, free of charge, to any person obtaining
11 # a copy of this software and associated documentation files (the
12 # "Software"), to deal in the Software without restriction, including
13 # without limitation the rights to use, copy, modify, merge, publish,
14 # distribute, sublicense, and/or sell copies of the Software, and to
15 # permit persons to whom the Software is furnished to do so, subject to
16 # the following conditions:
18 # The above copyright notice and this permission notice shall be included
19 # in all copies or substantial portions of the Software.
21 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
22 # KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
23 # WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24 # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
25 # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
26 # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
27 # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31 # The purpose of this module is to define how a check is to be performed.
32 # Use one of the Check...() functions below.
36 # A context class is used that defines functions for carrying out the tests,
37 # logging and messages. The following methods and members must be present:
39 # context.Display(msg) Function called to print messages that are normally
40 # displayed for the user. Newlines are explicitly used.
41 # The text should also be written to the logfile!
43 # context.Log(msg) Function called to write to a log file.
45 # context.BuildProg(text, ext)
46 # Function called to build a program, using "ext" for the
47 # file extention. Must return an empty string for
48 # success, an error message for failure.
49 # For reliable test results building should be done just
50 # like an actual program would be build, using the same
51 # command and arguments (including configure results so
54 # context.CompileProg(text, ext)
55 # Function called to compile a program, using "ext" for
56 # the file extention. Must return an empty string for
57 # success, an error message for failure.
58 # For reliable test results compiling should be done just
59 # like an actual source file would be compiled, using the
60 # same command and arguments (including configure results
63 # context.AppendLIBS(lib_name_list)
64 # Append "lib_name_list" to the value of LIBS.
65 # "lib_namelist" is a list of strings.
66 # Return the value of LIBS before changing it (any type
67 # can be used, it is passed to SetLIBS() later.)
69 # context.PrependLIBS(lib_name_list)
70 # Prepend "lib_name_list" to the value of LIBS.
71 # "lib_namelist" is a list of strings.
72 # Return the value of LIBS before changing it (any type
73 # can be used, it is passed to SetLIBS() later.)
75 # context.SetLIBS(value)
76 # Set LIBS to "value". The type of "value" is what
77 # AppendLIBS() returned.
78 # Return the value of LIBS before changing it (any type
79 # can be used, it is passed to SetLIBS() later.)
81 # context.headerfilename
82 # Name of file to append configure results to, usually
84 # The file must not exist or be empty when starting.
85 # Empty or None to skip this (some tests will not work!).
87 # context.config_h (may be missing). If present, must be a string, which
88 # will be filled with the contents of a config_h file.
90 # context.vardict Dictionary holding variables used for the tests and
91 # stores results from the tests, used for the build
93 # Normally contains "CC", "LIBS", "CPPFLAGS", etc.
95 # context.havedict Dictionary holding results from the tests that are to
96 # be used inside a program.
97 # Names often start with "HAVE_". These are zero
98 # (feature not present) or one (feature present). Other
99 # variables may have any value, e.g., "PERLVERSION" can
100 # be a number and "SYSTEMNAME" a string.
105 from types import IntType
111 LogInputFiles = 1 # Set that to log the input files in case of a failed test
112 LogErrorMessages = 1 # Set that to log Conftest-generated error messages
119 # - When a language is specified which is not supported the test fails. The
120 # message is a bit different, because not all the arguments for the normal
121 # message are available yet (chicken-egg problem).
124 def CheckBuilder(context, text = None, language = None):
126 Configure check to see if the compiler works.
127 Note that this uses the current value of compiler and linker flags, make
128 sure $CFLAGS, $CPPFLAGS and $LIBS are set correctly.
129 "language" should be "C" or "C++" and is used to select the compiler.
131 "text" may be used to specify the code to be build.
132 Returns an empty string for success, an error message for failure.
134 lang, suffix, msg = _lang2suffix(language)
136 context.Display("%s\n" % msg)
146 context.Display("Checking if building a %s file works... " % lang)
147 ret = context.BuildProg(text, suffix)
148 _YesNoResult(context, ret, None, text)
151 def CheckCC(context):
153 Configure check for a working C compiler.
155 This checks whether the C compiler, as defined in the $CC construction
156 variable, can compile a C source file. It uses the current $CCCOM value
157 too, so that it can test against non working flags.
160 context.Display("Checking whether the C compiler works")
167 ret = _check_empty_program(context, 'CC', text, 'C')
168 _YesNoResult(context, ret, None, text)
171 def CheckSHCC(context):
173 Configure check for a working shared C compiler.
175 This checks whether the C compiler, as defined in the $SHCC construction
176 variable, can compile a C source file. It uses the current $SHCCCOM value
177 too, so that it can test against non working flags.
180 context.Display("Checking whether the (shared) C compiler works")
187 ret = _check_empty_program(context, 'SHCC', text, 'C', use_shared = True)
188 _YesNoResult(context, ret, None, text)
191 def CheckCXX(context):
193 Configure check for a working CXX compiler.
195 This checks whether the CXX compiler, as defined in the $CXX construction
196 variable, can compile a CXX source file. It uses the current $CXXCOM value
197 too, so that it can test against non working flags.
200 context.Display("Checking whether the C++ compiler works")
207 ret = _check_empty_program(context, 'CXX', text, 'C++')
208 _YesNoResult(context, ret, None, text)
211 def CheckSHCXX(context):
213 Configure check for a working shared CXX compiler.
215 This checks whether the CXX compiler, as defined in the $SHCXX construction
216 variable, can compile a CXX source file. It uses the current $SHCXXCOM value
217 too, so that it can test against non working flags.
220 context.Display("Checking whether the (shared) C++ compiler works")
227 ret = _check_empty_program(context, 'SHCXX', text, 'C++', use_shared = True)
228 _YesNoResult(context, ret, None, text)
231 def _check_empty_program(context, comp, text, language, use_shared = False):
232 """Return 0 on success, 1 otherwise."""
233 if not context.env.has_key(comp) or not context.env[comp]:
234 # The compiler construction variable is not set or empty
237 lang, suffix, msg = _lang2suffix(language)
242 return context.CompileSharedObject(text, suffix)
244 return context.CompileProg(text, suffix)
247 def CheckFunc(context, function_name, header = None, language = None):
249 Configure check for a function "function_name".
250 "language" should be "C" or "C++" and is used to select the compiler.
252 Optional "header" can be defined to define a function prototype, include a
253 header file or anything else that comes before main().
254 Sets HAVE_function_name in context.havedict according to the result.
255 Note that this uses the current value of compiler and linker flags, make
256 sure $CFLAGS, $CPPFLAGS and $LIBS are set correctly.
257 Returns an empty string for success, an error message for failure.
260 # Remarks from autoconf:
261 # - Don't include <ctype.h> because on OSF/1 3.0 it includes <sys/types.h>
262 # which includes <sys/select.h> which contains a prototype for select.
263 # Similarly for bzero.
264 # - assert.h is included to define __stub macros and hopefully few
265 # prototypes, which can conflict with char $1(); below.
266 # - Override any gcc2 internal prototype to avoid an error.
267 # - We use char for the function declaration because int might match the
268 # return type of a gcc2 builtin and then its argument prototype would
270 # - The GNU C library defines this for functions which it implements to
271 # always fail with ENOSYS. Some functions are actually named something
272 # starting with __ and the normal name is an alias.
274 if context.headerfilename:
275 includetext = '#include "%s"' % context.headerfilename
283 char %s();""" % function_name
285 lang, suffix, msg = _lang2suffix(language)
287 context.Display("Cannot check for %s(): %s\n" % (function_name, msg))
296 #if defined (__stub_%(name)s) || defined (__stub___%(name)s)
304 """ % { 'name': function_name,
305 'include': includetext,
308 context.Display("Checking for %s function %s()... " % (lang, function_name))
309 ret = context.BuildProg(text, suffix)
310 _YesNoResult(context, ret, "HAVE_" + function_name, text,
311 "Define to 1 if the system has the function `%s'." %\
316 def CheckHeader(context, header_name, header = None, language = None,
317 include_quotes = None):
319 Configure check for a C or C++ header file "header_name".
320 Optional "header" can be defined to do something before including the
321 header file (unusual, supported for consistency).
322 "language" should be "C" or "C++" and is used to select the compiler.
324 Sets HAVE_header_name in context.havedict according to the result.
325 Note that this uses the current value of compiler and linker flags, make
326 sure $CFLAGS and $CPPFLAGS are set correctly.
327 Returns an empty string for success, an error message for failure.
329 # Why compile the program instead of just running the preprocessor?
330 # It is possible that the header file exists, but actually using it may
331 # fail (e.g., because it depends on other header files). Thus this test is
332 # more strict. It may require using the "header" argument.
334 # Use <> by default, because the check is normally used for system header
335 # files. SCons passes '""' to overrule this.
337 # Include "confdefs.h" first, so that the header can use HAVE_HEADER_H.
338 if context.headerfilename:
339 includetext = '#include "%s"\n' % context.headerfilename
345 lang, suffix, msg = _lang2suffix(language)
347 context.Display("Cannot check for header file %s: %s\n"
348 % (header_name, msg))
351 if not include_quotes:
352 include_quotes = "<>"
354 text = "%s%s\n#include %s%s%s\n\n" % (includetext, header,
355 include_quotes[0], header_name, include_quotes[1])
357 context.Display("Checking for %s header file %s... " % (lang, header_name))
358 ret = context.CompileProg(text, suffix)
359 _YesNoResult(context, ret, "HAVE_" + header_name, text,
360 "Define to 1 if you have the <%s> header file." % header_name)
364 def CheckType(context, type_name, fallback = None,
365 header = None, language = None):
367 Configure check for a C or C++ type "type_name".
368 Optional "header" can be defined to include a header file.
369 "language" should be "C" or "C++" and is used to select the compiler.
371 Sets HAVE_type_name in context.havedict according to the result.
372 Note that this uses the current value of compiler and linker flags, make
373 sure $CFLAGS, $CPPFLAGS and $LIBS are set correctly.
374 Returns an empty string for success, an error message for failure.
377 # Include "confdefs.h" first, so that the header can use HAVE_HEADER_H.
378 if context.headerfilename:
379 includetext = '#include "%s"' % context.headerfilename
385 lang, suffix, msg = _lang2suffix(language)
387 context.Display("Cannot check for %s type: %s\n" % (type_name, msg))
390 # Remarks from autoconf about this test:
391 # - Grepping for the type in include files is not reliable (grep isn't
393 # - Using "TYPE my_var;" doesn't work for const qualified types in C++.
394 # Adding an initializer is not valid for some C++ classes.
395 # - Using the type as parameter to a function either fails for K&$ C or for
397 # - Using "TYPE *my_var;" is valid in C for some types that are not
398 # declared (struct something).
399 # - Using "sizeof(TYPE)" is valid when TYPE is actually a variable.
400 # - Using the previous two together works reliably.
408 if (sizeof (%(name)s))
411 """ % { 'include': includetext,
415 context.Display("Checking for %s type %s... " % (lang, type_name))
416 ret = context.BuildProg(text, suffix)
417 _YesNoResult(context, ret, "HAVE_" + type_name, text,
418 "Define to 1 if the system has the type `%s'." % type_name)
419 if ret and fallback and context.headerfilename:
420 f = open(context.headerfilename, "a")
421 f.write("typedef %s %s;\n" % (fallback, type_name))
426 def CheckTypeSize(context, type_name, header = None, language = None, expect = None):
427 """This check can be used to get the size of a given type, or to check whether
428 the type is of expected size.
433 - includes : sequence
434 list of headers to include in the test code before testing the type
438 if given, will test wether the type has the given number of bytes.
439 If not given, will automatically find the size.
443 0 if the check failed, or the found size of the type if the check succeeded."""
445 # Include "confdefs.h" first, so that the header can use HAVE_HEADER_H.
446 if context.headerfilename:
447 includetext = '#include "%s"' % context.headerfilename
454 lang, suffix, msg = _lang2suffix(language)
456 context.Display("Cannot check for %s type: %s\n" % (type_name, msg))
459 src = includetext + header
460 if not expect is None:
461 # Only check if the given size is the right one
462 context.Display('Checking %s is %d bytes... ' % (type_name, expect))
464 # test code taken from autoconf: this is a pretty clever hack to find that
465 # a type is of a given size using only compilation. This speeds things up
466 # quite a bit compared to straightforward code using TryRun
468 typedef %s scons_check_type;
472 static int test_array[1 - 2 * !(((long int) (sizeof(scons_check_type))) == %d)];
479 st = context.CompileProg(src % (type_name, expect), suffix)
481 context.Display("yes\n")
482 _Have(context, "SIZEOF_%s" % type_name, expect,
483 "The size of `%s', as computed by sizeof." % type_name)
486 context.Display("no\n")
487 _LogFailed(context, src, st)
490 # Only check if the given size is the right one
491 context.Message('Checking size of %s ... ' % type_name)
493 # We have to be careful with the program we wish to test here since
494 # compilation will be attempted using the current environment's flags.
495 # So make sure that the program will compile without any warning. For
496 # example using: 'int main(int argc, char** argv)' will fail with the
497 # '-Wall -Werror' flags since the variables argc and argv would not be
498 # used in the program...
504 printf("%d", (int)sizeof(""" + type_name + """));
508 st, out = context.RunProg(src, suffix)
512 # If cannot convert output of test prog to an integer (the size),
513 # something went wront, so just fail
518 context.Display("yes\n")
519 _Have(context, "SIZEOF_%s" % type_name, size,
520 "The size of `%s', as computed by sizeof." % type_name)
523 context.Display("no\n")
524 _LogFailed(context, src, st)
529 def CheckDeclaration(context, symbol, includes = None, language = None):
530 """Checks whether symbol is declared.
532 Use the same test as autoconf, that is test whether the symbol is defined
533 as a macro or can be used as an r-value.
539 Optional "header" can be defined to include a header file.
541 only C and C++ supported.
545 True if the check failed, False if succeeded."""
547 # Include "confdefs.h" first, so that the header can use HAVE_HEADER_H.
548 if context.headerfilename:
549 includetext = '#include "%s"' % context.headerfilename
556 lang, suffix, msg = _lang2suffix(language)
558 context.Display("Cannot check for declaration %s: %s\n" % (type_name, msg))
561 src = includetext + includes
562 context.Display('Checking whether %s is declared... ' % symbol)
573 """ % (symbol, symbol)
575 st = context.CompileProg(src, suffix)
576 _YesNoResult(context, st, "HAVE_DECL_" + symbol, src,
577 "Set to 1 if %s is defined." % symbol)
580 def CheckLib(context, libs, func_name = None, header = None,
581 extra_libs = None, call = None, language = None, autoadd = 1,
584 Configure check for a C or C++ libraries "libs". Searches through
585 the list of libraries, until one is found where the test succeeds.
586 Tests if "func_name" or "call" exists in the library. Note: if it exists
587 in another library the test succeeds anyway!
588 Optional "header" can be defined to include a header file. If not given a
589 default prototype for "func_name" is added.
590 Optional "extra_libs" is a list of library names to be added after
591 "lib_name" in the build command. To be used for libraries that "lib_name"
593 Optional "call" replaces the call to "func_name" in the test code. It must
594 consist of complete C statements, including a trailing ";".
595 Both "func_name" and "call" arguments are optional, and in that case, just
596 linking against the libs is tested.
597 "language" should be "C" or "C++" and is used to select the compiler.
599 Note that this uses the current value of compiler and linker flags, make
600 sure $CFLAGS, $CPPFLAGS and $LIBS are set correctly.
601 Returns an empty string for success, an error message for failure.
603 # Include "confdefs.h" first, so that the header can use HAVE_HEADER_H.
604 if context.headerfilename:
605 includetext = '#include "%s"' % context.headerfilename
613 %s""" % (includetext, header)
615 # Add a function declaration if needed.
616 if func_name and func_name != "main":
625 # The actual test code.
627 call = "%s();" % func_name
629 # if no function to test, leave main() blank
639 i = string.find(call, "\n")
641 calltext = call[:i] + ".."
642 elif call[-1] == ';':
647 for lib_name in libs:
649 lang, suffix, msg = _lang2suffix(language)
651 context.Display("Cannot check for library %s: %s\n" % (lib_name, msg))
654 # if a function was specified to run in main(), say it
656 context.Display("Checking for %s in %s library %s... "
657 % (calltext, lang, lib_name))
658 # otherwise, just say the name of library and language
660 context.Display("Checking for %s library %s... "
668 oldLIBS = context.AppendLIBS(l)
670 oldLIBS = context.PrependLIBS(l)
671 sym = "HAVE_LIB" + lib_name
676 ret = context.BuildProg(text, suffix)
678 _YesNoResult(context, ret, sym, text,
679 "Define to 1 if you have the `%s' library." % lib_name)
680 if oldLIBS != -1 and (ret or not autoadd):
681 context.SetLIBS(oldLIBS)
689 # END OF PUBLIC FUNCTIONS
692 def _YesNoResult(context, ret, key, text, comment = None):
694 Handle the result of a test with a "yes" or "no" result.
695 "ret" is the return value: empty if OK, error message when not.
696 "key" is the name of the symbol to be defined (HAVE_foo).
697 "text" is the source code of the program used for testing.
698 "comment" is the C comment to add above the line defining the symbol (the
699 comment is automatically put inside a /* */). If None, no comment is added.
702 _Have(context, key, not ret, comment)
704 context.Display("no\n")
705 _LogFailed(context, text, ret)
707 context.Display("yes\n")
710 def _Have(context, key, have, comment = None):
712 Store result of a test in context.havedict and context.headerfilename.
713 "key" is a "HAVE_abc" name. It is turned into all CAPITALS and non-
714 alphanumerics are replaced by an underscore.
715 The value of "have" can be:
716 1 - Feature is defined, add "#define key".
717 0 - Feature is not defined, add "/* #undef key */".
718 Adding "undef" is what autoconf does. Not useful for the
719 compiler, but it shows that the test was done.
720 number - Feature is defined to this number "#define key have".
721 Doesn't work for 0 or 1, use a string then.
722 string - Feature is defined to this string "#define key have".
723 Give "have" as is should appear in the header file, include quotes
724 when desired and escape special characters!
726 key_up = string.upper(key)
727 key_up = re.sub('[^A-Z0-9_]', '_', key_up)
728 context.havedict[key_up] = have
730 line = "#define %s 1\n" % key_up
732 line = "/* #undef %s */\n" % key_up
733 elif type(have) == IntType:
734 line = "#define %s %d\n" % (key_up, have)
736 line = "#define %s %s\n" % (key_up, str(have))
738 if comment is not None:
739 lines = "\n/* %s */\n" % comment + line
743 if context.headerfilename:
744 f = open(context.headerfilename, "a")
747 elif hasattr(context,'config_h'):
748 context.config_h = context.config_h + lines
751 def _LogFailed(context, text, msg):
753 Write to the log about a failed program.
754 Add line numbers, so that error messages can be understood.
757 context.Log("Failed program was:\n")
758 lines = string.split(text, '\n')
759 if len(lines) and lines[-1] == '':
760 lines = lines[:-1] # remove trailing empty line
763 context.Log("%d: %s\n" % (n, line))
766 context.Log("Error message: %s\n" % msg)
769 def _lang2suffix(lang):
771 Convert a language name to a suffix.
772 When "lang" is empty or None C is assumed.
773 Returns a tuple (lang, suffix, None) when it works.
774 For an unrecognized language returns (None, None, msg).
776 lang = the unified language name
777 suffix = the suffix, including the leading dot
778 msg = an error message
780 if not lang or lang in ["C", "c"]:
781 return ("C", ".c", None)
782 if lang in ["c++", "C++", "cpp", "CXX", "cxx"]:
783 return ("C++", ".cpp", None)
785 return None, None, "Unsupported language: %s" % lang
788 # vim: set sw=4 et sts=4 tw=79 fo+=l:
792 # indent-tabs-mode:nil
794 # vim: set expandtab tabstop=4 shiftwidth=4: