intl dependency: include header when checking for libc builtin

This header is required anyway. And the compile test for linking to libc
with the gettext symbol, can succeed when we try to use the literal
symbol name without includes, but fail later during project build,
because actually including libintl.h might redefine the function to match
a forked symbol. This happens when GNU libintl is installed as a
standalone library on systems that have a less fully-featured gettext
implementation.

So, by including the header in has_function, we can ensure that we test
against the default resolved header. In the event that the symbol which
is #define'd by the header is 'libintl_gettext', linking will fail against
libc even when a builtin gettext does exist, and we will fall back to the
intl dependency that provides -lintl (and which is needed to properly
use the default header).

Of course, even that probably won't work.

has_function(prefix: '...') is useless to check the difference between
builtins and external library functions. It has code to detect
"builtins" that misfires in some cases (previously seen with iconv_open).

Instead compile an open-coded test file that this intl dependency
implementation fully controls, that doesn't get up to imaginative edge
cases like trying to find `__builtin_gettext`.

It's the only way to be sure.

Fixes compiling against the intl dependency on e.g. Alpine Linux when the
libintl package is installed.
pull/10010/head
Eli Schwartz 3 years ago
parent a580fac83a
commit 1ac6fc0595
No known key found for this signature in database
GPG Key ID: CEB167EFB5722BD6
  1. 3
      mesonbuild/dependencies/misc.py

@ -490,8 +490,9 @@ class IconvSystemDependency(SystemDependency):
class IntlBuiltinDependency(BuiltinDependency):
def __init__(self, name: str, env: 'Environment', kwargs: T.Dict[str, T.Any]):
super().__init__(name, env, kwargs)
code = '''#include <libintl.h>\n\nint main() {\n gettext("Hello world");\n}'''
if self.clib_compiler.has_function('ngettext', '', env)[0]:
if self.clib_compiler.links(code, env)[0]:
self.is_found = True

Loading…
Cancel
Save