Merge pull request #1006 from centricular/cpp-has-header-symbol

A bunch of fixes for compiler checks with C++
pull/1017/head
Jussi Pakkanen 8 years ago committed by GitHub
commit cf7b50364f
  1. 8
      .travis.yml
  2. 58
      mesonbuild/compilers.py
  3. 32
      test cases/common/111 has header symbol/meson.build
  4. 29
      test cases/common/33 try compile/meson.build
  5. 24
      test cases/common/35 sizeof/meson.build
  6. 6
      test cases/common/35 sizeof/prog.c.in
  7. 18
      test cases/common/37 has header/meson.build
  8. 80
      test cases/common/39 tryrun/meson.build
  9. 72
      test cases/common/43 has function/meson.build
  10. 30
      test cases/common/44 has member/meson.build
  11. 48
      test cases/common/45 alignment/meson.build
  12. 18
      test cases/common/83 has type/meson.build

@ -18,6 +18,12 @@ language:
services: services:
- docker - docker
matrix:
exclude:
# On OS X gcc is just a wrapper around clang, so don't waste time testing that
- os: osx
compiler: gcc
before_install: before_install:
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew update; fi - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew update; fi
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install ninja python3; fi - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install ninja python3; fi
@ -30,5 +36,5 @@ script:
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then echo FROM jpakkane/mesonci:yakkety > Dockerfile; fi - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then echo FROM jpakkane/mesonci:yakkety > Dockerfile; fi
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then echo ADD . /root >> Dockerfile; fi - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then echo ADD . /root >> Dockerfile; fi
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then docker build -t withgit .; fi - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then docker build -t withgit .; fi
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then docker run withgit /bin/sh -c "cd /root && TRAVIS=true ./run_tests.py -- $MESON_ARGS"; fi - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then docker run withgit /bin/sh -c "cd /root && TRAVIS=true CC=$CC CXX=$CXX ./run_tests.py -- $MESON_ARGS"; fi
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then SDKROOT=$(xcodebuild -version -sdk macosx Path) ./run_tests.py --backend=ninja -- $MESON_ARGS ; fi - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then SDKROOT=$(xcodebuild -version -sdk macosx Path) ./run_tests.py --backend=ninja -- $MESON_ARGS ; fi

