aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNirbheek Chauhan <nirbheek@centricular.com>2016-11-08 15:01:52 +0530
committerNirbheek Chauhan <nirbheek@centricular.com>2016-11-08 15:42:15 +0530
commitf6dfd362393fb1e999bcc0dbc7ef65c48d8b204f (patch)
tree8f72826860356316f8bc62d4f0a748219ee8ed83
parent87f07cdf3db9923b41ac23d27d8e017c8c57ecc3 (diff)
downloadmeson-f6dfd362393fb1e999bcc0dbc7ef65c48d8b204f.zip
meson-f6dfd362393fb1e999bcc0dbc7ef65c48d8b204f.tar.gz
meson-f6dfd362393fb1e999bcc0dbc7ef65c48d8b204f.tar.bz2
has_header_symbol: Make it work with C++ compilers
Need to pass -fpermissive to force C++ compilers to only warn about our non-conformant code that tests for a symbol being defined. Also do a simple #ifdef check first in has_header_symbol to allow arbitrary macros to be detected which would not have been detected earlier. This follows what AC_CHECK_DECL does. Closes #958
-rw-r--r--mesonbuild/compilers.py37
-rw-r--r--test cases/common/111 has header symbol/meson.build23
2 files changed, 44 insertions, 16 deletions
diff --git a/mesonbuild/compilers.py b/mesonbuild/compilers.py
index 94e8a54..ce137cb 100644
--- a/mesonbuild/compilers.py
+++ b/mesonbuild/compilers.py
@@ -512,6 +512,13 @@ class CCompiler(Compiler):
def get_no_optimization_args(self):
return ['-O0']
+ def get_compiler_check_args(self):
+ '''
+ Get arguments useful for compiler checks such as being permissive in
+ the code quality and not doing any optimization.
+ '''
+ return self.get_no_optimization_args()
+
def get_output_args(self, target):
return ['-o', target]
@@ -643,9 +650,14 @@ int someSymbolHereJustForFun;
extra_args = []
templ = '''{2}
#include <{0}>
-int main () {{ {1}; }}'''
- # Pass -O0 to ensure that the symbol isn't optimized away
- args = extra_args + self.get_no_optimization_args()
+int main () {{
+ /* If it's not defined as a macro, try to use as a symbol */
+ #ifndef {1}
+ {1};
+ #endif
+ return 0;
+}}'''
+ args = extra_args + self.get_compiler_check_args()
return self.compiles(templ.format(hname, symbol, prefix), env, args, dependencies)
@contextlib.contextmanager
@@ -784,7 +796,7 @@ int main(int argc, char **argv) {{
%s
int temparray[%d-sizeof(%s)];
'''
- args = extra_args + self.get_no_optimization_args()
+ args = extra_args + self.get_compiler_check_args()
if not self.compiles(element_exists_templ.format(prefix, element), env, args, dependencies):
return -1
for i in range(1, 1024):
@@ -833,7 +845,7 @@ struct tmp {
int testarray[%d-offsetof(struct tmp, target)];
'''
- args = extra_args + self.get_no_optimization_args()
+ args = extra_args + self.get_compiler_check_args()
if not self.compiles(type_exists_templ.format(typename), env, args, dependencies):
return -1
for i in range(1, 1024):
@@ -967,8 +979,7 @@ int main(int argc, char **argv) {
head, main = self._no_prototype_templ()
templ = head + stubs_fail + main
- # Add -O0 to ensure that the symbol isn't optimized away by the compiler
- args = extra_args + self.get_no_optimization_args()
+ args = extra_args + self.get_compiler_check_args()
if self.links(templ.format(prefix, funcname), env, extra_args, dependencies):
return True
# Some functions like alloca() are defined as compiler built-ins which
@@ -2035,6 +2046,12 @@ class GnuCPPCompiler(GnuCompiler, CPPCompiler):
return options['cpp_winlibs'].value
return []
+ def get_compiler_check_args(self):
+ # -fpermissive allows non-conforming code to compile which is necessary
+ # for many C++ checks. Particularly, the has_header_symbol check is
+ # too strict without this and always fails.
+ return self.get_no_optimization_args() + ['-fpermissive']
+
class GnuObjCCompiler(GnuCompiler,ObjCCompiler):
def __init__(self, exelist, version, is_cross, exe_wrapper=None, defines=None):
@@ -2057,6 +2074,12 @@ class GnuObjCPPCompiler(GnuCompiler, ObjCPPCompiler):
'2': ['-Wall', '-Wextra', '-Winvalid-pch', '-Wnon-virtual-dtor'],
'3' : ['-Wall', '-Wpedantic', '-Wextra', '-Winvalid-pch', '-Wnon-virtual-dtor']}
+ def get_compiler_check_args(self):
+ # -fpermissive allows non-conforming code to compile which is necessary
+ # for many ObjC++ checks. Particularly, the has_header_symbol check is
+ # too strict without this and always fails.
+ return self.get_no_optimization_args() + ['-fpermissive']
+
class ClangCompiler():
def __init__(self, clang_type):
self.id = 'clang'
diff --git a/test cases/common/111 has header symbol/meson.build b/test cases/common/111 has header symbol/meson.build
index e0afb42..c62e7c0 100644
--- a/test cases/common/111 has header symbol/meson.build
+++ b/test cases/common/111 has header symbol/meson.build
@@ -1,18 +1,23 @@
-project('has header symbol', 'c')
+project('has header symbol', 'c', 'cpp')
cc = meson.get_compiler('c')
+cpp = meson.get_compiler('cpp')
-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')
+foreach comp : [cc, cpp]
+ assert (comp.has_header_symbol('stdio.h', 'int'), 'base types should always be available')
+ assert (comp.has_header_symbol('stdio.h', 'printf'), 'printf function not found')
+ assert (comp.has_header_symbol('stdio.h', 'FILE'), 'FILE structure not found')
+ assert (comp.has_header_symbol('limits.h', 'INT_MAX'), 'INT_MAX define not found')
+ assert (not comp.has_header_symbol('limits.h', 'guint64'), 'guint64 is not defined in limits.h')
+ assert (not comp.has_header_symbol('stdlib.h', 'FILE'), 'FILE structure is defined in stdio.h, not stdlib.h')
+ assert (not comp.has_header_symbol('stdlol.h', 'printf'), 'stdlol.h shouldn\'t exist')
+ assert (not comp.has_header_symbol('stdlol.h', 'int'), 'shouldn\'t be able to find "int" with invalid header')
+endforeach
# 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
+
+