aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mesonbuild/compilers.py10
-rw-r--r--mesonbuild/interpreter.py19
-rw-r--r--test cases/common/111 has header symbol/meson.build18
3 files changed, 47 insertions, 0 deletions
diff --git a/mesonbuild/compilers.py b/mesonbuild/compilers.py
index 4f55be4..229d224 100644
--- a/mesonbuild/compilers.py
+++ b/mesonbuild/compilers.py
@@ -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)
diff --git a/mesonbuild/interpreter.py b/mesonbuild/interpreter.py
index 0a88ce4..d6a3a3e 100644
--- a/mesonbuild/interpreter.py
+++ b/mesonbuild/interpreter.py
@@ -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.')
diff --git a/test cases/common/111 has header symbol/meson.build b/test cases/common/111 has header symbol/meson.build
new file mode 100644
index 0000000..e0afb42
--- /dev/null
+++ b/test cases/common/111 has header symbol/meson.build
@@ -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