| Index: scons-2.0.1/engine/SCons/Conftest.py
|
| ===================================================================
|
| --- scons-2.0.1/engine/SCons/Conftest.py (revision 0)
|
| +++ scons-2.0.1/engine/SCons/Conftest.py (revision 0)
|
| @@ -0,0 +1,793 @@
|
| +"""SCons.Conftest
|
| +
|
| +Autoconf-like configuration support; low level implementation of tests.
|
| +"""
|
| +
|
| +#
|
| +# Copyright (c) 2003 Stichting NLnet Labs
|
| +# Copyright (c) 2001, 2002, 2003 Steven Knight
|
| +#
|
| +# Permission is hereby granted, free of charge, to any person obtaining
|
| +# a copy of this software and associated documentation files (the
|
| +# "Software"), to deal in the Software without restriction, including
|
| +# without limitation the rights to use, copy, modify, merge, publish,
|
| +# distribute, sublicense, and/or sell copies of the Software, and to
|
| +# permit persons to whom the Software is furnished to do so, subject to
|
| +# the following conditions:
|
| +#
|
| +# The above copyright notice and this permission notice shall be included
|
| +# in all copies or substantial portions of the Software.
|
| +#
|
| +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
|
| +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
| +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
| +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
| +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
| +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
| +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
| +#
|
| +
|
| +#
|
| +# The purpose of this module is to define how a check is to be performed.
|
| +# Use one of the Check...() functions below.
|
| +#
|
| +
|
| +#
|
| +# A context class is used that defines functions for carrying out the tests,
|
| +# logging and messages. The following methods and members must be present:
|
| +#
|
| +# context.Display(msg) Function called to print messages that are normally
|
| +# displayed for the user. Newlines are explicitly used.
|
| +# The text should also be written to the logfile!
|
| +#
|
| +# context.Log(msg) Function called to write to a log file.
|
| +#
|
| +# context.BuildProg(text, ext)
|
| +# Function called to build a program, using "ext" for the
|
| +# file extention. Must return an empty string for
|
| +# success, an error message for failure.
|
| +# For reliable test results building should be done just
|
| +# like an actual program would be build, using the same
|
| +# command and arguments (including configure results so
|
| +# far).
|
| +#
|
| +# context.CompileProg(text, ext)
|
| +# Function called to compile a program, using "ext" for
|
| +# the file extention. Must return an empty string for
|
| +# success, an error message for failure.
|
| +# For reliable test results compiling should be done just
|
| +# like an actual source file would be compiled, using the
|
| +# same command and arguments (including configure results
|
| +# so far).
|
| +#
|
| +# context.AppendLIBS(lib_name_list)
|
| +# Append "lib_name_list" to the value of LIBS.
|
| +# "lib_namelist" is a list of strings.
|
| +# Return the value of LIBS before changing it (any type
|
| +# can be used, it is passed to SetLIBS() later.)
|
| +#
|
| +# context.PrependLIBS(lib_name_list)
|
| +# Prepend "lib_name_list" to the value of LIBS.
|
| +# "lib_namelist" is a list of strings.
|
| +# Return the value of LIBS before changing it (any type
|
| +# can be used, it is passed to SetLIBS() later.)
|
| +#
|
| +# context.SetLIBS(value)
|
| +# Set LIBS to "value". The type of "value" is what
|
| +# AppendLIBS() returned.
|
| +# Return the value of LIBS before changing it (any type
|
| +# can be used, it is passed to SetLIBS() later.)
|
| +#
|
| +# context.headerfilename
|
| +# Name of file to append configure results to, usually
|
| +# "confdefs.h".
|
| +# The file must not exist or be empty when starting.
|
| +# Empty or None to skip this (some tests will not work!).
|
| +#
|
| +# context.config_h (may be missing). If present, must be a string, which
|
| +# will be filled with the contents of a config_h file.
|
| +#
|
| +# context.vardict Dictionary holding variables used for the tests and
|
| +# stores results from the tests, used for the build
|
| +# commands.
|
| +# Normally contains "CC", "LIBS", "CPPFLAGS", etc.
|
| +#
|
| +# context.havedict Dictionary holding results from the tests that are to
|
| +# be used inside a program.
|
| +# Names often start with "HAVE_". These are zero
|
| +# (feature not present) or one (feature present). Other
|
| +# variables may have any value, e.g., "PERLVERSION" can
|
| +# be a number and "SYSTEMNAME" a string.
|
| +#
|
| +
|
| +import re
|
| +from types import IntType
|
| +
|
| +#
|
| +# PUBLIC VARIABLES
|
| +#
|
| +
|
| +LogInputFiles = 1 # Set that to log the input files in case of a failed test
|
| +LogErrorMessages = 1 # Set that to log Conftest-generated error messages
|
| +
|
| +#
|
| +# PUBLIC FUNCTIONS
|
| +#
|
| +
|
| +# Generic remarks:
|
| +# - When a language is specified which is not supported the test fails. The
|
| +# message is a bit different, because not all the arguments for the normal
|
| +# message are available yet (chicken-egg problem).
|
| +
|
| +
|
| +def CheckBuilder(context, text = None, language = None):
|
| + """
|
| + Configure check to see if the compiler works.
|
| + Note that this uses the current value of compiler and linker flags, make
|
| + sure $CFLAGS, $CPPFLAGS and $LIBS are set correctly.
|
| + "language" should be "C" or "C++" and is used to select the compiler.
|
| + Default is "C".
|
| + "text" may be used to specify the code to be build.
|
| + Returns an empty string for success, an error message for failure.
|
| + """
|
| + lang, suffix, msg = _lang2suffix(language)
|
| + if msg:
|
| + context.Display("%s\n" % msg)
|
| + return msg
|
| +
|
| + if not text:
|
| + text = """
|
| +int main() {
|
| + return 0;
|
| +}
|
| +"""
|
| +
|
| + context.Display("Checking if building a %s file works... " % lang)
|
| + ret = context.BuildProg(text, suffix)
|
| + _YesNoResult(context, ret, None, text)
|
| + return ret
|
| +
|
| +def CheckCC(context):
|
| + """
|
| + Configure check for a working C compiler.
|
| +
|
| + This checks whether the C compiler, as defined in the $CC construction
|
| + variable, can compile a C source file. It uses the current $CCCOM value
|
| + too, so that it can test against non working flags.
|
| +
|
| + """
|
| + context.Display("Checking whether the C compiler works")
|
| + text = """
|
| +int main()
|
| +{
|
| + return 0;
|
| +}
|
| +"""
|
| + ret = _check_empty_program(context, 'CC', text, 'C')
|
| + _YesNoResult(context, ret, None, text)
|
| + return ret
|
| +
|
| +def CheckSHCC(context):
|
| + """
|
| + Configure check for a working shared C compiler.
|
| +
|
| + This checks whether the C compiler, as defined in the $SHCC construction
|
| + variable, can compile a C source file. It uses the current $SHCCCOM value
|
| + too, so that it can test against non working flags.
|
| +
|
| + """
|
| + context.Display("Checking whether the (shared) C compiler works")
|
| + text = """
|
| +int foo()
|
| +{
|
| + return 0;
|
| +}
|
| +"""
|
| + ret = _check_empty_program(context, 'SHCC', text, 'C', use_shared = True)
|
| + _YesNoResult(context, ret, None, text)
|
| + return ret
|
| +
|
| +def CheckCXX(context):
|
| + """
|
| + Configure check for a working CXX compiler.
|
| +
|
| + This checks whether the CXX compiler, as defined in the $CXX construction
|
| + variable, can compile a CXX source file. It uses the current $CXXCOM value
|
| + too, so that it can test against non working flags.
|
| +
|
| + """
|
| + context.Display("Checking whether the C++ compiler works")
|
| + text = """
|
| +int main()
|
| +{
|
| + return 0;
|
| +}
|
| +"""
|
| + ret = _check_empty_program(context, 'CXX', text, 'C++')
|
| + _YesNoResult(context, ret, None, text)
|
| + return ret
|
| +
|
| +def CheckSHCXX(context):
|
| + """
|
| + Configure check for a working shared CXX compiler.
|
| +
|
| + This checks whether the CXX compiler, as defined in the $SHCXX construction
|
| + variable, can compile a CXX source file. It uses the current $SHCXXCOM value
|
| + too, so that it can test against non working flags.
|
| +
|
| + """
|
| + context.Display("Checking whether the (shared) C++ compiler works")
|
| + text = """
|
| +int main()
|
| +{
|
| + return 0;
|
| +}
|
| +"""
|
| + ret = _check_empty_program(context, 'SHCXX', text, 'C++', use_shared = True)
|
| + _YesNoResult(context, ret, None, text)
|
| + return ret
|
| +
|
| +def _check_empty_program(context, comp, text, language, use_shared = False):
|
| + """Return 0 on success, 1 otherwise."""
|
| + if comp not in context.env or not context.env[comp]:
|
| + # The compiler construction variable is not set or empty
|
| + return 1
|
| +
|
| + lang, suffix, msg = _lang2suffix(language)
|
| + if msg:
|
| + return 1
|
| +
|
| + if use_shared:
|
| + return context.CompileSharedObject(text, suffix)
|
| + else:
|
| + return context.CompileProg(text, suffix)
|
| +
|
| +
|
| +def CheckFunc(context, function_name, header = None, language = None):
|
| + """
|
| + Configure check for a function "function_name".
|
| + "language" should be "C" or "C++" and is used to select the compiler.
|
| + Default is "C".
|
| + Optional "header" can be defined to define a function prototype, include a
|
| + header file or anything else that comes before main().
|
| + Sets HAVE_function_name in context.havedict according to the result.
|
| + Note that this uses the current value of compiler and linker flags, make
|
| + sure $CFLAGS, $CPPFLAGS and $LIBS are set correctly.
|
| + Returns an empty string for success, an error message for failure.
|
| + """
|
| +
|
| + # Remarks from autoconf:
|
| + # - Don't include <ctype.h> because on OSF/1 3.0 it includes <sys/types.h>
|
| + # which includes <sys/select.h> which contains a prototype for select.
|
| + # Similarly for bzero.
|
| + # - assert.h is included to define __stub macros and hopefully few
|
| + # prototypes, which can conflict with char $1(); below.
|
| + # - Override any gcc2 internal prototype to avoid an error.
|
| + # - We use char for the function declaration because int might match the
|
| + # return type of a gcc2 builtin and then its argument prototype would
|
| + # still apply.
|
| + # - The GNU C library defines this for functions which it implements to
|
| + # always fail with ENOSYS. Some functions are actually named something
|
| + # starting with __ and the normal name is an alias.
|
| +
|
| + if context.headerfilename:
|
| + includetext = '#include "%s"' % context.headerfilename
|
| + else:
|
| + includetext = ''
|
| + if not header:
|
| + header = """
|
| +#ifdef __cplusplus
|
| +extern "C"
|
| +#endif
|
| +char %s();""" % function_name
|
| +
|
| + lang, suffix, msg = _lang2suffix(language)
|
| + if msg:
|
| + context.Display("Cannot check for %s(): %s\n" % (function_name, msg))
|
| + return msg
|
| +
|
| + text = """
|
| +%(include)s
|
| +#include <assert.h>
|
| +%(hdr)s
|
| +
|
| +int main() {
|
| +#if defined (__stub_%(name)s) || defined (__stub___%(name)s)
|
| + fail fail fail
|
| +#else
|
| + %(name)s();
|
| +#endif
|
| +
|
| + return 0;
|
| +}
|
| +""" % { 'name': function_name,
|
| + 'include': includetext,
|
| + 'hdr': header }
|
| +
|
| + context.Display("Checking for %s function %s()... " % (lang, function_name))
|
| + ret = context.BuildProg(text, suffix)
|
| + _YesNoResult(context, ret, "HAVE_" + function_name, text,
|
| + "Define to 1 if the system has the function `%s'." %\
|
| + function_name)
|
| + return ret
|
| +
|
| +
|
| +def CheckHeader(context, header_name, header = None, language = None,
|
| + include_quotes = None):
|
| + """
|
| + Configure check for a C or C++ header file "header_name".
|
| + Optional "header" can be defined to do something before including the
|
| + header file (unusual, supported for consistency).
|
| + "language" should be "C" or "C++" and is used to select the compiler.
|
| + Default is "C".
|
| + Sets HAVE_header_name in context.havedict according to the result.
|
| + Note that this uses the current value of compiler and linker flags, make
|
| + sure $CFLAGS and $CPPFLAGS are set correctly.
|
| + Returns an empty string for success, an error message for failure.
|
| + """
|
| + # Why compile the program instead of just running the preprocessor?
|
| + # It is possible that the header file exists, but actually using it may
|
| + # fail (e.g., because it depends on other header files). Thus this test is
|
| + # more strict. It may require using the "header" argument.
|
| + #
|
| + # Use <> by default, because the check is normally used for system header
|
| + # files. SCons passes '""' to overrule this.
|
| +
|
| + # Include "confdefs.h" first, so that the header can use HAVE_HEADER_H.
|
| + if context.headerfilename:
|
| + includetext = '#include "%s"\n' % context.headerfilename
|
| + else:
|
| + includetext = ''
|
| + if not header:
|
| + header = ""
|
| +
|
| + lang, suffix, msg = _lang2suffix(language)
|
| + if msg:
|
| + context.Display("Cannot check for header file %s: %s\n"
|
| + % (header_name, msg))
|
| + return msg
|
| +
|
| + if not include_quotes:
|
| + include_quotes = "<>"
|
| +
|
| + text = "%s%s\n#include %s%s%s\n\n" % (includetext, header,
|
| + include_quotes[0], header_name, include_quotes[1])
|
| +
|
| + context.Display("Checking for %s header file %s... " % (lang, header_name))
|
| + ret = context.CompileProg(text, suffix)
|
| + _YesNoResult(context, ret, "HAVE_" + header_name, text,
|
| + "Define to 1 if you have the <%s> header file." % header_name)
|
| + return ret
|
| +
|
| +
|
| +def CheckType(context, type_name, fallback = None,
|
| + header = None, language = None):
|
| + """
|
| + Configure check for a C or C++ type "type_name".
|
| + Optional "header" can be defined to include a header file.
|
| + "language" should be "C" or "C++" and is used to select the compiler.
|
| + Default is "C".
|
| + Sets HAVE_type_name in context.havedict according to the result.
|
| + Note that this uses the current value of compiler and linker flags, make
|
| + sure $CFLAGS, $CPPFLAGS and $LIBS are set correctly.
|
| + Returns an empty string for success, an error message for failure.
|
| + """
|
| +
|
| + # Include "confdefs.h" first, so that the header can use HAVE_HEADER_H.
|
| + if context.headerfilename:
|
| + includetext = '#include "%s"' % context.headerfilename
|
| + else:
|
| + includetext = ''
|
| + if not header:
|
| + header = ""
|
| +
|
| + lang, suffix, msg = _lang2suffix(language)
|
| + if msg:
|
| + context.Display("Cannot check for %s type: %s\n" % (type_name, msg))
|
| + return msg
|
| +
|
| + # Remarks from autoconf about this test:
|
| + # - Grepping for the type in include files is not reliable (grep isn't
|
| + # portable anyway).
|
| + # - Using "TYPE my_var;" doesn't work for const qualified types in C++.
|
| + # Adding an initializer is not valid for some C++ classes.
|
| + # - Using the type as parameter to a function either fails for K&$ C or for
|
| + # C++.
|
| + # - Using "TYPE *my_var;" is valid in C for some types that are not
|
| + # declared (struct something).
|
| + # - Using "sizeof(TYPE)" is valid when TYPE is actually a variable.
|
| + # - Using the previous two together works reliably.
|
| + text = """
|
| +%(include)s
|
| +%(header)s
|
| +
|
| +int main() {
|
| + if ((%(name)s *) 0)
|
| + return 0;
|
| + if (sizeof (%(name)s))
|
| + return 0;
|
| +}
|
| +""" % { 'include': includetext,
|
| + 'header': header,
|
| + 'name': type_name }
|
| +
|
| + context.Display("Checking for %s type %s... " % (lang, type_name))
|
| + ret = context.BuildProg(text, suffix)
|
| + _YesNoResult(context, ret, "HAVE_" + type_name, text,
|
| + "Define to 1 if the system has the type `%s'." % type_name)
|
| + if ret and fallback and context.headerfilename:
|
| + f = open(context.headerfilename, "a")
|
| + f.write("typedef %s %s;\n" % (fallback, type_name))
|
| + f.close()
|
| +
|
| + return ret
|
| +
|
| +def CheckTypeSize(context, type_name, header = None, language = None, expect = None):
|
| + """This check can be used to get the size of a given type, or to check whether
|
| + the type is of expected size.
|
| +
|
| + Arguments:
|
| + - type : str
|
| + the type to check
|
| + - includes : sequence
|
| + list of headers to include in the test code before testing the type
|
| + - language : str
|
| + 'C' or 'C++'
|
| + - expect : int
|
| + if given, will test wether the type has the given number of bytes.
|
| + If not given, will automatically find the size.
|
| +
|
| + Returns:
|
| + status : int
|
| + 0 if the check failed, or the found size of the type if the check succeeded."""
|
| +
|
| + # Include "confdefs.h" first, so that the header can use HAVE_HEADER_H.
|
| + if context.headerfilename:
|
| + includetext = '#include "%s"' % context.headerfilename
|
| + else:
|
| + includetext = ''
|
| +
|
| + if not header:
|
| + header = ""
|
| +
|
| + lang, suffix, msg = _lang2suffix(language)
|
| + if msg:
|
| + context.Display("Cannot check for %s type: %s\n" % (type_name, msg))
|
| + return msg
|
| +
|
| + src = includetext + header
|
| + if not expect is None:
|
| + # Only check if the given size is the right one
|
| + context.Display('Checking %s is %d bytes... ' % (type_name, expect))
|
| +
|
| + # test code taken from autoconf: this is a pretty clever hack to find that
|
| + # a type is of a given size using only compilation. This speeds things up
|
| + # quite a bit compared to straightforward code using TryRun
|
| + src = src + r"""
|
| +typedef %s scons_check_type;
|
| +
|
| +int main()
|
| +{
|
| + static int test_array[1 - 2 * !(((long int) (sizeof(scons_check_type))) == %d)];
|
| + test_array[0] = 0;
|
| +
|
| + return 0;
|
| +}
|
| +"""
|
| +
|
| + st = context.CompileProg(src % (type_name, expect), suffix)
|
| + if not st:
|
| + context.Display("yes\n")
|
| + _Have(context, "SIZEOF_%s" % type_name, expect,
|
| + "The size of `%s', as computed by sizeof." % type_name)
|
| + return expect
|
| + else:
|
| + context.Display("no\n")
|
| + _LogFailed(context, src, st)
|
| + return 0
|
| + else:
|
| + # Only check if the given size is the right one
|
| + context.Message('Checking size of %s ... ' % type_name)
|
| +
|
| + # We have to be careful with the program we wish to test here since
|
| + # compilation will be attempted using the current environment's flags.
|
| + # So make sure that the program will compile without any warning. For
|
| + # example using: 'int main(int argc, char** argv)' will fail with the
|
| + # '-Wall -Werror' flags since the variables argc and argv would not be
|
| + # used in the program...
|
| + #
|
| + src = src + """
|
| +#include <stdlib.h>
|
| +#include <stdio.h>
|
| +int main() {
|
| + printf("%d", (int)sizeof(""" + type_name + """));
|
| + return 0;
|
| +}
|
| + """
|
| + st, out = context.RunProg(src, suffix)
|
| + try:
|
| + size = int(out)
|
| + except ValueError:
|
| + # If cannot convert output of test prog to an integer (the size),
|
| + # something went wront, so just fail
|
| + st = 1
|
| + size = 0
|
| +
|
| + if not st:
|
| + context.Display("yes\n")
|
| + _Have(context, "SIZEOF_%s" % type_name, size,
|
| + "The size of `%s', as computed by sizeof." % type_name)
|
| + return size
|
| + else:
|
| + context.Display("no\n")
|
| + _LogFailed(context, src, st)
|
| + return 0
|
| +
|
| + return 0
|
| +
|
| +def CheckDeclaration(context, symbol, includes = None, language = None):
|
| + """Checks whether symbol is declared.
|
| +
|
| + Use the same test as autoconf, that is test whether the symbol is defined
|
| + as a macro or can be used as an r-value.
|
| +
|
| + Arguments:
|
| + symbol : str
|
| + the symbol to check
|
| + includes : str
|
| + Optional "header" can be defined to include a header file.
|
| + language : str
|
| + only C and C++ supported.
|
| +
|
| + Returns:
|
| + status : bool
|
| + True if the check failed, False if succeeded."""
|
| +
|
| + # Include "confdefs.h" first, so that the header can use HAVE_HEADER_H.
|
| + if context.headerfilename:
|
| + includetext = '#include "%s"' % context.headerfilename
|
| + else:
|
| + includetext = ''
|
| +
|
| + if not includes:
|
| + includes = ""
|
| +
|
| + lang, suffix, msg = _lang2suffix(language)
|
| + if msg:
|
| + context.Display("Cannot check for declaration %s: %s\n" % (type_name, msg))
|
| + return msg
|
| +
|
| + src = includetext + includes
|
| + context.Display('Checking whether %s is declared... ' % symbol)
|
| +
|
| + src = src + r"""
|
| +int main()
|
| +{
|
| +#ifndef %s
|
| + (void) %s;
|
| +#endif
|
| + ;
|
| + return 0;
|
| +}
|
| +""" % (symbol, symbol)
|
| +
|
| + st = context.CompileProg(src, suffix)
|
| + _YesNoResult(context, st, "HAVE_DECL_" + symbol, src,
|
| + "Set to 1 if %s is defined." % symbol)
|
| + return st
|
| +
|
| +def CheckLib(context, libs, func_name = None, header = None,
|
| + extra_libs = None, call = None, language = None, autoadd = 1,
|
| + append = True):
|
| + """
|
| + Configure check for a C or C++ libraries "libs". Searches through
|
| + the list of libraries, until one is found where the test succeeds.
|
| + Tests if "func_name" or "call" exists in the library. Note: if it exists
|
| + in another library the test succeeds anyway!
|
| + Optional "header" can be defined to include a header file. If not given a
|
| + default prototype for "func_name" is added.
|
| + Optional "extra_libs" is a list of library names to be added after
|
| + "lib_name" in the build command. To be used for libraries that "lib_name"
|
| + depends on.
|
| + Optional "call" replaces the call to "func_name" in the test code. It must
|
| + consist of complete C statements, including a trailing ";".
|
| + Both "func_name" and "call" arguments are optional, and in that case, just
|
| + linking against the libs is tested.
|
| + "language" should be "C" or "C++" and is used to select the compiler.
|
| + Default is "C".
|
| + Note that this uses the current value of compiler and linker flags, make
|
| + sure $CFLAGS, $CPPFLAGS and $LIBS are set correctly.
|
| + Returns an empty string for success, an error message for failure.
|
| + """
|
| + # Include "confdefs.h" first, so that the header can use HAVE_HEADER_H.
|
| + if context.headerfilename:
|
| + includetext = '#include "%s"' % context.headerfilename
|
| + else:
|
| + includetext = ''
|
| + if not header:
|
| + header = ""
|
| +
|
| + text = """
|
| +%s
|
| +%s""" % (includetext, header)
|
| +
|
| + # Add a function declaration if needed.
|
| + if func_name and func_name != "main":
|
| + if not header:
|
| + text = text + """
|
| +#ifdef __cplusplus
|
| +extern "C"
|
| +#endif
|
| +char %s();
|
| +""" % func_name
|
| +
|
| + # The actual test code.
|
| + if not call:
|
| + call = "%s();" % func_name
|
| +
|
| + # if no function to test, leave main() blank
|
| + text = text + """
|
| +int
|
| +main() {
|
| + %s
|
| +return 0;
|
| +}
|
| +""" % (call or "")
|
| +
|
| + if call:
|
| + i = call.find("\n")
|
| + if i > 0:
|
| + calltext = call[:i] + ".."
|
| + elif call[-1] == ';':
|
| + calltext = call[:-1]
|
| + else:
|
| + calltext = call
|
| +
|
| + for lib_name in libs:
|
| +
|
| + lang, suffix, msg = _lang2suffix(language)
|
| + if msg:
|
| + context.Display("Cannot check for library %s: %s\n" % (lib_name, msg))
|
| + return msg
|
| +
|
| + # if a function was specified to run in main(), say it
|
| + if call:
|
| + context.Display("Checking for %s in %s library %s... "
|
| + % (calltext, lang, lib_name))
|
| + # otherwise, just say the name of library and language
|
| + else:
|
| + context.Display("Checking for %s library %s... "
|
| + % (lang, lib_name))
|
| +
|
| + if lib_name:
|
| + l = [ lib_name ]
|
| + if extra_libs:
|
| + l.extend(extra_libs)
|
| + if append:
|
| + oldLIBS = context.AppendLIBS(l)
|
| + else:
|
| + oldLIBS = context.PrependLIBS(l)
|
| + sym = "HAVE_LIB" + lib_name
|
| + else:
|
| + oldLIBS = -1
|
| + sym = None
|
| +
|
| + ret = context.BuildProg(text, suffix)
|
| +
|
| + _YesNoResult(context, ret, sym, text,
|
| + "Define to 1 if you have the `%s' library." % lib_name)
|
| + if oldLIBS != -1 and (ret or not autoadd):
|
| + context.SetLIBS(oldLIBS)
|
| +
|
| + if not ret:
|
| + return ret
|
| +
|
| + return ret
|
| +
|
| +#
|
| +# END OF PUBLIC FUNCTIONS
|
| +#
|
| +
|
| +def _YesNoResult(context, ret, key, text, comment = None):
|
| + """
|
| + Handle the result of a test with a "yes" or "no" result.
|
| + "ret" is the return value: empty if OK, error message when not.
|
| + "key" is the name of the symbol to be defined (HAVE_foo).
|
| + "text" is the source code of the program used for testing.
|
| + "comment" is the C comment to add above the line defining the symbol (the
|
| + comment is automatically put inside a /* */). If None, no comment is added.
|
| + """
|
| + if key:
|
| + _Have(context, key, not ret, comment)
|
| + if ret:
|
| + context.Display("no\n")
|
| + _LogFailed(context, text, ret)
|
| + else:
|
| + context.Display("yes\n")
|
| +
|
| +
|
| +def _Have(context, key, have, comment = None):
|
| + """
|
| + Store result of a test in context.havedict and context.headerfilename.
|
| + "key" is a "HAVE_abc" name. It is turned into all CAPITALS and non-
|
| + alphanumerics are replaced by an underscore.
|
| + The value of "have" can be:
|
| + 1 - Feature is defined, add "#define key".
|
| + 0 - Feature is not defined, add "/* #undef key */".
|
| + Adding "undef" is what autoconf does. Not useful for the
|
| + compiler, but it shows that the test was done.
|
| + number - Feature is defined to this number "#define key have".
|
| + Doesn't work for 0 or 1, use a string then.
|
| + string - Feature is defined to this string "#define key have".
|
| + Give "have" as is should appear in the header file, include quotes
|
| + when desired and escape special characters!
|
| + """
|
| + key_up = key.upper()
|
| + key_up = re.sub('[^A-Z0-9_]', '_', key_up)
|
| + context.havedict[key_up] = have
|
| + if have == 1:
|
| + line = "#define %s 1\n" % key_up
|
| + elif have == 0:
|
| + line = "/* #undef %s */\n" % key_up
|
| + elif isinstance(have, IntType):
|
| + line = "#define %s %d\n" % (key_up, have)
|
| + else:
|
| + line = "#define %s %s\n" % (key_up, str(have))
|
| +
|
| + if comment is not None:
|
| + lines = "\n/* %s */\n" % comment + line
|
| + else:
|
| + lines = "\n" + line
|
| +
|
| + if context.headerfilename:
|
| + f = open(context.headerfilename, "a")
|
| + f.write(lines)
|
| + f.close()
|
| + elif hasattr(context,'config_h'):
|
| + context.config_h = context.config_h + lines
|
| +
|
| +
|
| +def _LogFailed(context, text, msg):
|
| + """
|
| + Write to the log about a failed program.
|
| + Add line numbers, so that error messages can be understood.
|
| + """
|
| + if LogInputFiles:
|
| + context.Log("Failed program was:\n")
|
| + lines = text.split('\n')
|
| + if len(lines) and lines[-1] == '':
|
| + lines = lines[:-1] # remove trailing empty line
|
| + n = 1
|
| + for line in lines:
|
| + context.Log("%d: %s\n" % (n, line))
|
| + n = n + 1
|
| + if LogErrorMessages:
|
| + context.Log("Error message: %s\n" % msg)
|
| +
|
| +
|
| +def _lang2suffix(lang):
|
| + """
|
| + Convert a language name to a suffix.
|
| + When "lang" is empty or None C is assumed.
|
| + Returns a tuple (lang, suffix, None) when it works.
|
| + For an unrecognized language returns (None, None, msg).
|
| + Where:
|
| + lang = the unified language name
|
| + suffix = the suffix, including the leading dot
|
| + msg = an error message
|
| + """
|
| + if not lang or lang in ["C", "c"]:
|
| + return ("C", ".c", None)
|
| + if lang in ["c++", "C++", "cpp", "CXX", "cxx"]:
|
| + return ("C++", ".cpp", None)
|
| +
|
| + return None, None, "Unsupported language: %s" % lang
|
| +
|
| +
|
| +# vim: set sw=4 et sts=4 tw=79 fo+=l:
|
| +
|
| +# Local Variables:
|
| +# tab-width:4
|
| +# indent-tabs-mode:nil
|
| +# End:
|
| +# vim: set expandtab tabstop=4 shiftwidth=4:
|
|
|
| Property changes on: scons-2.0.1/engine/SCons/Conftest.py
|
| ___________________________________________________________________
|
| Added: svn:eol-style
|
| + LF
|
|
|
|
|