init
This commit is contained in:
812
scons-local-3.0.0/SCons/Conftest.py
Normal file
812
scons-local-3.0.0/SCons/Conftest.py
Normal file
@@ -0,0 +1,812 @@
|
||||
"""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
|
||||
|
||||
#
|
||||
# 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" % (symbol, 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
|
||||
|
||||
def CheckProg(context, prog_name):
|
||||
"""
|
||||
Configure check for a specific program.
|
||||
|
||||
Check whether program prog_name exists in path. If it is found,
|
||||
returns the path for it, otherwise returns None.
|
||||
"""
|
||||
context.Display("Checking whether %s program exists..." % prog_name)
|
||||
path = context.env.WhereIs(prog_name)
|
||||
if path:
|
||||
context.Display(path + "\n")
|
||||
else:
|
||||
context.Display("no\n")
|
||||
return path
|
||||
|
||||
|
||||
#
|
||||
# END OF PUBLIC FUNCTIONS
|
||||
#
|
||||
|
||||
def _YesNoResult(context, ret, key, text, comment = None):
|
||||
"""
|
||||
Handle the result of a test with a "yes" or "no" result.
|
||||
|
||||
:Parameters:
|
||||
- `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.
|
||||
|
||||
:Parameters:
|
||||
- `key` - is a "HAVE_abc" name. It is turned into all CAPITALS and non-alphanumerics are replaced by an underscore.
|
||||
- `have` - value as it should appear in the header file, include quotes when desired and escape special characters!
|
||||
- `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.
|
||||
|
||||
|
||||
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".
|
||||
|
||||
|
||||
"""
|
||||
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, int):
|
||||
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:
|
Reference in New Issue
Block a user