diff options
author | Mats Wichmann <mats@linux.com> | 2023-01-27 08:00:28 -0700 |
---|---|---|
committer | Mats Wichmann <mats@linux.com> | 2023-01-27 11:29:09 -0700 |
commit | 8aae133794ddeea09be2579d084ff87cd77b86f2 (patch) | |
tree | d56f17747c6b352d095c8a5701e9de63ee851b84 | |
parent | 04bc3eaab31c5437764b10ee942b19740b5139c9 (diff) | |
download | scons-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.txt | 3 | ||||
-rw-r--r-- | RELEASE.txt | 8 | ||||
-rw-r--r-- | SCons/Conftest.py | 10 | ||||
-rw-r--r-- | SCons/SConf.py | 24 | ||||
-rw-r--r-- | SCons/SConfTests.py | 81 | ||||
-rw-r--r-- | doc/man/scons.xml | 43 |
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> |