@ -513,6 +513,13 @@ class CCompiler(Compiler):
def get_no_optimization_args(self): def get_no_optimization_args(self):
return ['-O0'] 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): def get_output_args(self, target):
return ['-o', target] return ['-o', target]
@ -644,9 +651,14 @@ int someSymbolHereJustForFun;
extra_args = [] extra_args = []
templ = '''{2} templ = '''{2}
#include <{0}> #include <{0}>
int main () {{ {1}; }}''' int main () {{
# Pass -O0 to ensure that the symbol isn't optimized away /* If it's not defined as a macro, try to use as a symbol */
args = extra_args + self.get_no_optimization_args() #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) return self.compiles(templ.format(hname, symbol, prefix), env, args, dependencies)
@contextlib.contextmanager @contextlib.contextmanager
@ -785,7 +797,7 @@ int main(int argc, char **argv) {{
%s %s
int temparray[%d-sizeof(%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): if not self.compiles(element_exists_templ.format(prefix, element), env, args, dependencies):
return -1 return -1
for i in range(1, 1024): for i in range(1, 1024):
@ -834,7 +846,7 @@ struct tmp {
int testarray[%d-offsetof(struct tmp, target)]; 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): if not self.compiles(type_exists_templ.format(typename), env, args, dependencies):
return -1 return -1
for i in range(1, 1024): for i in range(1, 1024):
@ -919,7 +931,7 @@ int main(int argc, char **argv) {
head = '#include <limits.h>\n{0}\n' head = '#include <limits.h>\n{0}\n'
# We don't know what the function takes or returns, so try to use it as # We don't know what the function takes or returns, so try to use it as
# a function pointer # a function pointer
main = '\nint main() {{ int a = (int) &{1}; }}' main = '\nint main() {{ void *a = (void*) &{1}; }}'
return head, main return head, main
def has_function(self, funcname, prefix, env, extra_args=None, dependencies=None): def has_function(self, funcname, prefix, env, extra_args=None, dependencies=None):
@ -968,9 +980,8 @@ int main(int argc, char **argv) {
head, main = self._no_prototype_templ() head, main = self._no_prototype_templ()
templ = head + stubs_fail + main templ = head + stubs_fail + main
# Add -O0 to ensure that the symbol isn't optimized away by the compiler args = extra_args + self.get_compiler_check_args()
args = extra_args + self.get_no_optimization_args() if self.links(templ.format(prefix, funcname), env, args, dependencies):
if self.links(templ.format(prefix, funcname), env, extra_args, dependencies):
return True return True
# Some functions like alloca() are defined as compiler built-ins which # Some functions like alloca() are defined as compiler built-ins which
# are inlined by the compiler, so test for that instead. Built-ins are # are inlined by the compiler, so test for that instead. Built-ins are
@ -1049,6 +1060,20 @@ class CPPCompiler(CCompiler):
code = 'class breakCCompiler;int main(int argc, char **argv) { return 0; }\n' code = 'class breakCCompiler;int main(int argc, char **argv) { return 0; }\n'
return self.sanity_check_impl(work_dir, environment, 'sanitycheckcpp.cc', code) return self.sanity_check_impl(work_dir, environment, 'sanitycheckcpp.cc', code)
def has_header_symbol(self, hname, symbol, prefix, env, extra_args=None, dependencies=None):
# Check if it's a C-like symbol
if super().has_header_symbol(hname, symbol, prefix, env, extra_args, dependencies):
return True
# Check if it's a class or a template
if extra_args is None:
extra_args = []
templ = '''{2}
#include <{0}>
using {1};
int main () {{ return 0; }}'''
args = extra_args + self.get_compiler_check_args()
return self.compiles(templ.format(hname, symbol, prefix), env, args, dependencies)
class ObjCCompiler(CCompiler): class ObjCCompiler(CCompiler):
def __init__(self, exelist, version, is_cross, exe_wrap): def __init__(self, exelist, version, is_cross, exe_wrap):
self.language = 'objc' self.language = 'objc'
@ -1868,9 +1893,10 @@ class VisualStudioCCompiler(CCompiler):
pdbarr += ['pdb'] pdbarr += ['pdb']
return ['/DEBUG', '/PDB:' + '.'.join(pdbarr)] return ['/DEBUG', '/PDB:' + '.'.join(pdbarr)]
class VisualStudioCPPCompiler(VisualStudioCCompiler): class VisualStudioCPPCompiler(VisualStudioCCompiler, CPPCompiler):
def __init__(self, exelist, version, is_cross, exe_wrap): def __init__(self, exelist, version, is_cross, exe_wrap):
self.language = 'cpp' self.language = 'cpp'
CPPCompiler.__init__(self, exelist, version, is_cross, exe_wrap)
VisualStudioCCompiler.__init__(self, exelist, version, is_cross, exe_wrap) VisualStudioCCompiler.__init__(self, exelist, version, is_cross, exe_wrap)
self.base_options = ['b_pch'] # FIXME add lto, pgo and the like self.base_options = ['b_pch'] # FIXME add lto, pgo and the like
@ -2045,6 +2071,12 @@ class GnuCPPCompiler(GnuCompiler, CPPCompiler):
return options['cpp_winlibs'].value return options['cpp_winlibs'].value
return [] 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): class GnuObjCCompiler(GnuCompiler,ObjCCompiler):
def __init__(self, exelist, version, is_cross, exe_wrapper=None, defines=None): def __init__(self, exelist, version, is_cross, exe_wrapper=None, defines=None):
@ -2067,6 +2099,12 @@ class GnuObjCPPCompiler(GnuCompiler, ObjCPPCompiler):
'2': ['-Wall', '-Wextra', '-Winvalid-pch', '-Wnon-virtual-dtor'], '2': ['-Wall', '-Wextra', '-Winvalid-pch', '-Wnon-virtual-dtor'],
'3' : ['-Wall', '-Wpedantic', '-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(): class ClangCompiler():
def __init__(self, clang_type): def __init__(self, clang_type):
self.id = 'clang' self.id = 'clang'

@ -1,18 +1,32 @@
project('has header symbol', 'c') project('has header symbol', 'c', 'cpp')
cc = meson.get_compiler('c') cc = meson.get_compiler('c')
cpp = meson.get_compiler('cpp')
assert (cc.has_header_symbol('stdio.h', 'int'), 'base types should always be available') foreach comp : [cc, cpp]
assert (cc.has_header_symbol('stdio.h', 'printf'), 'printf function not found') assert (comp.has_header_symbol('stdio.h', 'int'), 'base types should always be available')
assert (cc.has_header_symbol('stdio.h', 'FILE'), 'FILE structure not found') assert (comp.has_header_symbol('stdio.h', 'printf'), 'printf function not found')
assert (cc.has_header_symbol('limits.h', 'INT_MAX'), 'INT_MAX define not found') assert (comp.has_header_symbol('stdio.h', 'FILE'), 'FILE structure not found')
assert (not cc.has_header_symbol('limits.h', 'guint64'), 'guint64 is not defined in limits.h') assert (comp.has_header_symbol('limits.h', 'INT_MAX'), 'INT_MAX define not found')
assert (not cc.has_header_symbol('stdlib.h', 'FILE'), 'FILE structure is defined in stdio.h, not stdlib.h') assert (not comp.has_header_symbol('limits.h', 'guint64'), 'guint64 is not defined in limits.h')
assert (not cc.has_header_symbol('stdlol.h', 'printf'), 'stdlol.h shouldn\'t exist') assert (not comp.has_header_symbol('stdlib.h', 'FILE'), 'FILE structure is defined in stdio.h, not stdlib.h')
assert (not cc.has_header_symbol('stdlol.h', 'int'), 'shouldn\'t be able to find "int" with invalid header') 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 # This is likely only available on Glibc, so just test for it
if cc.has_function('ppoll') if cc.has_function('ppoll')
assert (not cc.has_header_symbol('poll.h', 'ppoll'), 'ppoll should not be accessible without _GNU_SOURCE') 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') assert (cc.has_header_symbol('poll.h', 'ppoll', prefix : '#define _GNU_SOURCE'), 'ppoll should be accessible with _GNU_SOURCE')
endif endif
assert (cpp.has_header_symbol('iostream', 'std::iostream'), 'iostream not found in iostream.h')
assert (cpp.has_header_symbol('vector', 'std::vector'), 'vector not found in vector.h')
assert (not cpp.has_header_symbol('limits.h', 'std::iostream'), 'iostream should not be defined in limits.h')
boost = dependency('boost', required : false)
if boost.found()
assert (cpp.has_header_symbol('boost/math/quaternion.hpp', 'boost::math::quaternion', dependencies : boost), 'quaternion not found')
else
assert (not cpp.has_header_symbol('boost/math/quaternion.hpp', 'boost::math::quaternion', dependencies : boost), 'quaternion found?!')
endif

@ -1,4 +1,4 @@
project('try compile', 'c') project('try compile', 'c', 'cpp')
code = '''#include<stdio.h> code = '''#include<stdio.h>
void func() { printf("Something.\n"); } void func() { printf("Something.\n"); }
@ -8,19 +8,20 @@ breakcode = '''#include<nonexisting.h>
void func() { printf("This won't work.\n"); } void func() { printf("This won't work.\n"); }
''' '''
compiler = meson.get_compiler('c') foreach compiler : [meson.get_compiler('c'), meson.get_compiler('cpp')]
if compiler.compiles(code, name : 'should succeed') == false if compiler.compiles(code, name : 'should succeed') == false
error('Compiler is fail.') error('Compiler ' + compiler.get_id() + ' is fail.')
endif endif
if compiler.compiles(files('valid.c'), name : 'should succeed') == false if compiler.compiles(files('valid.c'), name : 'should succeed') == false
error('Compiler is fail.') error('Compiler ' + compiler.get_id() + ' is fail.')
endif endif
if compiler.compiles(breakcode, name : 'should fail') if compiler.compiles(breakcode, name : 'should fail')
error('Compiler returned true on broken code.') error('Compiler ' + compiler.get_id() + ' returned true on broken code.')
endif endif
if compiler.compiles(files('invalid.c'), name : 'should fail') if compiler.compiles(files('invalid.c'), name : 'should fail')
error('Compiler returned true on broken code.') error('Compiler ' + compiler.get_id() + ' returned true on broken code.')
endif endif
endforeach

@ -1,13 +1,33 @@
project('sizeof', 'c') project('sizeof', 'c', 'cpp')
# Test with C
cc = meson.get_compiler('c') cc = meson.get_compiler('c')
intsize = cc.sizeof('int') intsize = cc.sizeof('int')
wcharsize = cc.sizeof('wchar_t', prefix : '#include<wchar.h>') wcharsize = cc.sizeof('wchar_t', prefix : '#include<wchar.h>')
cd = configuration_data() cd = configuration_data()
cd.set('INTSIZE', intsize) cd.set('INTSIZE', intsize)
cd.set('WCHARSIZE', wcharsize) cd.set('WCHARSIZE', wcharsize)
cd.set('CONFIG', 'config.h')
configure_file(input : 'config.h.in', output : 'config.h', configuration : cd) configure_file(input : 'config.h.in', output : 'config.h', configuration : cd)
s = configure_file(input : 'prog.c.in', output : 'prog.c', configuration : cd)
e = executable('prog', 'prog.c') e = executable('prog', s)
test('sizeof test', e) test('sizeof test', e)
# Test with C++
cpp = meson.get_compiler('cpp')
intsize = cpp.sizeof('int')
wcharsize = cpp.sizeof('wchar_t', prefix : '#include<wchar.h>')
cdpp = configuration_data()
cdpp.set('INTSIZE', intsize)
cdpp.set('WCHARSIZE', wcharsize)
cdpp.set('CONFIG', 'config.hpp')
configure_file(input : 'config.h.in', output : 'config.hpp', configuration : cdpp)
spp = configure_file(input : 'prog.c.in', output : 'prog.cc', configuration : cdpp)
epp = executable('progpp', spp)
test('sizeof test c++', epp)

@ -1,6 +1,6 @@
#include"config.h" #include "@CONFIG@"
#include<stdio.h> #include <stdio.h>
#include<wchar.h> #include <wchar.h>
int main(int argc, char **argv) { int main(int argc, char **argv) {
if(INTSIZE != sizeof(int)) { if(INTSIZE != sizeof(int)) {

@ -1,11 +1,11 @@
project('has header', 'c') project('has header', 'c', 'cpp')
cc = meson.get_compiler('c') foreach comp : [meson.get_compiler('c'), meson.get_compiler('cpp')]
if comp.has_header('stdio.h') == false
error('Stdio missing.')
endif
if cc.has_header('stdio.h') == false if comp.has_header('ouagadougou.h')
error('Stdio missing.') error('Found non-existant header.')
endif endif
endforeach
if cc.has_header('ouagadougou.h')
error('Found non-existant header.')
endif

@ -1,14 +1,14 @@
project('tryrun', 'c') project('tryrun', 'c', 'cpp')
# Complex to exercise all code paths. # Complex to exercise all code paths.
if meson.is_cross_build() if meson.is_cross_build()
if meson.has_exe_wrapper() if meson.has_exe_wrapper()
cc = meson.get_compiler('c', native : false) compilers = [meson.get_compiler('c', native : false), meson.get_compiler('cpp', native : false)]
else else
cc = meson.get_compiler('c', native : true) compilers = [meson.get_compiler('c', native : true), meson.get_compiler('cpp', native : true)]
endif endif
else else
cc = meson.get_compiler('c') compilers = [meson.get_compiler('c'), meson.get_compiler('cpp')]
endif endif
ok_code = '''#include<stdio.h> ok_code = '''#include<stdio.h>
@ -32,45 +32,47 @@ INPUTS = [
['File', files('ok.c'), files('error.c'), files('no_compile.c')], ['File', files('ok.c'), files('error.c'), files('no_compile.c')],
] ]
foreach input : INPUTS foreach cc : compilers
type = input[0] foreach input : INPUTS
ok = cc.run(input[1], name : type + ' should succeed') type = input[0]
err = cc.run(input[2], name : type + ' should fail') ok = cc.run(input[1], name : type + ' should succeed')
noc = cc.run(input[3], name : type + ' does not compile') err = cc.run(input[2], name : type + ' should fail')
noc = cc.run(input[3], name : type + ' does not compile')
if noc.compiled() if noc.compiled()
error(type + ' compilation fail test failed.') error(type + ' compilation fail test failed.')
else else
message(type + ' fail detected properly.') message(type + ' fail detected properly.')
endif endif
if ok.compiled() if ok.compiled()
message(type + ' compilation worked.') message(type + ' compilation worked.')
else else
error(type + ' compilation did not work.') error(type + ' compilation did not work.')
endif endif
if ok.returncode() == 0 if ok.returncode() == 0
message(type + ' return code ok.') message(type + ' return code ok.')
else else
error(type + ' return code fail') error(type + ' return code fail')
endif endif
if err.returncode() == 1 if err.returncode() == 1
message(type + ' bad return code ok.') message(type + ' bad return code ok.')
else else
error(type + ' bad return code fail.') error(type + ' bad return code fail.')
endif endif
if ok.stdout().strip() == 'stdout' if ok.stdout().strip() == 'stdout'
message(type + ' stdout ok.') message(type + ' stdout ok.')
else else
message(type + ' bad stdout.') message(type + ' bad stdout.')
endif endif
if ok.stderr().strip() == 'stderr' if ok.stderr().strip() == 'stderr'
message(type + ' stderr ok.') message(type + ' stderr ok.')
else else
message(type + ' bad stderr.') message(type + ' bad stderr.')
endif endif
endforeach
endforeach endforeach

