Merge pull request #531 from centricular/has_function_impl_fix

cc.has_function: Also detect implementations and redefinitions by a provided header
pull/537/head
Jussi Pakkanen 9 years ago
commit 63c2d92ae7
  1. 16
      mesonbuild/compilers.py
  2. 12
      test cases/common/43 has function/meson.build

@ -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=[]):

@ -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

Loading…
Cancel
Save