summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMats Wichmann <mats@linux.com>2023-01-27 08:00:28 -0700
committerMats Wichmann <mats@linux.com>2023-01-27 11:29:09 -0700
commit8aae133794ddeea09be2579d084ff87cd77b86f2 (patch)
treed56f17747c6b352d095c8a5701e9de63ee851b84
parent04bc3eaab31c5437764b10ee942b19740b5139c9 (diff)
downloadscons-git-8aae133794ddeea09be2579d084ff87cd77b86f2.tar.gz
Add unique kwarg to CheckLibs
Minor tweak to CheckFunc - the dummy prototype should have a dummy arg list too (comment from Python setuptools discussion). Might as well fail the official way: #error instead of C syntax error. Fixes #2768 Signed-off-by: Mats Wichmann <mats@linux.com>
-rw-r--r--CHANGES.txt3
-rw-r--r--RELEASE.txt8
-rw-r--r--SCons/Conftest.py10
-rw-r--r--SCons/SConf.py24
-rw-r--r--SCons/SConfTests.py81
-rw-r--r--doc/man/scons.xml43
6 files changed, 128 insertions, 41 deletions
diff --git a/CHANGES.txt b/CHANGES.txt
index 93be68dfd..f51f8b228 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -124,6 +124,9 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER
based on what is known now, 3.12 itself should work with this release.
- Add "append" keyword argument to Configure context's CheckLib and
CheckLibWithHeader to control whether to append or prepend (issue #2767)
+ Also added "unique" keyword, to control whether a library is added
+ or not if it is already in the $LIBS construction var in the
+ configure context. (issue #2768).
RELEASE 4.4.0 - Sat, 30 Jul 2022 14:08:29 -0700
diff --git a/RELEASE.txt b/RELEASE.txt
index 01bf63b12..b68432df3 100644
--- a/RELEASE.txt
+++ b/RELEASE.txt
@@ -46,9 +46,11 @@ CHANGED/ENHANCED EXISTING FUNCTIONALITY
- Preliminary support for Python 3.12.
- Run LaTeX after biber/bibtex only if necessary
- Configure context methods CheckLib and CheckLibWithHeader now expose
- an additional keyword argument 'append' which controls whether to append
- (the default) or prepend discovered libraries to $LIBS. The functionality
- was always present but prepending could not be requested via the offical API.
+ two additional keyword arguments: 'append', which controls whether to append
+ (the default) or prepend discovered libraries to $LIBS, and 'unique',
+ which controls whether to add the library if it is already in the $LIBS
+ list. This brings the library-adding functionality in Configure in line
+ with the regular Append, AppendUnique, Prepend and PrependUnique methods.
FIXES
diff --git a/SCons/Conftest.py b/SCons/Conftest.py
index 83175cb2c..3c52ef462 100644
--- a/SCons/Conftest.py
+++ b/SCons/Conftest.py
@@ -267,7 +267,7 @@ def CheckFunc(context, function_name, header = None, language = None):
#ifdef __cplusplus
extern "C"
#endif
-char %s();""" % function_name
+char %s(void);""" % function_name
lang, suffix, msg = _lang2suffix(language)
if msg:
@@ -285,7 +285,7 @@ char %s();""" % function_name
int main(void) {
#if defined (__stub_%(name)s) || defined (__stub___%(name)s)
- fail fail fail
+ #error "%(name)s has a GNU stub, cannot check"
#else
%(name)s();
#endif
@@ -627,7 +627,7 @@ int main(void) {
def CheckLib(context, libs, func_name = None, header = None,
extra_libs = None, call = None, language = None, autoadd = 1,
- append = True):
+ append=True, unique=False):
"""
Configure check for a C or C++ libraries "libs". Searches through
the list of libraries, until one is found where the test succeeds.
@@ -713,9 +713,9 @@ return 0;
if extra_libs:
l.extend(extra_libs)
if append:
- oldLIBS = context.AppendLIBS(l)
+ oldLIBS = context.AppendLIBS(l, unique)
else:
- oldLIBS = context.PrependLIBS(l)
+ oldLIBS = context.PrependLIBS(l, unique)
sym = "HAVE_LIB" + lib_name
else:
oldLIBS = -1
diff --git a/SCons/SConf.py b/SCons/SConf.py
index 051c14ce6..85edd3ab1 100644
--- a/SCons/SConf.py
+++ b/SCons/SConf.py
@@ -923,14 +923,20 @@ class CheckContext:
st, out = self.TryRun(text, ext)
return not st, out
- def AppendLIBS(self, lib_name_list):
+ def AppendLIBS(self, lib_name_list, unique=False):
oldLIBS = self.env.get( 'LIBS', [] )
- self.env.Append(LIBS = lib_name_list)
+ if unique:
+ self.env.AppendUnique(LIBS = lib_name_list)
+ else:
+ self.env.Append(LIBS = lib_name_list)
return oldLIBS
- def PrependLIBS(self, lib_name_list):
+ def PrependLIBS(self, lib_name_list, unique=False):
oldLIBS = self.env.get( 'LIBS', [] )
- self.env.Prepend(LIBS = lib_name_list)
+ if unique:
+ self.env.PrependUnique(LIBS = lib_name_list)
+ else:
+ self.env.Prepend(LIBS = lib_name_list)
return oldLIBS
def SetLIBS(self, val):
@@ -1067,7 +1073,8 @@ def CheckCXXHeader(context, header, include_quotes = '""'):
def CheckLib(context, library = None, symbol = "main",
- header = None, language = None, autoadd=True, append=True,) -> bool:
+ header = None, language = None, autoadd=True,
+ append=True, unique=False) -> bool:
"""
A test for a library. See also CheckLibWithHeader.
Note that library may also be None to test whether the given symbol
@@ -1083,7 +1090,7 @@ def CheckLib(context, library = None, symbol = "main",
# ToDo: accept path for the library
res = SCons.Conftest.CheckLib(context, library, symbol, header = header,
language = language, autoadd = autoadd,
- append=append)
+ append=append, unique=unique)
context.did_show_result = True
return not res
@@ -1091,7 +1098,7 @@ def CheckLib(context, library = None, symbol = "main",
# Bram: Can only include one header and can't use #ifdef HAVE_HEADER_H.
def CheckLibWithHeader(context, libs, header, language,
- call = None, autoadd=True, append=True) -> bool:
+ call = None, autoadd=True, append=True, unique=False) -> bool:
# ToDo: accept path for library. Support system header files.
"""
Another (more sophisticated) test for a library.
@@ -1108,7 +1115,8 @@ def CheckLibWithHeader(context, libs, header, language,
libs = [libs]
res = SCons.Conftest.CheckLib(context, libs, None, prog_prefix,
- call = call, language = language, autoadd=autoadd, append=append)
+ call = call, language = language, autoadd=autoadd,
+ append=append, unique=unique)
context.did_show_result = 1
return not res
diff --git a/SCons/SConfTests.py b/SCons/SConfTests.py
index 172fba75c..f0290e51c 100644
--- a/SCons/SConfTests.py
+++ b/SCons/SConfTests.py
@@ -32,6 +32,7 @@ import TestCmd
sys.stdout = io.StringIO()
+# a library that is sure to exist on the platform
if sys.platform == 'win32':
existing_lib = "msvcrt"
else:
@@ -78,9 +79,13 @@ class SConfTestCase(unittest.TestCase):
# - cygwin on Windows (using cmd.exe, not bash)
# - posix
# - msvc on Windows (hopefully)
- if (not self.scons_env.Detect( self.scons_env.subst('$CXX') ) or
- not self.scons_env.Detect( self.scons_env.subst('$CC') ) or
- not self.scons_env.Detect( self.scons_env.subst('$LINK') )):
+ if not all(
+ (
+ self.scons_env.Detect(self.scons_env.subst('$CXX')),
+ self.scons_env.Detect(self.scons_env.subst('$CC')),
+ self.scons_env.Detect(self.scons_env.subst('$LINK')),
+ )
+ ):
raise Exception("This test needs an installed compiler!")
if self.scons_env['CXX'] == 'g++':
global existing_lib
@@ -502,27 +507,59 @@ int main(void) {
r = sconf.CheckLib( ["hopefullynolib",existing_lib], "main", autoadd=0 )
assert r, "did not find %s " % existing_lib
- # CheckLib() with autoadd
def libs(env):
return env.get('LIBS', [])
- env = sconf.env.Clone()
-
+ # CheckLib() with combinations of autoadd, append
try:
- r = sconf.CheckLib( existing_lib, "main", autoadd=1 )
+ env = sconf.env.Clone()
+ r = sconf.CheckLib(existing_lib, "main", autoadd=True, append=True)
assert r, "did not find main in %s" % existing_lib
expect = libs(env) + [existing_lib]
got = libs(sconf.env)
assert got == expect, "LIBS: expected %s, got %s" % (expect, got)
+ env = sconf.env.Clone()
+ r = sconf.CheckLib(existing_lib, "main", autoadd=True, append=False)
+ assert r, "did not find main in %s" % existing_lib
+ expect = [existing_lib] + libs(env)
+ got = libs(sconf.env)
+ assert got == expect, "LIBS: expected %s, got %s" % (expect, got)
+
sconf.env = env.Clone()
- r = sconf.CheckLib( existing_lib, "main", autoadd=0 )
+ r = sconf.CheckLib(existing_lib, "main", autoadd=False)
assert r, "did not find main in %s" % existing_lib
expect = libs(env)
got = libs(sconf.env)
assert got == expect, "before and after LIBS were not the same"
finally:
sconf.env = env
+
+ # CheckLib() with unique
+ sconf.env.Append(LIBS=existing_lib)
+ try:
+ env = sconf.env.Clone()
+ r = sconf.CheckLib(
+ existing_lib, "main", autoadd=True, append=True, unique=False
+ )
+ assert r, f"did not find main in {existing_lib}"
+
+ expect = libs(env) + [existing_lib]
+ got = libs(sconf.env)
+ assert got == expect, f"LIBS: expected {expect}, got {got}"
+
+ env = sconf.env.Clone()
+ r = sconf.CheckLib(
+ existing_lib, "main", autoadd=True, append=True, unique=True
+ )
+ assert r, f"did not find main in {existing_lib}"
+
+ expect = libs(env)
+ got = libs(sconf.env)
+ assert got == expect, f"LIBS: expected {expect}, got {got}"
+ finally:
+ sconf.env = env
+
finally:
sconf.Finish()
@@ -565,13 +602,12 @@ int main(void) {
r = sconf.CheckLibWithHeader( [existing_lib,"hopefullynolib"], ["stdio.h", "math.h"], "C", autoadd=0 )
assert r, "did not find %s, #include stdio.h first" % existing_lib
- # CheckLibWithHeader with autoadd
def libs(env):
return env.get('LIBS', [])
- env = sconf.env.Clone()
-
+ # CheckLibWithHeader with combinations of autoadd, append
try:
+ env = sconf.env.Clone()
r = sconf.CheckLibWithHeader(
existing_lib, "math.h", "C", autoadd=True, append=True
)
@@ -600,6 +636,29 @@ int main(void) {
finally:
sconf.env = env
+ # CheckLibWithHeader() with unique
+ sconf.env.Append(LIBS=existing_lib)
+ try:
+ env = sconf.env.Clone()
+ r = sconf.CheckLibWithHeader(
+ existing_lib, "math.h", "C", autoadd=True, append=True, unique=False
+ )
+ assert r, f"did not find main in {existing_lib}"
+ expect = libs(env) + [existing_lib]
+ got = libs(sconf.env)
+ assert got == expect, f"LIBS: expected {expect}, got {got}"
+
+ env = sconf.env.Clone()
+ r = sconf.CheckLibWithHeader(
+ existing_lib, "math.h", "C", autoadd=True, append=True, unique=True
+ )
+ assert r, f"did not find main in {existing_lib}"
+ expect = libs(env)
+ got = libs(sconf.env)
+ assert got == expect, f"LIBS: expected {expect}, got {got}"
+ finally:
+ sconf.env = env
+
finally:
sconf.Finish()
diff --git a/doc/man/scons.xml b/doc/man/scons.xml
index 15270e2d9..e79a267d1 100644
--- a/doc/man/scons.xml
+++ b/doc/man/scons.xml
@@ -3892,7 +3892,7 @@ Returns a boolean indicating success or failure.</para>
<term><replaceable>context</replaceable>.<methodname>CheckFunc</methodname>(<parameter>function_name, [header, language]</parameter>)</term>
<listitem>
<para>Checks if <parameter>function_name</parameter> is usable
-in the context's local environment using the compiler
+in the context's local environment, using the compiler
specified by <parameter>language</parameter> - that is,
can a check referencing it be compiled using the current values
of &cv-link-CFLAGS;, &cv-link-CPPFLAGS;,
@@ -3913,17 +3913,21 @@ If omitted, the default stanza will be
#ifdef __cplusplus
extern "C"
#endif
-char function_name();
+char function_name(void);
</programlisting>
<para>
-Note: do not use <parameter>header</parameter>
-to include the standard header file that declares
-<parameter>function_name</parameter> - successful
-compilation of the test program depends on using
-a dummy prototype for it,
-to avoid probems with compilers which object to
-function signature mismatches.
+Note: if <parameter>header</parameter> is supplied,
+it should <emphasis>not</emphasis>
+include the standard header file that declares
+<parameter>function_name</parameter>,
+and it <emphasis>should</emphasis> include a
+dummy prototype similar to the default case.
+Compilers reject builds where a function call does
+not match the declared prototype as happens
+if the "real" header is included,
+and modern compilers are now rejecting
+implicit function declarations.
</para>
<para>Returns a boolean indicating success or failure.</para>
@@ -3931,7 +3935,7 @@ function signature mismatches.
</varlistentry>
<varlistentry>
- <term><replaceable>context</replaceable>.<methodname>CheckLib</methodname>(<parameter>[library, symbol, header, language, autoadd=True, append=True]</parameter>) </term>
+ <term><replaceable>context</replaceable>.<methodname>CheckLib</methodname>(<parameter>[library, symbol, header, language, autoadd=True, append=True, unique=False]</parameter>) </term>
<listitem>
<para>Checks if
<parameter>library</parameter>
@@ -3948,12 +3952,17 @@ linking the stub program),
it is added to the &cv-link-LIBS; &consvar; in the context.
if <parameter>append</parameter> is true (the default),
the library is appended, otherwise it is prepended.
+If <parameter>unique</parameter> is true,
+and the library would otherwise be added but is
+already present in &cv-link-LIBS; in the configure context,
+it will not be added again. The default is <literal>False</literal>.
</para>
<para>
<parameter>library</parameter> can be a list of library names,
or <constant>None</constant> (the default if the argument is omitted).
If the former, <parameter>symbol</parameter> is checked against
-each library name in order, returning on the first
+each library name in order, returning
+(and reporting success) on the first
successful test; if the latter,
it is checked with the current value of &cv-LIBS;
(in this case no library name would be added).
@@ -3973,13 +3982,14 @@ at least one should be supplied.
<para>Returns a boolean indicating success or failure.</para>
<para>
<emphasis>Changed in version 4.5.0: added the
-<parameter>append</parameter> parameter.</emphasis>
+<parameter>append</parameter> and <parameter>unique</parameter>
+parameters.</emphasis>
</para>
</listitem>
</varlistentry>
<varlistentry>
- <term><replaceable>context</replaceable>.<methodname>CheckLibWithHeader</methodname>(<parameter>library, header, [language, call, autoadd=True, append=True]</parameter>)</term>
+ <term><replaceable>context</replaceable>.<methodname>CheckLibWithHeader</methodname>(<parameter>library, header, [language, call, autoadd=True, append=True, unique=False]</parameter>)</term>
<listitem>
<para>Provides an alternative to the
@@ -4012,11 +4022,16 @@ is added to the &cv-link-LIBS; &consvar; in the context
and the method returns.
If <parameter>append</parameter> is true (the default),
the library is appended, otherwise prepended.
+If <parameter>unique</parameter> is true,
+and the library would otherwise be added but is
+already present in &cv-link-LIBS; in the configure context,
+it will not be added again. The default is <literal>False</literal>.
</para>
<para>Returns a boolean indicating success or failure.</para>
<para>
<emphasis>Changed in version 4.5.0: added the
-<parameter>append</parameter> parameter.</emphasis>
+<parameter>append</parameter> and <parameter>unique</parameter>
+parameters.</emphasis>
</para>
</listitem>
</varlistentry>