aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJussi Pakkanen <jpakkane@gmail.com>2016-05-10 20:56:08 +0300
committerJussi Pakkanen <jpakkane@gmail.com>2016-05-10 20:56:08 +0300
commit63c2d92ae77dba8b61e831d23d5c7a29fae2072f (patch)
tree89bc8b90a2fc6acf639f1e5c068cd145345c752e
parent95c86b5c42faffda4038f72a0961e18c59f81c59 (diff)
parent0ac33b885727180b071fa091c34ef56d00b80ceb (diff)
downloadmeson-63c2d92ae77dba8b61e831d23d5c7a29fae2072f.zip
meson-63c2d92ae77dba8b61e831d23d5c7a29fae2072f.tar.gz
meson-63c2d92ae77dba8b61e831d23d5c7a29fae2072f.tar.bz2
Merge pull request #531 from centricular/has_function_impl_fix
cc.has_function: Also detect implementations and redefinitions by a provided header
-rw-r--r--mesonbuild/compilers.py16
-rw-r--r--test cases/common/43 has function/meson.build12
2 files changed, 20 insertions, 8 deletions
diff --git a/mesonbuild/compilers.py b/mesonbuild/compilers.py
index a320e7d..d0950ef 100644
--- a/mesonbuild/compilers.py
+++ b/mesonbuild/compilers.py
@@ -680,6 +680,13 @@ int main(int argc, char **argv) {
return align
def has_function(self, funcname, prefix, env, extra_args=[]):
+ """
+ First, this function looks for the symbol in the default libraries
+ provided by the compiler (stdlib + a few others usually). If that
+ fails, it checks if any of the headers specified in the prefix provide
+ an implementation of the function, and if that fails, it checks if it's
+ implemented as a compiler-builtin.
+ """
# Define the symbol to something else in case it is defined by the
# includes or defines listed by the user `{0}` or by the compiler.
# Then, undef the symbol to get rid of it completely.
@@ -725,12 +732,17 @@ int main(int argc, char **argv) {
raise EnvironmentException('Cross variable {0} is not a boolean.'.format(varname))
if self.links(templ.format(prefix, funcname), extra_args):
return True
+ # Add -O0 to ensure that the symbol isn't optimized away by the compiler
+ extra_args += self.get_no_optimization_args()
+ # Sometimes the implementation is provided by the header, or the header
+ # redefines the symbol to be something else. In that case, we want to
+ # still detect the function.
+ if self.links('{0}\nint main() {{ {1}; }}'.format(prefix, funcname), extra_args):
+ 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().
- # Add -O0 to ensure that the symbol isn't optimized away by the compiler
- extra_args += self.get_no_optimization_args()
return self.links('int main() {{ {0}; }}'.format('__builtin_' + funcname), extra_args)
def has_member(self, typename, membername, prefix, extra_args=[]):
diff --git a/test cases/common/43 has function/meson.build b/test cases/common/43 has function/meson.build
index 3736a3d..c7fe353 100644
--- a/test cases/common/43 has function/meson.build
+++ b/test cases/common/43 has function/meson.build
@@ -3,16 +3,16 @@ project('has function', 'c')
cc = meson.get_compiler('c')
if not cc.has_function('printf', prefix : '#include<stdio.h>')
- error('Existing function not found.')
+ error('"printf" function not found (should always exist).')
endif
# Should also be able to detect it without specifying the header
# We check for a different function here to make sure the result is
# not taken from a cache (ie. the check above)
-assert(cc.has_function('fprintf'), 'Existing function not found without include')
+assert(cc.has_function('fprintf'), '"fprintf" function not found without include (should always exist).')
if cc.has_function('hfkerhisadf', prefix : '#include<stdio.h>')
- error('Found non-existant function.')
+ error('Found non-existent function "hfkerhisadf".')
endif
# With glibc on Linux lchmod is a stub that will always return an error,
@@ -21,9 +21,9 @@ endif
# 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'
- assert (cc.has_function('poll', prefix : '#include <poll.h>'), 'couldn\'t detect poll when defined by a header')
+ assert (cc.has_function('poll', prefix : '#include <poll.h>'), 'couldn\'t detect "poll" when defined by a header')
assert (not cc.has_function('lchmod', prefix : '''#include <sys/stat.h>
- #include <unistd.h>'''), 'lchmod check should have failed')
+ #include <unistd.h>'''), '"lchmod" check should have failed')
endif
# For some functions one needs to define _GNU_SOURCE before including the
@@ -31,5 +31,5 @@ endif
# as well without any prefix
if cc.has_header_symbol('sys/socket.h', 'recvmmsg', prefix : '#define _GNU_SOURCE')
# We assume that if recvmmsg exists sendmmsg does too
- assert (cc.has_function('sendmmsg'), 'Failed to detect existing function')
+ assert (cc.has_function('sendmmsg'), 'Failed to detect function "sendmmsg" (should always exist).')
endif