@ -1,41 +1,43 @@
project('has function', 'c') project('has function', 'c', 'cpp')
cc = meson.get_compiler('c') compilers = [meson.get_compiler('c'), meson.get_compiler('cpp')]
if not cc.has_function('printf', prefix : '#include<stdio.h>') foreach cc : compilers
error('"printf" function not found (should always exist).') if not cc.has_function('printf', prefix : '#include<stdio.h>')
endif error('"printf" function not found (should always exist).')
endif
# Should also be able to detect it without specifying the header # Should also be able to detect it without specifying the header
# We check for a different function here to make sure the result is # We check for a different function here to make sure the result is
# not taken from a cache (ie. the check above) # not taken from a cache (ie. the check above)
# On MSVC fprintf is defined as an inline function in the header, so it cannot # On MSVC fprintf is defined as an inline function in the header, so it cannot
# be found without the include. # be found without the include.
if cc.get_id() != 'msvc' if cc.get_id() != 'msvc'
assert(cc.has_function('fprintf'), '"fprintf" function not found without include (on !msvc).') assert(cc.has_function('fprintf'), '"fprintf" function not found without include (on !msvc).')
else else
assert(cc.has_function('fprintf', prefix : '#include <stdio.h>'), '"fprintf" function not found with include (on msvc).') assert(cc.has_function('fprintf', prefix : '#include <stdio.h>'), '"fprintf" function not found with include (on msvc).')
endif endif
if cc.has_function('hfkerhisadf', prefix : '#include<stdio.h>') if cc.has_function('hfkerhisadf', prefix : '#include<stdio.h>')
error('Found non-existent function "hfkerhisadf".') error('Found non-existent function "hfkerhisadf".')
endif endif
# With glibc on Linux lchmod is a stub that will always return an error, # With glibc on Linux lchmod is a stub that will always return an error,
# we want to detect that and declare that the function is not available. # we want to detect that and declare that the function is not available.
# We can't check for the C library used here of course, but if it's not # We can't check for the C library used here of course, but if it's not
# implemented in glibc it's probably not implemented in any other 'slimmer' # 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. # C library variants either, so the check should be safe either way hopefully.
if host_machine.system() == 'linux' and cc.get_id() == 'gcc' 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> 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 endif
# For some functions one needs to define _GNU_SOURCE before including the # For some functions one needs to define _GNU_SOURCE before including the
# right headers to get them picked up. Make sure we can detect these functions # right headers to get them picked up. Make sure we can detect these functions
# as well without any prefix # as well without any prefix
if cc.has_header_symbol('sys/socket.h', 'recvmmsg', prefix : '#define _GNU_SOURCE') if cc.has_header_symbol('sys/socket.h', 'recvmmsg', prefix : '#define _GNU_SOURCE')
# We assume that if recvmmsg exists sendmmsg does too # We assume that if recvmmsg exists sendmmsg does too
assert (cc.has_function('sendmmsg'), 'Failed to detect function "sendmmsg" (should always exist).') assert (cc.has_function('sendmmsg'), 'Failed to detect function "sendmmsg" (should always exist).')
endif endif
endforeach

