diff options
author | William Deegan <bill@baddogconsulting.com> | 2024-01-03 08:24:33 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-01-03 08:24:33 +0300 |
commit | fe942c4e71a3484568e56e9f8ba9a05ba1d91b5c (patch) | |
tree | ea2df122b0c0e9e3e82f75be9ba84f2d250a5102 | |
parent | 9b01a5ccf39e351bd08dd8c832afbed62db7d359 (diff) | |
parent | 812b6941a1a42d252d12c5b07457af5d08cce83a (diff) |
Merge pull request #4445 from jcbrill/jbrill-gh4320-fix
Fix 4320: add an optional argument list string to the configure CheckFunc method
-rw-r--r-- | CHANGES.txt | 5 | ||||
-rw-r--r-- | RELEASE.txt | 5 | ||||
-rw-r--r-- | SCons/Conftest.py | 15 | ||||
-rw-r--r-- | SCons/SConf.py | 4 | ||||
-rw-r--r-- | SCons/SConfTests.py | 17 | ||||
-rw-r--r-- | doc/man/scons.xml | 25 | ||||
-rw-r--r-- | test/Configure/config-h.py | 2 |
7 files changed, 52 insertions, 21 deletions
diff --git a/CHANGES.txt b/CHANGES.txt index 0d7f94b2d..48a0c38e9 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -13,6 +13,11 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER - Use of NotImplemented instead of NotImplementedError for special methods of _ListVariable class + From Joseph Brill: + - Fix issue #4320: add an optional argument list string to configure's CheckFunc + method so that the generated function argument list matches the function's + prototype when including a header file. + From William Deegan: - Fix sphinx config to handle SCons versions with post such as: 4.6.0.post1 diff --git a/RELEASE.txt b/RELEASE.txt index cdf694084..b84360c08 100644 --- a/RELEASE.txt +++ b/RELEASE.txt @@ -26,8 +26,9 @@ DEPRECATED FUNCTIONALITY CHANGED/ENHANCED EXISTING FUNCTIONALITY --------------------------------------- -- List modifications to existing features, where the previous behavior - wouldn't actually be considered a bug +- Add an optional argument list string to configure's CheckFunc method so + that the generated function argument list matches the function's + prototype when including a header file. Fixes GH Issue #4320 FIXES ----- diff --git a/SCons/Conftest.py b/SCons/Conftest.py index 6af5e7889..79ede9968 100644 --- a/SCons/Conftest.py +++ b/SCons/Conftest.py @@ -231,17 +231,22 @@ def _check_empty_program(context, comp, text, language, use_shared: bool = False return context.CompileProg(text, suffix) -def CheckFunc(context, function_name, header = None, language = None): +def CheckFunc(context, function_name, header = None, language = None, funcargs = 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(). + Optional "funcargs" can be defined to define an argument list for the + generated function invocation. 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. + + .. versionchanged:: 4.7.0 + The ``funcargs`` parameter was added. """ # Remarks from autoconf: @@ -274,6 +279,9 @@ char %s(void);""" % function_name context.Display("Cannot check for %s(): %s\n" % (function_name, msg)) return msg + if not funcargs: + funcargs = '' + text = """ %(include)s #include <assert.h> @@ -287,14 +295,15 @@ int main(void) { #if defined (__stub_%(name)s) || defined (__stub___%(name)s) #error "%(name)s has a GNU stub, cannot check" #else - %(name)s(); + %(name)s(%(args)s); #endif return 0; } """ % { 'name': function_name, 'include': includetext, - 'hdr': header } + 'hdr': header, + 'args': funcargs} context.Display("Checking for %s function %s()... " % (lang, function_name)) ret = context.BuildProg(text, suffix) diff --git a/SCons/SConf.py b/SCons/SConf.py index e522c8bb7..53666e63e 100644 --- a/SCons/SConf.py +++ b/SCons/SConf.py @@ -1002,8 +1002,8 @@ def SConf(*args, **kw): return SCons.Util.Null() -def CheckFunc(context, function_name, header = None, language = None) -> bool: - res = SCons.Conftest.CheckFunc(context, function_name, header = header, language = language) +def CheckFunc(context, function_name, header = None, language = None, funcargs = None) -> bool: + res = SCons.Conftest.CheckFunc(context, function_name, header = header, language = language, funcargs = funcargs) context.did_show_result = 1 return not res diff --git a/SCons/SConfTests.py b/SCons/SConfTests.py index 2903ba675..08ef25e79 100644 --- a/SCons/SConfTests.py +++ b/SCons/SConfTests.py @@ -671,11 +671,26 @@ int main(void) { log_file=self.test.workpath('config.log')) try: - # CheckFunc() + # look for function using default heading r = sconf.CheckFunc('strcpy') assert r, "did not find strcpy" + # no default heading, supply dummy signature r = sconf.CheckFunc('strcpy', '/* header */ char strcpy();') assert r, "did not find strcpy" + # ... supply complete signature, and function args + r = sconf.CheckFunc('strcpy', header='/* header */ char *strcpy(char *dest, char *src);', funcargs='"", ""') + # ... supply standard header for prototype, and function args + assert r, "did not find strcpy" + r = sconf.CheckFunc('strcpy', header='#include <string.h>', funcargs='"", ""') + # also try in C++ mode + cpp_header = """\ +#ifdef __cplusplus +extern "C" +#endif +char *strcpy(char *dest, char *src); +""" + r = sconf.CheckFunc('strcpy', header=cpp_header, funcargs='"", ""', language="C++") + assert r, "did not find strcpy" r = sconf.CheckFunc('hopefullynofunction') assert not r, "unexpectedly found hopefullynofunction" diff --git a/doc/man/scons.xml b/doc/man/scons.xml index aaebc2c27..22f93f5f7 100644 --- a/doc/man/scons.xml +++ b/doc/man/scons.xml @@ -3954,7 +3954,7 @@ Returns a boolean indicating success or failure.</para> </varlistentry> <varlistentry> - <term><replaceable>context</replaceable>.<methodname>CheckFunc</methodname>(<parameter>function_name, [header, language]</parameter>)</term> + <term><replaceable>context</replaceable>.<methodname>CheckFunc</methodname>(<parameter>function_name, [header, language, funcargs]</parameter>)</term> <listitem> <para>Checks if <parameter>function_name</parameter> is usable in the context's local environment, using the compiler @@ -3982,17 +3982,18 @@ char function_name(void); </programlisting> <para> -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. +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. If +this is not possible, the optional <parameter>funcargs</parameter> argument can be used +to specify a string containing an argument list with the same number and type of +arguments as the prototype. The arguments can simply be constant values of the correct +type. Modern C/C++ compilers reject implicit function declarations and may also reject +function calls whose arguments are not type compatible with the prototype. +</para> + +<para> +<emphasis>Changed in version 4.7.0: added the <parameter>funcargs</parameter>.</emphasis> </para> <para>Returns a boolean indicating success or failure.</para> diff --git a/test/Configure/config-h.py b/test/Configure/config-h.py index e5df6258f..aca18e42a 100644 --- a/test/Configure/config-h.py +++ b/test/Configure/config-h.py @@ -41,7 +41,7 @@ env = Environment() import os env.AppendENVPath('PATH', os.environ['PATH']) conf = Configure(env, config_h = 'config.h') -r1 = conf.CheckFunc('printf') +r1 = conf.CheckFunc('printf', header='#include <stdio.h>', funcargs='""') r2 = conf.CheckFunc('noFunctionCall') r3 = conf.CheckFunc('memmove') r4 = conf.CheckType('int') |