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
108
109
110
111
112
113
114
115
116
117
118
|
project('libalabaster', 'c', version: '0.01',
meson_version: '>=0.63.0',
default_options: ['warning_level=2', 'c_std=c99'],
license: 'GPL-3.0-only')
compiler = meson.get_compiler('c')
is_debug = get_option('debug')
is_msvc = compiler.get_id() == 'msvc' or compiler.get_id() == 'clang-cl'
is_msvc_specifically = compiler.cmd_array()[0] == 'cl'
is_windows = host_machine.system() == 'windows'
supports_needed_gnu_extensions = not is_msvc_specifically
have_builtin_expect = compiler.has_function('__builtin_expect')
have_typeof = compiler.compiles('__typeof__(1) j;')
if not have_typeof
error('Compiler support for \'__typeof__()\' is required.')
endif
have_posix_memalign = compiler.has_function(
'posix_memalign', prefix: '#define _POSIX_C_SOURCE 200112L\n#include <stdlib.h>')
have_wide_string = compiler.has_function('wcsrtombs')
have_wide_string_width = compiler.has_function('wcswidth')
# For testing: '-Wshadow', '-Wconversion', '-Wc++-compat'
alabaster_args = ['-fstrict-aliasing', '-Wstrict-aliasing']
if is_debug
alabaster_args += ['-DAL_DEBUG']
elif get_option('release-asserts')
# It's possible that some external code would rely on NDEBUG for conditionally
# excluding something other than asserts. The trade-off here is to accept that rather
# than possibly miss an assert.
alabaster_args += ['-DAL_RELEASE_ASSERTS']
else
alabaster_args += ['-DNDEBUG']
endif
# The definition of the assert() macro is determined by the _last_ place where
# <assert.h> was included, because it redefines itself each time. Making it
# unnecessarily complicated to predict if assert() will be active or a no-op.
# Maybe I just haven't seen why this could make sense, but to me it's counterintuitive.
# We define al_assert() to be unchanging and let any dependencies figure it out for themselves.
# Another note, which I hadn't heard before but, this clearly makes relying on NDEBUG
# for anything other than asserts a very bad practice.
# https://sourceware.org/git/?p=glibc.git;a=blob;f=assert/assert.h;h=31892aebcb9115a3b48be4d179eb9e8ab2f8784f;hb=HEAD#l24
if compiler.has_function('__assert_fail', prefix: '#include <assert.h>')
alabaster_args += ['-DAL_ASSERT_FUNCTION=__assert_fail', '-DAL_ASSERT_INCLUDE_FUNC']
elif compiler.has_function('_assert', prefix: '#include <assert.h>')
# https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/assert-macro-assert-wassert?view=msvc-170
alabaster_args += ['-DAL_ASSERT_FUNCTION=_assert']
elif compiler.has_function('__assert', prefix: '#include <assert.h>')
# https://github.com/aosp-mirror/platform_bionic/blob/731631f300090436d7f5df80d50b6275c8c60a93/libc/include/assert.h#L63
alabaster_args += ['-DAL_ASSERT_FUNCTION=__assert', '-DAL_ASSERT_EXPR_LAST']
endif
if is_msvc_specifically
alabaster_args += ['/arch:AVX']
endif
if compiler.has_function('rand_r', prefix: '#define _POSIX_C_SOURCE 200112L\n#include <stdlib.h>')
elif is_windows # This is supposed to be a check for if libc = Microsoft CRT.
# https://learn.microsoft.com/en-us/previous-versions/f0d4wb4t(v=vs.140)?redirectedfrom=MSDN
# "The srand function sets ... in the current thread."
alabaster_args += ['-DAL_SRAND_THREAD_LOCAL']
else
error('No thread-local rand().')
endif
if supports_needed_gnu_extensions
alabaster_args += ['-DAL_HAVE_GNU_EXTENSIONS']
endif
if have_builtin_expect
alabaster_args += ['-DAL_HAVE_BUILTIN_EXPECT']
endif
if have_posix_memalign
alabaster_args += ['-DAL_HAVE_POSIX_MEMALIGN']
endif
if have_wide_string
alabaster_args += ['-DAL_HAVE_WIDE_STRING']
endif
if have_wide_string_width
alabaster_args += ['-DAL_HAVE_WIDE_STRING_WIDTH']
endif
c89atomic = subproject('c89atomic').get_variable('c89atomic')
alabaster_src = [
'src/lib.c',
'src/random.c',
'src/str.c',
'src/ring_buffer.c',
'src/log.c'
]
alabaster_inc = include_directories('include')
alabaster_deps = [c89atomic]
alabaster = declare_dependency(include_directories: alabaster_inc,
dependencies: alabaster_deps, sources: alabaster_src,
compile_args: alabaster_args)
if get_option('tests').allowed()
tests_src = [
'tests/main.c',
'tests/lib.c',
'tests/array.c',
'tests/str.c',
'tests/ring_buffer.c'
]
if supports_needed_gnu_extensions
tests_src += ['tests/array_typed.c']
endif
executable('tests', tests_src, dependencies: alabaster, install: false)
endif
|