@ -1,19 +1,21 @@
project('has member', 'c') project('has member', 'c', 'cpp')
cc = meson.get_compiler('c') compilers = [meson.get_compiler('c'), meson.get_compiler('cpp')]
if not cc.has_member('struct tm', 'tm_sec', prefix : '#include<time.h>') foreach cc : compilers
error('Did not detect member of "struct tm" that exists: "tm_sec"') if not cc.has_member('struct tm', 'tm_sec', prefix : '#include<time.h>')
endif error('Did not detect member of "struct tm" that exists: "tm_sec"')
endif
if cc.has_member('struct tm', 'tm_nonexistent', prefix : '#include<time.h>') if cc.has_member('struct tm', 'tm_nonexistent', prefix : '#include<time.h>')
error('Not existing member "tm_nonexistent" found.') error('Not existing member "tm_nonexistent" found.')
endif endif
if not cc.has_members('struct tm', 'tm_sec', 'tm_min', prefix : '#include<time.h>') if not cc.has_members('struct tm', 'tm_sec', 'tm_min', prefix : '#include<time.h>')
error('Did not detect members of "struct tm" that exist: "tm_sec" "tm_min"') error('Did not detect members of "struct tm" that exist: "tm_sec" "tm_min"')
endif endif
if cc.has_members('struct tm', 'tm_sec', 'tm_nonexistent2', prefix : '#include<time.h>') if cc.has_members('struct tm', 'tm_sec', 'tm_nonexistent2', prefix : '#include<time.h>')
error('Not existing member "tm_nonexistent2" found.') error('Not existing member "tm_nonexistent2" found.')
endif endif
endforeach

