diff options
author | Nirbheek Chauhan <nirbheek@centricular.com> | 2016-12-06 23:59:49 +0530 |
---|---|---|
committer | Jussi Pakkanen <jpakkane@gmail.com> | 2016-12-10 23:18:17 +0200 |
commit | be04aa2a0b00d123aae78da2448a216f7e3201b9 (patch) | |
tree | 3bd6fa65412250ba4daa201a5635f83721a4eb57 | |
parent | c75b5886da31c97e991a4458fc9bcb41ed149ecd (diff) | |
download | meson-be04aa2a0b00d123aae78da2448a216f7e3201b9.zip meson-be04aa2a0b00d123aae78da2448a216f7e3201b9.tar.gz meson-be04aa2a0b00d123aae78da2448a216f7e3201b9.tar.bz2 |
has_function: Fix checking for builtins with includes
We were checking for builtins explicitly like this because the ordinary
checks don't work for builtins at all. We do exactly the same check as
Autoconf and it doesn't work with Autoconf either (Autoconf is broken!)
So now we check for it in two ways: if there's no #include in prefix, we
check if `__builtin_symbol` exists (has_function allows checking for
functions without providing includes). If there's a #include, we check
if `symbol` exists.
The old method was causing problems with some buggy toolchains such as
MSYS2 which define some builtins in the C library but don't expose them
via headers which meant that `__builtin_symbol` would be found even
though `symbol` is not available.
Doing this allows people to always get the correct answer as long as
they specify the includes that are required to find a function while
also not forcing people to always specify includes to find a function
which is cumbersome.
Closes #1083
-rw-r--r-- | mesonbuild/compilers.py | 22 | ||||
-rw-r--r-- | test cases/common/43 has function/meson.build | 10 |
2 files changed, 26 insertions, 6 deletions
diff --git a/mesonbuild/compilers.py b/mesonbuild/compilers.py index 0f6250f..7b9adde 100644 --- a/mesonbuild/compilers.py +++ b/mesonbuild/compilers.py @@ -1020,11 +1020,23 @@ int main(int argc, char **argv) { if self.links(templ.format(prefix, funcname), env, extra_args, dependencies): return True # Some functions like alloca() are defined as compiler built-ins which - # are inlined by the compiler, so test for that instead. Built-ins are - # special functions that ignore all includes and defines, so we just - # directly try to link via main(). - return self.links('int main() {{ {0}; }}'.format('__builtin_' + funcname), - env, extra_args, dependencies) + # are inlined by the compiler, so look for __builtin_symbol in the libc + # if there's no #include-s in prefix which would've #define-d the + # symbol correctly. If there is a #include, just check for the symbol + # directly. This is needed because the above #undef fancy footwork + # doesn't work for builtins. + # This fixes instances such as #1083 where MSYS2 defines + # __builtin_posix_memalign in the C library but doesn't define + # posix_memalign in the headers to point to that builtin which results + # in an invalid detection. + if '#include' not in prefix: + code = 'int main() {{ {0}; }}' + return self.links(code.format('__builtin_' + funcname), env, + extra_args, dependencies) + else: + code = '{0}\n' + stubs_fail + '\nint main() {{ {1}; }}' + return self.links(code.format(prefix, funcname), env, extra_args, + dependencies) def has_members(self, typename, membernames, prefix, env, extra_args=None, dependencies=None): if extra_args is None: diff --git a/test cases/common/43 has function/meson.build b/test cases/common/43 has function/meson.build index e0d3344..323ed00 100644 --- a/test cases/common/43 has function/meson.build +++ b/test cases/common/43 has function/meson.build @@ -1,5 +1,7 @@ project('has function', 'c', 'cpp') +host_system = host_machine.system() + # This is used in the `test_compiler_check_flags_order` unit test unit_test_args = '-I/tmp' compilers = [meson.get_compiler('c'), meson.get_compiler('cpp')] @@ -34,7 +36,7 @@ foreach cc : compilers # We can't check for the C library used here of course, but if it's not # implemented in glibc it's probably not implemented in any other 'slimmer' # C library variants either, so the check should be safe either way hopefully. - if host_machine.system() == 'linux' and cc.get_id() == 'gcc' + if host_system == 'linux' and cc.get_id() == 'gcc' assert (cc.has_function('poll', prefix : '#include <poll.h>', args : unit_test_args), 'couldn\'t detect "poll" when defined by a header') @@ -42,6 +44,12 @@ foreach cc : compilers assert (not cc.has_function('lchmod', prefix : lchmod_prefix, args : unit_test_args), '"lchmod" check should have failed') + # Check that built-ins are found properly both with and without headers + assert(cc.has_function('alloca', args : unit_test_args), + 'built-in alloca must be found on Linux') + assert(cc.has_function('alloca', prefix : '#include <alloca.h>', + args : unit_test_args), + 'built-in alloca must be found on Linux with #include') endif # For some functions one needs to define _GNU_SOURCE before including the |