-
-
Notifications
You must be signed in to change notification settings - Fork 321
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix 4320: add an optional argument list string to the configure CheckFunc method #4445
Conversation
…Func method. Add an optional argument list string so the generated function argument list matches the function's prototype when including a header file.
@mwichmann documentation note fragment from #4320
Tests
|
Ideally we'd add a test which actually populates funcargs. Also the docs for CheckFunc() will need to be updated. |
ah... moving slowly here. I thought this already existed, just wasn't being called. |
This was added to SConfTests.py which changes the prototype and populates funcargs:
|
Nope. Just trying to sneak a simple solution under the radar. |
empty string funcargs != populates IMHO.. ;) |
|
ok. Needs doc update, CHANGES, RELEASE updates. Then it should be mergable. |
I've added a blurb for CHANGES.txt, RELEASE.txt and updated the manpage entry for CheckFunc() |
doc/man/scons.xml
Outdated
@@ -3974,6 +3974,11 @@ If omitted, the default stanza will be | |||
(with <parameter>function_name</parameter> appropriately substituted): | |||
</para> | |||
|
|||
<para> | |||
The optional <parameter>funcargs</parameter> can be defined to specify an argument list for the generated |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This addition should go after the existing example (and maybe wants its own example?). Also notice that further down it basically says "don't do that" about what this change is enabling (that is, including a standard header). We'll want to think about what that should say now. Also include a version notice.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated text. Please take another pass at this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not seeing anything different. Is github interface messing up again?
…e now obsolete note about function prototype
The test case was modified to do exactly what the documentation note says should not be done with the header argument:
With modern compilers/preprocessors (inline function declarations, rewritting/remapping declarations), I'm not sure how the stupid simple case for "printf" could be resolved without including the actual header. The symbol for "printf" is only exported for one target platform (amd64). However, the source code for other targets (arm64, x86) certainly allows the "printf" symbol to be resolved in the source code by remapping to another function and not exporting "printf". What exactly is the intent and semantics of what configure's CheckFunc is attempting to achieve?
The msvc "printf" satisfies both 1 and 2 only for the the amd64 dlls and satisfies only 2 for the other platform dlls. The documentation note seems to imply 1 above. If that is the case, perhaps the test for "printf" should be removed or another stdlib function chosen that is likely to always be exported. It seems far fetched in practice that a stdio function would be used without actually including the appropriate header file. Either way, it doesn't hurt to have the ability to modify the generated signature. |
The point was to remember to update the docs, not walk back on the new functionality. Don't want to have the case where it says Do Not Do X and then Here's How To Do X. |
Here's automake on the issue:
|
For explanation, these functions mirror things GNU autoconf does, and it's not very sophisticated. We make sure a function "exists" by trying to compile a program using it and not getting a link error (or, for that matter, a compile error); we're not going further than that. It's mostly from the era of not very stable APIs - glibc 2.10 has a new function that 2.9 didn't have, so if it's there use it, else use a local reimplementation (the User Guide has such an example). I don't personally see a lot of cases of needing to do this kind of thing these days, while I do see code that checks for linkable libraries - like you might include a block of code in the program if a particular crypto library is available, etc. It does depend on (potentially) accumulated information - it doesn't ask at all what library you might need to link against the symbol, so earlier Sorry for rambling on if all this was clear... |
@mwichmann @jcbrill - just pushed updates here which I think cover @mwichmann 's feedback? |
Having said "I don't see this" I went an looked at a big project, and indeed it does do one of these: # Glibc 2.25+, OpenBSD 5.5+ and FreeBSD 11.0+ offer explicit_bzero, a secure way to zero memory
if conf.CheckFunc('explicit_bzero'):
conf.env.SetConfigHeaderDefine("CONFIG_HAVE_EXPLICIT_BZERO") |
doc/man/scons.xml
Outdated
<para> | ||
The optional <parameter>funcargs</parameter> can be defined to specify an argument list for the generated | ||
function invocation. | ||
</para> | ||
|
||
<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. | ||
and the function_name being called takes any parameters, appropriate values for those | ||
function arguments should be supplied | ||
by using the <parameter>funcargs</parameter>. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here's a possible alternative (I think it's okay as is, I was just thinking of how I would have explained this... This would combine the two paragraphs into the new single para, and retains some of what was in the note originally.)
<para>
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 of arguments as
in the prototype (they can just be 0 values or empty strings).
Modern C/C++ compilers reject implicit function declarations,
and may also reject function calls that don't look
like they match the protoype.
</para>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I rather like this change.
Perhaps wordsmithing the following:
can be used to specify a string containing
an argument list with the same number of arguments as
in the prototype (they can just be 0 values or empty strings).
To something along the lines of:
can be used to specify a string containing
an argument list with the same number and type of arguments and as
in the prototype (they can simply be constant values of the correct type).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I rather like this change.
Perhaps wordsmithing the following:
that's fine by me (although apparently the types don't actually matter).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(although apparently the types don't actually matter)
I would not have expected that. If a prototype is present, I would have expected type checking (taking into account some types are automatically coerced) and possible compiler errors rather than linker errors, at least for c.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tests run on ubuntu/wsl2 and windows/pc.
Both of these tests will fail (passing a float where a char* is expected):
r = sconf.CheckFunc('strcpy', header='/* header */ char *strcpy(char *dest, char *src);', funcargs='0.0, ""')
assert r, "type failure prototype"
r = sconf.CheckFunc('strcpy', header='#include <string.h>', funcargs='0.0, ""')
assert r, "type failures include header"
However, both of these tests will pass (passing an int where a char* is expected):
r = sconf.CheckFunc('strcpy', header='/* header */ char *strcpy(char *dest, char *src);', funcargs='0, ""')
assert r, "type failure prototype"
r = sconf.CheckFunc('strcpy', header='#include <string.h>', funcargs='0, ""')
assert r, "type failures include header"
Which is what I now suspect you were alluding to in the statement above.
Zero can used/coerced into integers, floats, and (apparently) addresses which covers pointers and strings.
I wouldn't be surprised if there were warnings generated but am too lazy to test.
Perhaps the original text covers most all scenarios.
Edit:
funcargs='0, 0'
(i.e., strcpy(0, 0);
) passes as well for both ubuntu/windows.
Interested in a small expansion to the unit tests? These all pass for me on Linux but might be pushing the envelope too hard on MSVC, don't know yet (a .txt due to GitHub's asinine assumptions about allowable file suffixes) |
As always, I appreciate the information. I'm stuck on viewing the original issue as a "false negative" which was the motivation for the intent question. I need to get over it, bigger fish to fry and all that.
Always. The patch was applied and two tests were run using a minimal test file consisting of:
The two tests pass for the following configurations:
Due to time limitations, I have not run the full test suite locally. Happy to push if desired. |
Before you push, need to also fix the manpage problem, which is that an added line is not contained as expected: diff --git a/doc/man/scons.xml b/doc/man/scons.xml
index e2e6a57fb..91e8dd7da 100644
--- a/doc/man/scons.xml
+++ b/doc/man/scons.xml
@@ -3993,7 +3993,9 @@ Note: if <parameter>header</parameter> is supplied,
by using the <parameter>funcargs</parameter>.
</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>
</listitem> |
…kFunc. Changes: * add additional CheckFunc test cases to SCons/SConfTests.py * add paragraph tags around change notice for CheckFunc funcargs argument in doc/man/scons.xml
I believe it was applied as expected. Let me know if it was botched. |
…funcargs usage. [ci skip]
Man page documentation change modified from @mwichmann suggestion above (plain text):
No additional work is planned. |
Add an optional argument list string to the configure CheckFunc method so that the generated function argument list matches the function's prototype when including a header file.
Fixes #4320.
CHANGES.txt
(and read theREADME.rst
)