diff options
author | Nirbheek Chauhan <nirbheek@centricular.com> | 2016-11-08 15:01:52 +0530 |
---|---|---|
committer | Nirbheek Chauhan <nirbheek@centricular.com> | 2016-11-08 15:42:15 +0530 |
commit | f6dfd362393fb1e999bcc0dbc7ef65c48d8b204f (patch) | |
tree | 8f72826860356316f8bc62d4f0a748219ee8ed83 | |
parent | 87f07cdf3db9923b41ac23d27d8e017c8c57ecc3 (diff) | |
download | meson-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.py | 37 | ||||
-rw-r--r-- | test cases/common/111 has header symbol/meson.build | 23 |
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 + + |