You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
cc.has_function('ngettext', prefix : '#include <libintl.h>') returns true when cross compiling with mingw, but it should return false because it also needs '-lintl' to be able to link.
The reason is CCompiler.has_function() first try to link a code and that fails. Then it tries to detect built-in, #ifdef __has_builtin is false, and ! defined({func}) is false too because mingw's libintl.h has this: # define ngettext libintl_ngettext. So that built-in check succeed and it shouldn't.
I don't think it's a dup, looks like more an extra way it's broken. Here it has nothing to do with builtin actually, it's for a case where a header #define the symbol to something that is implemented into a library and meson claims it works without actually linking to that lib.
#include<math.h>intmain() {
#ifdef__has_builtin#if !__has_builtin(__builtin_hypot)
#error "__builtin_hypot not found"
#endif#elif ! defined(hypot)
/* Check for __builtin_hypot only if no includes were added to the * prefix above, which means no definition of hypot can be found. * We would always check for this, but we get false positives on * MSYS2 if we do. Their toolchain is broken, but we can at least * give them a workaround. */#if0__builtin_hypot;
#else#error "No definition for __builtin_hypot found in the prefix"
#endif#endifreturn0;
}
but there's no check if the code used is really able to use that built-in, in many cases if a replacement function is defined the compiler will use that function, not the built-in causing compiler/linking failures.
Note also that the code above will succeed if there's just a preprocessor definition, for instance a code like
/* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */#ifdef__cplusplusextern"C"#endifcharhypot ();
intmain ()
{
returnhypot ();
;
return0;
}
that although produces a warning does a full check of compile + link.
Is there a good reason to use prefix: ... here? I assume it will fail to be detected as available in the stdlib if you don't add the header... this should be and cc.has_header('libintl.h') if the goal is actually to find out if the development header is installed too.
Aside: meson recently grew the dependency('intl') custom builtin dependency specifically for this example.
For cross-platform proper results it is essential to include the right header when checking for the presence of the function, as the header might contain essential annotations for the function declaration used by the compiler and linker that decide if compiling and linking will succeed.
One example of this is macOS, which has special availability annotations, so when targeting older macOS versions that lack specific functions, those will become weakly linked (and with the right flags, compilation and/or linking will fail completely) which avoid accidental use of such functions when compiling for older macOS versions with code that is not prepared to deal with it (which probably applies to most projects using meson and explicitly checking if a function exists at build time).
Another big can of worms is introduced by the fact that mesons cc.has_function checks for builtins too. IMHO meson should have a new check_function where the header(s) should be a mandatory argument that only works for functions and a separate has_builtin for the small number of cases where a function might be implemented by a builtin only (like IIRC alloc on some systems). This would reduce implementation complexity, make testing easier and prevent unexpected outcomes (like current with has_function on macOS/iOS when not specifying the header in prefix:).
Meanwhile I forgot how broken this is, rediscovered it in #9642, and then afterward came across this issue again.
Use case there was for libiconv/iconv_open, not libintl/ngettext, but the same basic issue... I ended up just writing a custom test file snippet for the check, because I can't trust the one has_function provides.
This is tolerable for meson's builtin dependencies, it is write-once-solve-everywhere. Less so for cc.has_function when used directly in project meson.build files...
As I mentioned when originally rediscovering the problem here: #9632 (comment)
As far as I can tell, on compilers without __has_builtin this goes straight to "is the function defined in the header? Okay, immediately return success". So if you include a header in a has_function check it always falls back to successfully answering that it's a valid builtin.
And as I was told on IRC, mingw toolchains don't have a version of GCC that is recent enough to support __has_builtin, TIL.
Activity
xclaesse commentedon Jun 14, 2018
I'm not sure, but I think that code is missing a
EDIT: not, that break unit tests, 'alloca' is not found with that change.
ePirat commentedon Jun 14, 2018
Seems this is a duplicate of either #3672 or #3676, no?
See also PR #3675
xclaesse commentedon Jun 14, 2018
I don't think it's a dup, looks like more an extra way it's broken. Here it has nothing to do with builtin actually, it's for a case where a header #define the symbol to something that is implemented into a library and meson claims it works without actually linking to that lib.
nirbheek commentedon Jun 18, 2018
I'll update #3675 with a test for this.
package/libglib2: fix NLS build on musl and uclibc
etrunko commentedon Jan 30, 2020
I'm getting this error with fedora rawhide (32), the check for hypot() function returns YES, while the link fails due to lack of -lm.
https://kojipkgs.fedoraproject.org//work/tasks/2934/41262934/build.log
Funny thing tough, it works with Fedora 31.
https://kojipkgs.fedoraproject.org//work/tasks/3519/41263519/build.log
I added a
cat meson-logs/meson-log.txtto the spec file so to print the contents of that file after the configure time.freddy77 commentedon Jan 31, 2020
Looking at above log
but there's no check if the code used is really able to use that built-in, in many cases if a replacement function is defined the compiler will use that function, not the built-in causing compiler/linking failures.
Note also that the code above will succeed if there's just a preprocessor definition, for instance a code like
will succeed.
Autoconf code uses something like
that although produces a warning does a full check of compile + link.
eli-schwartz commentedon Aug 31, 2021
Is there a good reason to use
prefix: ...here? I assume it will fail to be detected as available in the stdlib if you don't add the header... this should beand cc.has_header('libintl.h')if the goal is actually to find out if the development header is installed too.Aside: meson recently grew the dependency('intl') custom builtin dependency specifically for this example.
ePirat commentedon Aug 31, 2021
For cross-platform proper results it is essential to include the right header when checking for the presence of the function, as the header might contain essential annotations for the function declaration used by the compiler and linker that decide if compiling and linking will succeed.
One example of this is macOS, which has special availability annotations, so when targeting older macOS versions that lack specific functions, those will become weakly linked (and with the right flags, compilation and/or linking will fail completely) which avoid accidental use of such functions when compiling for older macOS versions with code that is not prepared to deal with it (which probably applies to most projects using meson and explicitly checking if a function exists at build time).
Another big can of worms is introduced by the fact that mesons
cc.has_functionchecks for builtins too. IMHO meson should have a newcheck_functionwhere the header(s) should be a mandatory argument that only works for functions and a separatehas_builtinfor the small number of cases where a function might be implemented by a builtin only (like IIRC alloc on some systems). This would reduce implementation complexity, make testing easier and prevent unexpected outcomes (like current withhas_functionon macOS/iOS when not specifying the header inprefix:).eli-schwartz commentedon Dec 2, 2021
Meanwhile I forgot how broken this is, rediscovered it in #9642, and then afterward came across this issue again.
Use case there was for libiconv/iconv_open, not libintl/ngettext, but the same basic issue... I ended up just writing a custom test file snippet for the check, because I can't trust the one has_function provides.
This is tolerable for meson's builtin dependencies, it is write-once-solve-everywhere. Less so for cc.has_function when used directly in project meson.build files...
eli-schwartz commentedon Dec 2, 2021
As I mentioned when originally rediscovering the problem here:
#9632 (comment)
And as I was told on IRC, mingw toolchains don't have a version of GCC that is recent enough to support __has_builtin, TIL.
package/libglib2: fix NLS build on musl and uclibc
meson: include headers when checking for functions
meson: include headers when checking for functions
meson: include headers when checking for functions