blob: 2757cff1ef16b1734664d9c1abd2cdca6dedb98b [file] [log] [blame]
Austin Schuh35a2f492021-04-07 21:41:56 -07001# Project definition
2project('rawrre', 'c',
3 version: '0.6.0',
4 default_options: ['c_std=c99'],
5 meson_version: '>=0.46.0')
6
7# Set compiler warning flags
8compiler = meson.get_compiler('c')
9compiler_args = compiler.get_supported_arguments([
10 '-Wall',
11 '-Wmissing-declarations',
12 '-Wmissing-prototypes',
13 '-Wstrict-prototypes',
14 '-Wbad-function-cast',
15 '-Wsign-compare',
16 '-Wnested-externs',
17 '-Wshadow',
18 '-Waggregate-return',
19 '-Wcast-align',
20 '-Wextra',
21 '-Wold-style-definition',
22 '-Wdeclaration-after-statement',
23 '-Wuninitialized', # TODO: Only when optimising? But why?
24 '-Wshorten-64-to-32', # Apple-specific
25 '-pedantic',
26])
27add_project_arguments(compiler_args, language: 'c')
28
29# TODO: Include -g flag for extra debug stuff?
30# TODO: Optimise for speed or size?
31
32# Configuration
33# TODO: Generate a configuration file instead of defining? Would simplify the
34# configuration.
35# This would allow projects depending on this able to import those
36# defines, too.
37compile_args = []
38configuration = configuration_data()
39
40# OS
41system = host_machine.system()
42add_project_arguments('-DOS="@0@"'.format(system), language: 'c')
43configuration.set_quoted('OS', system)
44if system == 'darwin'
45 add_project_arguments('-DDARWIN', language: 'c')
46 configuration.set('DARWIN', 1)
47elif system == 'dragonfly'
48 add_project_arguments('-DDRAGONFLY', language: 'c')
49 configuration.set('DRAGONFLY', 1)
50elif system == 'freebsd'
51 add_project_arguments('-DFREEBSD', language: 'c')
52 configuration.set('FREEBSD', 1)
53elif system == 'gnu'
54 add_project_arguments('-DGNU', language: 'c')
55 configuration.set('GNU', 1)
56elif system == 'gnu/kfreebsd'
57 add_project_arguments(
58 '-DKFREEBSD',
59 '-D_GNU_SOURCE',
60 language: 'c')
61 configuration.set('GNU', 1)
62 configuration.set('_GNU_SOURCE', 1)
63elif system == 'linux'
64 add_project_arguments('-DLINUX', language: 'c')
65 configuration.set('LINUX', 1)
66elif system == 'netbsd'
67 add_project_arguments('-DDNETBSD', language: 'c')
68 configuration.set('NETBSD', 1)
69elif system == 'sunos'
70 add_project_arguments('-DSOLARIS', language: 'c')
71 configuration.set('SOLARIS', 1)
72 compile_args += '-DSOLARIS'
73elif system == 'windows'
74 add_project_arguments('-DWIN32', language: 'c')
75 configuration.set('WIN32', 1)
76 compile_args += '-DWIN32'
77else
78 warning('Unhandled OS: @0@'.format(system))
79endif
80
81# Architecture
82cpu = host_machine.cpu()
83add_project_arguments('-DARCH="@0@"'.format(cpu), language: 'c')
84configuration.set_quoted('ARCH', cpu)
85
86# Dependency: Threads
87# TODO: Make this overridable
88thread_dep = dependency('threads', required: false)
89
90# Dependency: OpenSSL
91openssl_dep = dependency('openssl', version: '>=0.9.8', required: false)
92# TODO: Make this overridable
93if openssl_dep.found()
94 add_project_arguments(
95 '-DUSE_OPENSSL',
96 '-DUSE_TLS',
97 language: 'c')
98 configuration.set('USE_OPENSSL', 1)
99 configuration.set('USE_TLS', 1)
100 compile_args += '-DUSE_OPENSSL'
101
102 # Check for DTLS
103 if compiler.has_header('openssl/dtls1.h')
104 add_project_arguments(
105 '-DUSE_OPENSSL_DTLS',
106 '-DUSE_DTLS',
107 language: 'c')
108 configuration.set('USE_OPENSSL_DTLS', 1)
109 configuration.set('USE_DTLS', 1)
110 endif
111
112 # Check for SRTP
113 if compiler.has_header('openssl/srtp.h')
114 add_project_arguments(
115 '-DUSE_OPENSSL_SRTP',
116 '-DUSE_DTLS_SRTP',
117 language: 'c')
118 configuration.set('USE_OPENSSL_SRTP', 1)
119 configuration.set('USE_DTLS_SRTP', 1)
120 endif
121endif
122
123# Dependency: zlib
124# TODO: Make this overridable
125# TODO: Arbitrary version, ask maintainers
126zlib_dep = dependency('zlib', version: '>=1.2.8', required: false)
127if zlib_dep.found()
128 add_project_arguments('-DUSE_ZLIB', language: 'c')
129 configuration.set('USE_ZLIB', 1)
130 compile_args += '-DUSE_ZLIB'
131endif
132
133# Dependencies list
134dependencies = [
135 thread_dep,
136 openssl_dep,
137 zlib_dep,
138]
139
140# Features: Common
141add_project_arguments(
142 '-DHAVE_INET6',
143 '-DHAVE_SELECT',
144 '-DHAVE_STDBOOL_H',
145 language: 'c')
146configuration.set('HAVE_INET6', 1)
147configuration.set('HAVE_SELECT', 1)
148configuration.set('HAVE_STDBOOL_H', 1)
149compile_args += [
150 '-DHAVE_INET6',
151 '-DHAVE_STDBOOL_H',
152]
153
154# Features: Check for fixed size integer types
155if compiler.has_header('inttypes.h')
156 add_project_arguments('-DHAVE_INTTYPES_H', language: 'c')
157 configuration.set('HAVE_INTTYPES_H', 1)
158 compile_args += '-DHAVE_INTTYPES_H'
159endif
160
161# Features: Check for route
162have_net_route = compiler.has_header('net/route.h')
163if have_net_route
164 add_project_arguments('-DHAVE_NET_ROUTE_H', language: 'c')
165 configuration.set('HAVE_NET_ROUTE_H', 1)
166endif
167
168# Features: Check for sysctl
169have_sysctl = compiler.has_header('sys/sysctl.h')
170if have_sysctl
171 add_project_arguments('-DHAVE_SYS_SYSCTL_H', language: 'c')
172 configuration.set('HAVE_SYS_SYSCTL_H', 1)
173endif
174
175# Features: OS-specific
176if system == 'windows'
177 # Windows
178 add_project_arguments(
179 '-DHAVE_IO_H',
180 '-D_WIN32_WINNT=0x0501',
181 '-D__ssize_t_defined',
182 language: 'c')
183 configuration.set('HAVE_IO_H', 1)
184 configuration.set('_WIN32_WINNT', 0x0501)
185 configuration.set('__ssize_t_defined', 1)
186 compile_args += '-D__ssize_t_defined'
187
188 # Additional linking
189 dependencies += compiler.find_library('wsock32', required: true)
190 dependencies += compiler.find_library('ws2_32', required: true)
191 dependencies += compiler.find_library('iphlpapi', required: true)
192
193 # TODO: APP_LFLAGS += -Wl,--export-all-symbols
194else
195 # UNIX
196 add_project_arguments(
197 '-DHAVE_FORK',
198 '-DHAVE_INET_NTOP',
199 '-DHAVE_PWD_H',
200 '-DHAVE_SELECT_H',
201 '-DHAVE_SETRLIMIT',
202 '-DHAVE_SIGNAL',
203 '-DHAVE_STRERROR_R',
204 '-DHAVE_STRINGS_H',
205 '-DHAVE_SYS_TIME_H',
206 '-DHAVE_UNAME',
207 '-DHAVE_UNISTD_H',
208 language: 'c')
209 configuration.set('HAVE_FORK', 1)
210 configuration.set('HAVE_INET_NTOP', 1)
211 configuration.set('HAVE_PWD_H', 1)
212 configuration.set('HAVE_SELECT_H', 1)
213 configuration.set('HAVE_SETRLIMIT', 1)
214 configuration.set('HAVE_SIGNAL', 1)
215 configuration.set('HAVE_STRERROR_R', 1)
216 configuration.set('HAVE_STRINGS_H', 1)
217 configuration.set('HAVE_SYS_TIME_H', 1)
218 configuration.set('HAVE_UNAME', 1)
219 configuration.set('HAVE_UNISTD_H', 1)
220
221 # Solaris requires some additional linking
222 if system == 'sunos'
223 dependencies += compiler.find_library('socket', required: true)
224 dependencies += compiler.find_library('nsl', required: true)
225 endif
226
227 # Check for pthread
228 if compiler.has_header('pthread.h')
229 add_project_arguments('-DHAVE_PTHREAD', language: 'c')
230 configuration.set('HAVE_PTHREAD', 1)
231 endif
232
233 # Check for ifaddrs
234 ifaddrs_prefix = '''
235 #include <sys/socket.h>
236 #define __USE_MISC 1 /**< Use MISC code */
237 #include <net/if.h>
238 #include <ifaddrs.h>
239 '''
240 if compiler.has_function('getifaddrs', prefix: ifaddrs_prefix)
241 add_project_arguments('-DHAVE_GETIFADDRS', language: 'c')
242 configuration.set('HAVE_GETIFADDRS', 1)
243 endif
244
245 # Check for dlfcn
246 if compiler.has_header('dlfcn.h')
247 # Linux, GNU and Solaris require linking
248 if system == 'linux' or system == 'gnu' or system == 'sunos'
249 dependencies += compiler.find_library('dl', required: true)
250 endif
251 add_project_link_arguments('-rdynamic', language: 'c')
252 add_project_arguments('-DHAVE_DLFCN', language: 'c')
253 configuration.set('HAVE_DLFCN', 1)
254 endif
255
256 # Check for epoll
257 if compiler.has_header('sys/epoll.h')
258 add_project_arguments('-DHAVE_EPOLL', language: 'c')
259 configuration.set('HAVE_EPOLL', 1)
260 endif
261
262 # Check for resolv
263 resolv_prefix = '''
264 #define _BSD_SOURCE 1
265 #define _DEFAULT_SOURCE 1
266 #include <sys/types.h>
267 #include <netinet/in.h>
268 #include <arpa/nameser.h>
269 #include <resolv.h>
270 '''
271 if compiler.has_type('struct __res_state', prefix: resolv_prefix)
272 # OSX/iOS and Solaris require linking
273 if system == 'darwin' or system == 'sunos'
274 dependencies += compiler.find_library('resolv', required: true)
275 endif
276 add_project_arguments('-DHAVE_RESOLV', language: 'c')
277 configuration.set('HAVE_RESOLV', 1)
278 endif
279
280 # Check for kqueue
281 kqueue_prefix = '''
282 #include <sys/types.h>
283 #include <sys/event.h>
284 #include <sys/time.h>
285 '''
286 if compiler.has_function('kqueue', prefix: kqueue_prefix)
287 add_project_arguments('-DHAVE_KQUEUE', language: 'c')
288 configuration.set('HAVE_KQUEUE', 1)
289 endif
290
291 # Check for arc4random
292 if compiler.has_function('arc4random', prefix: '#include <stdlib.h>')
293 add_project_arguments('-DHAVE_ARC4RANDOM', language: 'c')
294 configuration.set('HAVE_ARC4RANDOM', 1)
295 endif
296
297 # Features OSX/iOS is lacking
298 if not (system == 'darwin')
299 # OSX/iOS's poll() does not support devices
300 add_project_arguments(
301 '-DHAVE_POLL',
302 '-DHAVE_INET_PTON',
303 language: 'c')
304 configuration.set('HAVE_POLL', 1)
305 configuration.set('HAVE_INET_PTON', 1)
306 endif
307endif
308
309# Features: Routing for Linux and *BSD
310if system == 'linux' or (have_sysctl and have_net_route)
311 add_project_arguments('-DHAVE_ROUTE_LIST', language: 'c')
312 configuration.set('HAVE_ROUTE_LIST', 1)
313endif
314
315# Version
316version = meson.project_version()
317version_array = version.split('.')
318add_project_arguments(
319 '-DVERSION="@0@"'.format(version),
320 '-DVER_MAJOR=@0@'.format(version_array[0]),
321 '-DVER_MINOR=@0@'.format(version_array[1]),
322 '-DVER_PATCH=@0@'.format(version_array[2]),
323 language: 'c')
324configuration.set_quoted('VERSION', version)
325configuration.set('VER_MAJOR', version_array[0])
326configuration.set('VER_MINOR', version_array[1])
327configuration.set('VER_PATCH', version_array[2])
328
329# TODO: Define 'RELEASE' when using build type 'release'
330# Also, compile_args += '-DMBUF_DEBUG=1' in that case
331# TODO: Check if we need to do anything for gcov
332# TODO: Check if we need to do anything for GNU profiling
333# TODO: Port packaging section
334# TODO: Port clang section
335# TODO: Port documentation section
336
337# Includes
338include_dir = include_directories('include')
339subdir('include')
340
341# Sources & Modules
342# TODO: Make which to build configurable
343subdir('src')
344
345# Build library
346re = library(meson.project_name(), sources,
347 dependencies: dependencies,
348 include_directories: include_dir,
349 install: true,
350 version: version)
351
352# Install headers
353install_headers(includes, subdir: 're')
354
355# Declare dependency
356re_dep = declare_dependency(
357 compile_args: compile_args,
358 include_directories: include_dir,
359 link_with: re)
360
361# Generate pkg-config file
362pkg = import('pkgconfig')
363description = '''Generic library for real-time communications with
364 async IO support'''
365description = ' '.join(description.split())
366pkg.generate(re,
367 name: 'libre',
368 description: description,
369 url: 'http://www.creytiv.com/re.html',
370 extra_cflags: compile_args, # https://github.com/creytiv/re/issues/167
371 subdirs: 're')
372
373# TODO: Ensure 'install' has the same result as when invoking 'make'