New API: cc.has_header_symbol to check if a header defines a specific symbol

Also supports a 'prefix' keyword argument for feature checks such as _GNU_SOURCE
or for headers that need to be included first
pull/490/head
Nirbheek Chauhan 9 years ago
parent cab5ce4fc0
commit 700010e452
  1. 10
      mesonbuild/compilers.py
  2. 19
      mesonbuild/interpreter.py
  3. 18
      test cases/common/111 has header symbol/meson.build

@ -258,6 +258,9 @@ class Compiler():
def has_header(self, *args, **kwargs):
raise EnvironmentException('Language %s does not support header checks.' % self.language)
def has_header_symbol(self, *args, **kwargs):
raise EnvironmentException('Language %s does not support header symbol checks.' % self.language)
def compiles(self, *args, **kwargs):
raise EnvironmentException('Language %s does not support compile checks.' % self.language)
@ -460,6 +463,13 @@ int someSymbolHereJustForFun;
'''
return self.compiles(templ % hname, extra_args)
def has_header_symbol(self, hname, symbol, prefix, extra_args=[]):
templ = '''{2}
#include <{0}>
int main () {{ {1}; }}'''
# Pass -O0 to ensure that the symbol isn't optimized away
return self.compiles(templ.format(hname, symbol, prefix), extra_args + ['-O0'])
def compile(self, code, srcname, extra_args=[]):
commands = self.get_exelist()
commands.append(srcname)

@ -575,6 +575,7 @@ class CompilerHolder(InterpreterObject):
'get_id': self.get_id_method,
'sizeof': self.sizeof_method,
'has_header': self.has_header_method,
'has_header_symbol': self.has_header_symbol_method,
'run' : self.run_method,
'has_function' : self.has_function_method,
'has_member' : self.has_member_method,
@ -752,6 +753,24 @@ class CompilerHolder(InterpreterObject):
mlog.log('Has header "%s":' % string, h)
return haz
def has_header_symbol_method(self, args, kwargs):
if len(args) != 2:
raise InterpreterException('has_header_symbol method takes exactly two arguments.')
check_stringlist(args)
hname = args[0]
symbol = args[1]
prefix = kwargs.get('prefix', '')
if not isinstance(prefix, str):
raise InterpreterException('Prefix argument of has_function must be a string.')
extra_args = self.determine_args(kwargs)
haz = self.compiler.has_header_symbol(hname, symbol, prefix, extra_args)
if haz:
h = mlog.green('YES')
else:
h = mlog.red('NO')
mlog.log('Header <{0}> has symbol "{1}":'.format(hname, symbol), h)
return haz
def find_library_method(self, args, kwargs):
if len(args) != 1:
raise InterpreterException('find_library method takes one argument.')

@ -0,0 +1,18 @@
project('has header symbol', 'c')
cc = meson.get_compiler('c')
assert (cc.has_header_symbol('stdio.h', 'int'), 'base types should always be available')
assert (cc.has_header_symbol('stdio.h', 'printf'), 'printf function not found')
assert (cc.has_header_symbol('stdio.h', 'FILE'), 'FILE structure not found')
assert (cc.has_header_symbol('limits.h', 'INT_MAX'), 'INT_MAX define not found')
assert (not cc.has_header_symbol('limits.h', 'guint64'), 'guint64 is not defined in limits.h')
assert (not cc.has_header_symbol('stdlib.h', 'FILE'), 'FILE structure is defined in stdio.h, not stdlib.h')
assert (not cc.has_header_symbol('stdlol.h', 'printf'), 'stdlol.h shouldn\'t exist')
assert (not cc.has_header_symbol('stdlol.h', 'int'), 'shouldn\'t be able to find "int" with invalid header')
# This is likely only available on Glibc, so just test for it
if cc.has_function('ppoll')
assert (not cc.has_header_symbol('poll.h', 'ppoll'), 'ppoll should not be accessible without _GNU_SOURCE')
assert (cc.has_header_symbol('poll.h', 'ppoll', prefix : '#define _GNU_SOURCE'), 'ppoll should be accessible with _GNU_SOURCE')
endif
Loading…
Cancel
Save