@ -1,29 +1,31 @@
project('alignment', 'c') project('alignment', 'c', 'cpp')
cc = meson.get_compiler('c') compilers = [meson.get_compiler('c'), meson.get_compiler('cpp')]
# These tests should return the same value on all foreach cc : compilers
# platforms. If (and when) they don't, fix 'em up. # These tests should return the same value on all
if cc.alignment('char') != 1 # platforms. If (and when) they don't, fix 'em up.
error('Alignment of char misdetected.') if cc.alignment('char') != 1
endif error('Alignment of char misdetected.')
endif
ptr_size = cc.sizeof('void*') ptr_size = cc.sizeof('void*')
dbl_alignment = cc.alignment('double') dbl_alignment = cc.alignment('double')
# These tests are not thorough. Doing this properly # These tests are not thorough. Doing this properly
# would take a lot of work because it is strongly # would take a lot of work because it is strongly
# platform and compiler dependent. So just check # platform and compiler dependent. So just check
# that they produce something fairly sane. # that they produce something fairly sane.
if ptr_size == 8 or ptr_size == 4 if ptr_size == 8 or ptr_size == 4
message('Size of ptr ok.') message('Size of ptr ok.')
else else
error('Size of ptr misdetected.') error('Size of ptr misdetected.')
endif endif
if dbl_alignment == 8 or dbl_alignment == 4 if dbl_alignment == 8 or dbl_alignment == 4
message('Alignment of double ok.') message('Alignment of double ok.')
else else
error('Alignment of double misdetected.') error('Alignment of double misdetected.')
endif endif
endforeach

@ -1,11 +1,13 @@
project('has type', 'c') project('has type', 'c', 'cpp')
cc = meson.get_compiler('c') compilers = [meson.get_compiler('c'), meson.get_compiler('cpp')]
if not cc.has_type('time_t', prefix : '#include<time.h>') foreach cc : compilers
error('Did not detect type that exists.') if not cc.has_type('time_t', prefix : '#include<time.h>')
endif error('Did not detect type that exists.')
endif
if cc.has_type('no_time_t', prefix : '#include<time.h>') if cc.has_type('no_time_t', prefix : '#include<time.h>')
error('Not existing type found.') error('Not existing type found.')
endif endif
endforeach

Loading…
Cancel
Save