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.
104 from types import IntType
110 LogInputFiles = 1 # Set that to log the input files in case of a failed test
111 LogErrorMessages = 1 # Set that to log Conftest-generated error messages
118 # - When a language is specified which is not supported the test fails. The
119 # message is a bit different, because not all the arguments for the normal
120 # message are available yet (chicken-egg problem).
123 def CheckBuilder(context, text = None, language = None):
125 Configure check to see if the compiler works.
126 Note that this uses the current value of compiler and linker flags, make
127 sure $CFLAGS, $CPPFLAGS and $LIBS are set correctly.
128 "language" should be "C" or "C++" and is used to select the compiler.
130 "text" may be used to specify the code to be build.
131 Returns an empty string for success, an error message for failure.
133 lang, suffix, msg = _lang2suffix(language)
135 context.Display("%s\n" % msg)
145 context.Display("Checking if building a %s file works... " % lang)
146 ret = context.BuildProg(text, suffix)
147 _YesNoResult(context, ret, None, text)
150 def CheckCC(context):
152 Configure check for a working C compiler.
154 This checks whether the C compiler, as defined in the $CC construction
155 variable, can compile a C source file. It uses the current $CCCOM value
156 too, so that it can test against non working flags.
159 context.Display("Checking whether the C compiler works")
166 ret = _check_empty_program(context, 'CC', text, 'C')
167 _YesNoResult(context, ret, None, text)
170 def CheckSHCC(context):
172 Configure check for a working shared C compiler.
174 This checks whether the C compiler, as defined in the $SHCC construction
175 variable, can compile a C source file. It uses the current $SHCCCOM value
176 too, so that it can test against non working flags.
179 context.Display("Checking whether the (shared) C compiler works")
186 ret = _check_empty_program(context, 'SHCC', text, 'C', use_shared = True)
187 _YesNoResult(context, ret, None, text)
190 def CheckCXX(context):
192 Configure check for a working CXX compiler.
194 This checks whether the CXX compiler, as defined in the $CXX construction
195 variable, can compile a CXX source file. It uses the current $CXXCOM value
196 too, so that it can test against non working flags.
199 context.Display("Checking whether the C++ compiler works")
206 ret = _check_empty_program(context, 'CXX', text, 'C++')
207 _YesNoResult(context, ret, None, text)
210 def CheckSHCXX(context):
212 Configure check for a working shared CXX compiler.
214 This checks whether the CXX compiler, as defined in the $SHCXX construction
215 variable, can compile a CXX source file. It uses the current $SHCXXCOM value
216 too, so that it can test against non working flags.
219 context.Display("Checking whether the (shared) C++ compiler works")
226 ret = _check_empty_program(context, 'SHCXX', text, 'C++', use_shared = True)
227 _YesNoResult(context, ret, None, text)
230 def _check_empty_program(context, comp, text, language, use_shared = False):
231 """Return 0 on success, 1 otherwise."""
232 if comp not in context.env or not context.env[comp]:
233 # The compiler construction variable is not set or empty
236 lang, suffix, msg = _lang2suffix(language)
241 return context.CompileSharedObject(text, suffix)
243 return context.CompileProg(text, suffix)
246 def CheckFunc(context, function_name, header = None, language = None):
248 Configure check for a function "function_name".
249 "language" should be "C" or "C++" and is used to select the compiler.
251 Optional "header" can be defined to define a function prototype, include a
252 header file or anything else that comes before main().
253 Sets HAVE_function_name in context.havedict according to the result.
254 Note that this uses the current value of compiler and linker flags, make
255 sure $CFLAGS, $CPPFLAGS and $LIBS are set correctly.
256 Returns an empty string for success, an error message for failure.
259 # Remarks from autoconf:
260 # - Don't include <ctype.h> because on OSF/1 3.0 it includes <sys/types.h>
261 # which includes <sys/select.h> which contains a prototype for select.
262 # Similarly for bzero.
263 # - assert.h is included to define __stub macros and hopefully few
264 # prototypes, which can conflict with char $1(); below.
265 # - Override any gcc2 internal prototype to avoid an error.
266 # - We use char for the function declaration because int might match the
267 # return type of a gcc2 builtin and then its argument prototype would
269 # - The GNU C library defines this for functions which it implements to
270 # always fail with ENOSYS. Some functions are actually named something
271 # starting with __ and the normal name is an alias.
273 if context.headerfilename:
274 includetext = '#include "%s"' % context.headerfilename
282 char %s();""" % function_name
284 lang, suffix, msg = _lang2suffix(language)
286 context.Display("Cannot check for %s(): %s\n" % (function_name, msg))
295 #if defined (__stub_%(name)s) || defined (__stub___%(name)s)
303 """ % { 'name': function_name,
304 'include': includetext,
307 context.Display("Checking for %s function %s()... " % (lang, function_name))
308 ret = context.BuildProg(text, suffix)
309 _YesNoResult(context, ret, "HAVE_" + function_name, text,
310 "Define to 1 if the system has the function `%s'." %\
315 def CheckHeader(context, header_name, header = None, language = None,
316 include_quotes = None):
318 Configure check for a C or C++ header file "header_name".
319 Optional "header" can be defined to do something before including the
320 header file (unusual, supported for consistency).
321 "language" should be "C" or "C++" and is used to select the compiler.
323 Sets HAVE_header_name in context.havedict according to the result.
324 Note that this uses the current value of compiler and linker flags, make
325 sure $CFLAGS and $CPPFLAGS are set correctly.
326 Returns an empty string for success, an error message for failure.
328 # Why compile the program instead of just running the preprocessor?
329 # It is possible that the header file exists, but actually using it may
330 # fail (e.g., because it depends on other header files). Thus this test is
331 # more strict. It may require using the "header" argument.
333 # Use <> by default, because the check is normally used for system header
334 # files. SCons passes '""' to overrule this.
336 # Include "confdefs.h" first, so that the header can use HAVE_HEADER_H.
337 if context.headerfilename:
338 includetext = '#include "%s"\n' % context.headerfilename
344 lang, suffix, msg = _lang2suffix(language)
346 context.Display("Cannot check for header file %s: %s\n"
347 % (header_name, msg))
350 if not include_quotes:
351 include_quotes = "<>"
353 text = "%s%s\n#include %s%s%s\n\n" % (includetext, header,
354 include_quotes[0], header_name, include_quotes[1])
356 context.Display("Checking for %s header file %s... " % (lang, header_name))
357 ret = context.CompileProg(text, suffix)
358 _YesNoResult(context, ret, "HAVE_" + header_name, text,
359 "Define to 1 if you have the <%s> header file." % header_name)
363 def CheckType(context, type_name, fallback = None,
364 header = None, language = None):
366 Configure check for a C or C++ type "type_name".
367 Optional "header" can be defined to include a header file.
368 "language" should be "C" or "C++" and is used to select the compiler.
370 Sets HAVE_type_name in context.havedict according to the result.
371 Note that this uses the current value of compiler and linker flags, make
372 sure $CFLAGS, $CPPFLAGS and $LIBS are set correctly.
373 Returns an empty string for success, an error message for failure.
376 # Include "confdefs.h" first, so that the header can use HAVE_HEADER_H.
377 if context.headerfilename:
378 includetext = '#include "%s"' % context.headerfilename
384 lang, suffix, msg = _lang2suffix(language)
386 context.Display("Cannot check for %s type: %s\n" % (type_name, msg))
389 # Remarks from autoconf about this test:
390 # - Grepping for the type in include files is not reliable (grep isn't
392 # - Using "TYPE my_var;" doesn't work for const qualified types in C++.
393 # Adding an initializer is not valid for some C++ classes.
394 # - Using the type as parameter to a function either fails for K&$ C or for
396 # - Using "TYPE *my_var;" is valid in C for some types that are not
397 # declared (struct something).
398 # - Using "sizeof(TYPE)" is valid when TYPE is actually a variable.
399 # - Using the previous two together works reliably.
407 if (sizeof (%(name)s))
410 """ % { 'include': includetext,
414 context.Display("Checking for %s type %s... " % (lang, type_name))
415 ret = context.BuildProg(text, suffix)
416 _YesNoResult(context, ret, "HAVE_" + type_name, text,
417 "Define to 1 if the system has the type `%s'." % type_name)
418 if ret and fallback and context.headerfilename:
419 f = open(context.headerfilename, "a")
420 f.write("typedef %s %s;\n" % (fallback, type_name))
425 def CheckTypeSize(context, type_name, header = None, language = None, expect = None):
426 """This check can be used to get the size of a given type, or to check whether
427 the type is of expected size.
432 - includes : sequence
433 list of headers to include in the test code before testing the type
437 if given, will test wether the type has the given number of bytes.
438 If not given, will automatically find the size.
442 0 if the check failed, or the found size of the type if the check succeeded."""
444 # Include "confdefs.h" first, so that the header can use HAVE_HEADER_H.
445 if context.headerfilename:
446 includetext = '#include "%s"' % context.headerfilename
453 lang, suffix, msg = _lang2suffix(language)
455 context.Display("Cannot check for %s type: %s\n" % (type_name, msg))
458 src = includetext + header
459 if not expect is None:
460 # Only check if the given size is the right one
461 context.Display('Checking %s is %d bytes... ' % (type_name, expect))
463 # test code taken from autoconf: this is a pretty clever hack to find that
464 # a type is of a given size using only compilation. This speeds things up
465 # quite a bit compared to straightforward code using TryRun
467 typedef %s scons_check_type;
471 static int test_array[1 - 2 * !(((long int) (sizeof(scons_check_type))) == %d)];
478 st = context.CompileProg(src % (type_name, expect), suffix)
480 context.Display("yes\n")
481 _Have(context, "SIZEOF_%s" % type_name, expect,
482 "The size of `%s', as computed by sizeof." % type_name)
485 context.Display("no\n")
486 _LogFailed(context, src, st)
489 # Only check if the given size is the right one
490 context.Message('Checking size of %s ... ' % type_name)
492 # We have to be careful with the program we wish to test here since
493 # compilation will be attempted using the current environment's flags.
494 # So make sure that the program will compile without any warning. For
495 # example using: 'int main(int argc, char** argv)' will fail with the
496 # '-Wall -Werror' flags since the variables argc and argv would not be
497 # used in the program...
503 printf("%d", (int)sizeof(""" + type_name + """));
507 st, out = context.RunProg(src, suffix)
511 # If cannot convert output of test prog to an integer (the size),
512 # something went wront, so just fail
517 context.Display("yes\n")
518 _Have(context, "SIZEOF_%s" % type_name, size,
519 "The size of `%s', as computed by sizeof." % type_name)
522 context.Display("no\n")
523 _LogFailed(context, src, st)
528 def CheckDeclaration(context, symbol, includes = None, language = None):
529 """Checks whether symbol is declared.
531 Use the same test as autoconf, that is test whether the symbol is defined
532 as a macro or can be used as an r-value.
538 Optional "header" can be defined to include a header file.
540 only C and C++ supported.
544 True if the check failed, False if succeeded."""
546 # Include "confdefs.h" first, so that the header can use HAVE_HEADER_H.
547 if context.headerfilename:
548 includetext = '#include "%s"' % context.headerfilename
555 lang, suffix, msg = _lang2suffix(language)
557 context.Display("Cannot check for declaration %s: %s\n" % (type_name, msg))
560 src = includetext + includes
561 context.Display('Checking whether %s is declared... ' % symbol)
572 """ % (symbol, symbol)
574 st = context.CompileProg(src, suffix)
575 _YesNoResult(context, st, "HAVE_DECL_" + symbol, src,
576 "Set to 1 if %s is defined." % symbol)
579 def CheckLib(context, libs, func_name = None, header = None,
580 extra_libs = None, call = None, language = None, autoadd = 1,
583 Configure check for a C or C++ libraries "libs". Searches through
584 the list of libraries, until one is found where the test succeeds.
585 Tests if "func_name" or "call" exists in the library. Note: if it exists
586 in another library the test succeeds anyway!
587 Optional "header" can be defined to include a header file. If not given a
588 default prototype for "func_name" is added.
589 Optional "extra_libs" is a list of library names to be added after
590 "lib_name" in the build command. To be used for libraries that "lib_name"
592 Optional "call" replaces the call to "func_name" in the test code. It must
593 consist of complete C statements, including a trailing ";".
594 Both "func_name" and "call" arguments are optional, and in that case, just
595 linking against the libs is tested.
596 "language" should be "C" or "C++" and is used to select the compiler.
598 Note that this uses the current value of compiler and linker flags, make
599 sure $CFLAGS, $CPPFLAGS and $LIBS are set correctly.
600 Returns an empty string for success, an error message for failure.
602 # Include "confdefs.h" first, so that the header can use HAVE_HEADER_H.
603 if context.headerfilename:
604 includetext = '#include "%s"' % context.headerfilename
612 %s""" % (includetext, header)
614 # Add a function declaration if needed.
615 if func_name and func_name != "main":
624 # The actual test code.
626 call = "%s();" % func_name
628 # if no function to test, leave main() blank
640 calltext = call[:i] + ".."
641 elif call[-1] == ';':
646 for lib_name in libs:
648 lang, suffix, msg = _lang2suffix(language)
650 context.Display("Cannot check for library %s: %s\n" % (lib_name, msg))
653 # if a function was specified to run in main(), say it
655 context.Display("Checking for %s in %s library %s... "
656 % (calltext, lang, lib_name))
657 # otherwise, just say the name of library and language
659 context.Display("Checking for %s library %s... "
667 oldLIBS = context.AppendLIBS(l)
669 oldLIBS = context.PrependLIBS(l)
670 sym = "HAVE_LIB" + lib_name
675 ret = context.BuildProg(text, suffix)
677 _YesNoResult(context, ret, sym, text,
678 "Define to 1 if you have the `%s' library." % lib_name)
679 if oldLIBS != -1 and (ret or not autoadd):
680 context.SetLIBS(oldLIBS)
688 # END OF PUBLIC FUNCTIONS
691 def _YesNoResult(context, ret, key, text, comment = None):
693 Handle the result of a test with a "yes" or "no" result.
694 "ret" is the return value: empty if OK, error message when not.
695 "key" is the name of the symbol to be defined (HAVE_foo).
696 "text" is the source code of the program used for testing.
697 "comment" is the C comment to add above the line defining the symbol (the
698 comment is automatically put inside a /* */). If None, no comment is added.
701 _Have(context, key, not ret, comment)
703 context.Display("no\n")
704 _LogFailed(context, text, ret)
706 context.Display("yes\n")
709 def _Have(context, key, have, comment = None):
711 Store result of a test in context.havedict and context.headerfilename.
712 "key" is a "HAVE_abc" name. It is turned into all CAPITALS and non-
713 alphanumerics are replaced by an underscore.
714 The value of "have" can be:
715 1 - Feature is defined, add "#define key".
716 0 - Feature is not defined, add "/* #undef key */".
717 Adding "undef" is what autoconf does. Not useful for the
718 compiler, but it shows that the test was done.
719 number - Feature is defined to this number "#define key have".
720 Doesn't work for 0 or 1, use a string then.
721 string - Feature is defined to this string "#define key have".
722 Give "have" as is should appear in the header file, include quotes
723 when desired and escape special characters!
726 key_up = re.sub('[^A-Z0-9_]', '_', key_up)
727 context.havedict[key_up] = have
729 line = "#define %s 1\n" % key_up
731 line = "/* #undef %s */\n" % key_up
732 elif isinstance(have, IntType):
733 line = "#define %s %d\n" % (key_up, have)
735 line = "#define %s %s\n" % (key_up, str(have))
737 if comment is not None:
738 lines = "\n/* %s */\n" % comment + line
742 if context.headerfilename:
743 f = open(context.headerfilename, "a")
746 elif hasattr(context,'config_h'):
747 context.config_h = context.config_h + lines
750 def _LogFailed(context, text, msg):
752 Write to the log about a failed program.
753 Add line numbers, so that error messages can be understood.
756 context.Log("Failed program was:\n")
757 lines = text.split('\n')
758 if len(lines) and lines[-1] == '':
759 lines = lines[:-1] # remove trailing empty line
762 context.Log("%d: %s\n" % (n, line))
765 context.Log("Error message: %s\n" % msg)
768 def _lang2suffix(lang):
770 Convert a language name to a suffix.
771 When "lang" is empty or None C is assumed.
772 Returns a tuple (lang, suffix, None) when it works.
773 For an unrecognized language returns (None, None, msg).
775 lang = the unified language name
776 suffix = the suffix, including the leading dot
777 msg = an error message
779 if not lang or lang in ["C", "c"]:
780 return ("C", ".c", None)
781 if lang in ["c++", "C++", "cpp", "CXX", "cxx"]:
782 return ("C++", ".cpp", None)
784 return None, None, "Unsupported language: %s" % lang
787 # vim: set sw=4 et sts=4 tw=79 fo+=l:
791 # indent-tabs-mode:nil
793 # vim: set expandtab tabstop=4 shiftwidth=4: