Austin Schuh | 35a2f49 | 2021-04-07 21:41:56 -0700 | [diff] [blame] | 1 | # Project definition |
| 2 | project('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 |
| 8 | compiler = meson.get_compiler('c') |
| 9 | compiler_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 | ]) |
| 27 | add_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. |
| 37 | compile_args = [] |
| 38 | configuration = configuration_data() |
| 39 | |
| 40 | # OS |
| 41 | system = host_machine.system() |
| 42 | add_project_arguments('-DOS="@0@"'.format(system), language: 'c') |
| 43 | configuration.set_quoted('OS', system) |
| 44 | if system == 'darwin' |
| 45 | add_project_arguments('-DDARWIN', language: 'c') |
| 46 | configuration.set('DARWIN', 1) |
| 47 | elif system == 'dragonfly' |
| 48 | add_project_arguments('-DDRAGONFLY', language: 'c') |
| 49 | configuration.set('DRAGONFLY', 1) |
| 50 | elif system == 'freebsd' |
| 51 | add_project_arguments('-DFREEBSD', language: 'c') |
| 52 | configuration.set('FREEBSD', 1) |
| 53 | elif system == 'gnu' |
| 54 | add_project_arguments('-DGNU', language: 'c') |
| 55 | configuration.set('GNU', 1) |
| 56 | elif 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) |
| 63 | elif system == 'linux' |
| 64 | add_project_arguments('-DLINUX', language: 'c') |
| 65 | configuration.set('LINUX', 1) |
| 66 | elif system == 'netbsd' |
| 67 | add_project_arguments('-DDNETBSD', language: 'c') |
| 68 | configuration.set('NETBSD', 1) |
| 69 | elif system == 'sunos' |
| 70 | add_project_arguments('-DSOLARIS', language: 'c') |
| 71 | configuration.set('SOLARIS', 1) |
| 72 | compile_args += '-DSOLARIS' |
| 73 | elif system == 'windows' |
| 74 | add_project_arguments('-DWIN32', language: 'c') |
| 75 | configuration.set('WIN32', 1) |
| 76 | compile_args += '-DWIN32' |
| 77 | else |
| 78 | warning('Unhandled OS: @0@'.format(system)) |
| 79 | endif |
| 80 | |
| 81 | # Architecture |
| 82 | cpu = host_machine.cpu() |
| 83 | add_project_arguments('-DARCH="@0@"'.format(cpu), language: 'c') |
| 84 | configuration.set_quoted('ARCH', cpu) |
| 85 | |
| 86 | # Dependency: Threads |
| 87 | # TODO: Make this overridable |
| 88 | thread_dep = dependency('threads', required: false) |
| 89 | |
| 90 | # Dependency: OpenSSL |
| 91 | openssl_dep = dependency('openssl', version: '>=0.9.8', required: false) |
| 92 | # TODO: Make this overridable |
| 93 | if 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 |
| 121 | endif |
| 122 | |
| 123 | # Dependency: zlib |
| 124 | # TODO: Make this overridable |
| 125 | # TODO: Arbitrary version, ask maintainers |
| 126 | zlib_dep = dependency('zlib', version: '>=1.2.8', required: false) |
| 127 | if zlib_dep.found() |
| 128 | add_project_arguments('-DUSE_ZLIB', language: 'c') |
| 129 | configuration.set('USE_ZLIB', 1) |
| 130 | compile_args += '-DUSE_ZLIB' |
| 131 | endif |
| 132 | |
| 133 | # Dependencies list |
| 134 | dependencies = [ |
| 135 | thread_dep, |
| 136 | openssl_dep, |
| 137 | zlib_dep, |
| 138 | ] |
| 139 | |
| 140 | # Features: Common |
| 141 | add_project_arguments( |
| 142 | '-DHAVE_INET6', |
| 143 | '-DHAVE_SELECT', |
| 144 | '-DHAVE_STDBOOL_H', |
| 145 | language: 'c') |
| 146 | configuration.set('HAVE_INET6', 1) |
| 147 | configuration.set('HAVE_SELECT', 1) |
| 148 | configuration.set('HAVE_STDBOOL_H', 1) |
| 149 | compile_args += [ |
| 150 | '-DHAVE_INET6', |
| 151 | '-DHAVE_STDBOOL_H', |
| 152 | ] |
| 153 | |
| 154 | # Features: Check for fixed size integer types |
| 155 | if 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' |
| 159 | endif |
| 160 | |
| 161 | # Features: Check for route |
| 162 | have_net_route = compiler.has_header('net/route.h') |
| 163 | if have_net_route |
| 164 | add_project_arguments('-DHAVE_NET_ROUTE_H', language: 'c') |
| 165 | configuration.set('HAVE_NET_ROUTE_H', 1) |
| 166 | endif |
| 167 | |
| 168 | # Features: Check for sysctl |
| 169 | have_sysctl = compiler.has_header('sys/sysctl.h') |
| 170 | if have_sysctl |
| 171 | add_project_arguments('-DHAVE_SYS_SYSCTL_H', language: 'c') |
| 172 | configuration.set('HAVE_SYS_SYSCTL_H', 1) |
| 173 | endif |
| 174 | |
| 175 | # Features: OS-specific |
| 176 | if 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 |
| 194 | else |
| 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 |
| 307 | endif |
| 308 | |
| 309 | # Features: Routing for Linux and *BSD |
| 310 | if 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) |
| 313 | endif |
| 314 | |
| 315 | # Version |
| 316 | version = meson.project_version() |
| 317 | version_array = version.split('.') |
| 318 | add_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') |
| 324 | configuration.set_quoted('VERSION', version) |
| 325 | configuration.set('VER_MAJOR', version_array[0]) |
| 326 | configuration.set('VER_MINOR', version_array[1]) |
| 327 | configuration.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 |
| 338 | include_dir = include_directories('include') |
| 339 | subdir('include') |
| 340 | |
| 341 | # Sources & Modules |
| 342 | # TODO: Make which to build configurable |
| 343 | subdir('src') |
| 344 | |
| 345 | # Build library |
| 346 | re = library(meson.project_name(), sources, |
| 347 | dependencies: dependencies, |
| 348 | include_directories: include_dir, |
| 349 | install: true, |
| 350 | version: version) |
| 351 | |
| 352 | # Install headers |
| 353 | install_headers(includes, subdir: 're') |
| 354 | |
| 355 | # Declare dependency |
| 356 | re_dep = declare_dependency( |
| 357 | compile_args: compile_args, |
| 358 | include_directories: include_dir, |
| 359 | link_with: re) |
| 360 | |
| 361 | # Generate pkg-config file |
| 362 | pkg = import('pkgconfig') |
| 363 | description = '''Generic library for real-time communications with |
| 364 | async IO support''' |
| 365 | description = ' '.join(description.split()) |
| 366 | pkg.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' |