aboutsummaryrefslogtreecommitdiff
path: root/test cases/common/39 has function/meson.build
blob: 26f13d6faaf9bfabc645a14d9b3b4d03e9a472c1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
project('has function', 'c', 'cpp')

host_system = host_machine.system()

# This is used in the `test_compiler_check_flags_order` unit test
unit_test_args = '-I/tmp'
defines_has_builtin = '''#ifndef __has_builtin
#error "no __has_builtin"
#endif
'''
compilers = [meson.get_compiler('c'), meson.get_compiler('cpp')]

foreach cc : compilers
  if not cc.has_function('printf', prefix : '#include<stdio.h>',
                         args : unit_test_args)
    error('"printf" function not found (should always exist).')
  endif

  # Should also be able to detect it without specifying the header
  # We check for a different function here to make sure the result is
  # not taken from a cache (ie. the check above)
  # On MSVC fprintf is defined as an inline function in the header, so it cannot
  # be found without the include.
  if not ['msvc', 'intel-cl'].contains(cc.get_id())
    assert(cc.has_function('fprintf', args : unit_test_args),
           '"fprintf" function not found without include (on !msvc).')
  else
    assert(cc.has_function('fprintf', prefix : '#include <stdio.h>',
                           args : unit_test_args),
           '"fprintf" function not found with include (on msvc).')
    # Compiler intrinsics
    assert(cc.has_function('strcmp'),
           'strcmp intrinsic should have been found on MSVC')
    assert(cc.has_function('strcmp', prefix : '#include <string.h>'),
           'strcmp intrinsic should have been found with #include on MSVC')
  endif

  if cc.has_function('hfkerhisadf', prefix : '#include<stdio.h>',
                     args : unit_test_args)
    error('Found non-existent function "hfkerhisadf".')
  endif

  if cc.has_function('hfkerhisadf', args : unit_test_args)
    error('Found non-existent function "hfkerhisadf".')
  endif

  # 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 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'
  # C library variants either, so the check should be safe either way hopefully.
  if host_system == 'linux' or host_system == 'darwin'
    assert (cc.has_function('poll', prefix : '#include <poll.h>',
                            args : unit_test_args),
            'couldn\'t detect "poll" when defined by a header')
    lchmod_prefix = '#include <sys/stat.h>\n#include <unistd.h>'
    has_lchmod = cc.has_function('lchmod', prefix : lchmod_prefix, args : unit_test_args)

    if host_system == 'linux'
      glibc_major = cc.get_define('__GLIBC__', prefix: '#include <gnu/libc-version.h>', args: unit_test_args)
      glibc_minor = cc.get_define('__GLIBC_MINOR__', prefix: '#include <gnu/libc-version.h>', args: unit_test_args)
      glibc_vers = '@0@.@1@'.format(glibc_major, glibc_minor)
      message('GLIBC vetsion:', glibc_vers)

      # lchmod was implemented in glibc 2.32 (https://sourceware.org/pipermail/libc-announce/2020/000029.html)
      if glibc_vers.version_compare('<2.32')
        assert (not has_lchmod, '"lchmod" check should have failed')
      else
        assert (has_lchmod, '"lchmod" check should have succeeded')
      endif
    else
      # macOS and *BSD have lchmod
      assert (has_lchmod, '"lchmod" check should have succeeded')
    endif
    # Check that built-ins are found properly both with and without headers
    assert(cc.has_function('alloca', args : unit_test_args),
           'built-in alloca must be found on ' + host_system)
    assert(cc.has_function('alloca', prefix : '#include <alloca.h>',
           args : unit_test_args),
           'built-in alloca must be found with #include')
    if not cc.compiles(defines_has_builtin, args : unit_test_args)
      assert(not cc.has_function('alloca',
             prefix : '#include <alloca.h>\n#undef alloca',
             args : unit_test_args),
             'built-in alloca must not be found with #include and #undef')
    endif
  endif

  # 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
  # as well without any prefix
  if cc.has_header_symbol('sys/socket.h', 'recvmmsg',
                          prefix : '#define _GNU_SOURCE',
                          args : unit_test_args)
    # We assume that if recvmmsg exists sendmmsg does too
    assert (cc.has_function('sendmmsg', args : unit_test_args),
            'Failed to detect function "sendmmsg" (should always exist).')
  endif

  # We should be able to find GCC and Clang __builtin functions
  if ['gcc', 'clang'].contains(cc.get_id())
    # __builtin_constant_p is documented to exist at least as far back as
    # GCC 2.95.3
    assert(cc.has_function('__builtin_constant_p', args : unit_test_args),
           '__builtin_constant_p must be found under gcc and clang')
  endif
endforeach