Files
Sergio Ammirata df64a2f1c0 meson: prepare 0.2.18-rc3
Bump API to 4.12.0, ABI to 15:0:11 (soversion 4 unchanged,
binary-compatible with 0.2.15/0.2.16/0.2.17 and rc2).  New interfaces
since rc2: rist_recovery_depth_set() with the
RIST_RECOVERY_DEPTH_MIN/DEFAULT/MAX macros, and the additive stats
fields (RIST_STATS_VERSION 3: profile / seq_bits / advanced_active).

Changes since rc2:
  - Advanced-profile correctness fixes (>64k sequence gaps, ring-index
    masking in receiver_mark_missing, expected-next-seq wrap mask,
    payload-only byte accounting, sequence-based duplicate detection,
    32-bit-safe merge-mode pairing).
  - Default profile is now Advanced with Main interoperability (TR-06-3
    Section 9); risttunnel follows RIST_DEFAULT_PROFILE.
  - Tunable Advanced recovery-ring depth via ?recovery-depth=.
  - Advanced-profile profile/framing visibility in the stats API and the
    Prometheus exporter.
2026-06-21 16:46:17 -04:00

443 lines
14 KiB
Meson
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# librist. Copyright (c) 2019 SipRadius LLC. All right reserved.
# Author: Kuldeep Singh Dhaka <kuldeep@madresistor.com>
# Author: Sergio Ammirata, Ph.D. <sergio@ammirata.net>
# SPDX-License-Identifier: BSD-2-Clause
project('libRIST', 'c',
version: '0.2.18',
default_options: ['c_std=c99', 'warning_level=3', 'libdir=lib'],
meson_version: '>= 0.51.0')
cc = meson.get_compiler('c')
# Configuration data for config.h
cdata = configuration_data()
#librist ABI version, libtool rules (taken from https://github.com/pvanhoof/dir-examples)
#If the library source code has changed at all since the last update, then increment revision (c:r:a becomes c:r+1:a).
#If any interfaces have been added, removed, or changed since the last update, increment current, and set revision to 0.
#If any interfaces have been added since the last public release, then increment age.
#If any interfaces have been removed or changed since the last public release, then set age to 0.
librist_abi_current = 15
librist_abi_revision = 0
librist_abi_age = 11
librist_soversion = librist_abi_current - librist_abi_age
librist_version = '@0@.@1@.@2@'.format(librist_abi_current - librist_abi_age, librist_abi_age, librist_abi_revision)
# libRIST version
#API follows semver rules:
#MAJOR version when you make incompatible API changes,
#MINOR version when you add functionality in a backwards-compatible manner, and
#PATCH not used (doesn't make sense for API version, remains here for backwards compat)
librist_api_version_major = 4
librist_api_version_minor = 12
librist_api_version_patch = 0
librist_src_root = meson.current_source_dir()
deps = []
platform_files = []
inc = []
inc += include_directories('.', 'src', 'include/librist', 'include', 'contrib')
builtin_lz4 = get_option('builtin_lz4')
builtin_cjson = get_option('builtin_cjson')
builtin_mbedtls = get_option('builtin_mbedtls')
if (host_machine.system() == 'darwin'
and not meson.is_cross_build()
and find_program('brew', required : false).found()
and (not builtin_cjson or not builtin_mbedtls))
r = run_command('brew', '--prefix', check: true)
brewoutput = r.stdout().strip()
inc += include_directories(brewoutput + '/include')
endif
use_mbedtls = get_option('use_mbedtls')
use_nettle = get_option('use_nettle')
use_gnutls = get_option('use_gnutls')
if not use_gnutls
if use_nettle
warning('use_nettle is deprecated, use use_gnutls')
endif
use_gnutls = use_nettle
endif
cdata.set10('ALLOW_INSECURE_IV_FALLBACK', get_option('allow_insecure_iv_fallback'))
required_library = false
if not get_option('fallback_builtin')
required_library = true
endif
should_install = true
if meson.is_subproject()
should_install = false
endif
have_pthreads = cc.has_header('pthread.h')
have_clock_gettime = false
threads = []
test_args = []
if host_machine.system() == 'windows'
platform_files += 'src/tun_win.c'
deps += [
cc.find_library('ws2_32'),
cc.find_library('iphlpapi'),
cc.find_library('bcrypt')
]
windows_version_test = '''
#include <windef.h>
#if !defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0600
# error _WIN32_WINNT toolchain default not high enough
#endif
'''
if not cc.compiles(windows_version_test, name: '_WIN32_WINNT includes Vista')
add_project_arguments(['-D_WIN32_WINNT=0x0600'], language: 'c')
endif
if get_option('default_library') != 'static'
add_project_arguments(['-DLIBRIST_BUILDING_DLL'], language: 'c')
endif
if get_option('have_mingw_pthreads')
if have_pthreads
threads = dependency('threads')
deps += threads
cdata.set('HAVE_PTHREADS', 1)
endif
else
have_pthreads = false
endif
# Use has_header_symbol so mingw-w64's static inline clock_gettime
# (in <time.h>, regardless of winpthreads) is detected.
# Must stay outside the have_mingw_pthreads block: modern mingw-w64
# ships the inline unconditionally and contrib/time-shim.c must
# not redefine it.
have_clock_gettime = cc.has_header_symbol('time.h', 'clock_gettime', args : test_args)
if cc.get_id() == 'msvc'
# librist uses C11 features (stdatomic.h, mixed declarations).
# MSVC only exposes them under /std:c11 or /std:c17.
if cc.has_argument('/std:c11')
add_project_arguments(['/std:c11'], language: 'c')
elif cc.has_argument('/std:c17')
add_project_arguments(['/std:c17'], language: 'c')
endif
endif
add_project_arguments(['-DWIN32_LEAN_AND_MEAN'], language: 'c')
add_project_arguments(['-D__USE_MINGW_ANSI_STDIO=1'], language: 'c')
add_project_arguments(['-D_CRT_NONSTDC_NO_DEPRECATE'], language: 'c')
add_project_arguments(['-D_CRT_SECURE_NO_WARNINGS'], language: 'c')
add_project_arguments(cc.get_supported_arguments(['-wd4996', '-wd4324']), language: 'c')
#Windows meson tends to break on pkgconfig/Cmake finding, so use builtin libraries
librist_soversion = ''
else
if host_machine.system() == 'linux' or host_machine.system() == 'android'
platform_files += 'src/tun_linux.c'
test_args += '-D_GNU_SOURCE'
add_project_arguments('-D_GNU_SOURCE', language: 'c')
if cc.check_header('linux/if_alg.h')
add_project_arguments(['-DLINUX_CRYPTO'], language: 'c')
platform_files += 'contrib/linux-crypto.c'
endif
checkgetif = '''
#include <ifaddrs.h>
void test(void) {
struct ifaddrs *ifaddr = NULL;
getifaddrs(&ifaddr);
}
'''
hasgetifaddrs = cc.compiles(checkgetif)
if not hasgetifaddrs and host_machine.system() == 'android'
platform_files += 'compat/android/ifaddrs.c'
inc += include_directories('compat/android')
endif
elif host_machine.system() == 'darwin'
platform_files += 'src/tun_darwin.c'
test_args += '-D_DARWIN_C_SOURCE'
add_project_arguments('-D_DARWIN_C_SOURCE', language: 'c')
elif host_machine.system() == 'gnu'
test_args += '-D_GNU_SOURCE'
add_project_arguments('-D_GNU_SOURCE', language: 'c')
elif host_machine.system() == 'emscripten'
platform_files += 'src/tun_emscripten.c'
add_project_arguments('-D_GNU_SOURCE', language: 'c')
endif
librist_soversion = librist_soversion
if host_machine.system() == 'emscripten'
have_clock_gettime = true
else
have_clock_gettime = cc.has_function('clock_gettime', prefix : '#include <time.h>', args : test_args)
if not have_clock_gettime and host_machine.system() != 'darwin'
lib_rt = cc.find_library('rt', required: false)
have_clock_gettime = cc.has_function('clock_gettime', prefix : '#include <time.h>', args : test_args, dependencies : lib_rt)
if not have_clock_gettime
error('clock_gettime not found')
endif
deps += [ lib_rt ]
endif
endif
add_project_arguments(['-Wshadow', '-pedantic-errors'], language: 'c')
add_project_arguments(cc.get_supported_arguments([
'-Wundef',
'-Werror=vla',
'-Wno-maybe-uninitialized',
'-Wno-missing-field-initializers',
'-Wno-unused-parameter',
'-Wshorten-64-to-32',
'-Wunused-parameter',
'-Wmaybe-uninitialized',
'-Wno-error=deprecated-declarations'
]), language : 'c')
if host_machine.system() != 'emscripten'
threads = [ dependency('threads') ]
endif
if host_machine.system() != 'freebsd' and host_machine.system() != 'emscripten'
add_project_arguments(cc.get_supported_arguments([
'-Watomic-implicit-seq-cst']), language: 'c')
endif
deps += threads
endif
cdata.set10('HAVE_CLOCK_GETTIME', have_clock_gettime)
cdata.set10('HAVE_PTHREADS', have_pthreads)
sock_un_h = cc.has_header('sys/un.h')
cdata.set10('HAVE_SOCK_UN_H', sock_un_h)
microhttpd = dependency('libmicrohttpd', required: false)
cdata.set10('HAVE_LIBMICROHTTPD', microhttpd.found())
if microhttpd.found()
code = '''
#include <microhttpd.h>
static enum MHD_Result test(void) {
return MHD_NO;
}'''
cdata.set10('MICROHTTPD_HAS_RESULT_ENUM',cc.compiles(code, dependencies: [microhttpd], name: 'libmicrohttpd has MHD_Result enum'))
code = '''
#include <microhttpd.h>
static void test(void) {
MHD_start_daemon(MHD_USE_AUTO_INTERNAL_THREAD, 0, NULL, NULL, NULL, NULL, MHD_OPTION_END);
}'''
cdata.set10('MICROHTTPD_HAS_AUTO_INTERNAL_THREAD',cc.compiles(code, dependencies: [microhttpd], name: 'libmicrohttpd has MHD_USE_AUTO_INTERNAL_THREAD flag'))
endif
compile_prometheus = sock_un_h or microhttpd.found()
cdata.set10('HAVE_PROMETHEUS_SUPPORT', compile_prometheus)
if cc.has_argument('-fvisibility=hidden')
add_project_arguments('-fvisibility=hidden', language: 'c')
else
warning('Compiler does not support -fvisibility=hidden, all symbols will be public!')
endif
# Header checks
stdatomic_dependency = []
if not cc.check_header('stdatomic.h')
if cc.get_id() == 'msvc'
# we have a custom replacement for MSVC
stdatomic_dependency = declare_dependency(
include_directories : include_directories('compat/msvc'),
)
elif cc.compiles('''int main() { int v = 0; return __atomic_fetch_add(&v, 1, __ATOMIC_SEQ_CST); }''',
name : 'GCC-style atomics', args : test_args)
stdatomic_dependency = declare_dependency(
include_directories : include_directories('compat/gcc'),
)
else
error('Atomics not supported')
endif
endif
#On ubuntu cjson does not come with pkgconfig files, hence the extended checking.
if not builtin_cjson
cjson_lib = dependency('libcjson', required: false)
if not cjson_lib.found()
cjson_lib = cc.find_library('cjson', required: required_library, has_headers: ['cjson/cJSON.h'])
if not cjson_lib.found()
builtin_cjson = true
endif
endif
endif
if builtin_cjson
message('Using builtin cJSON library')
cjson_lib = declare_dependency( compile_args : '-DCJSON_HIDE_SYMBOLS',
sources: 'contrib/contrib_cJSON/cjson/cJSON.c',
include_directories : include_directories('contrib/contrib_cJSON'))
endif
if not builtin_lz4
lz4_lib = dependency('liblz4', required: false)
if not lz4_lib.found()
lz4_lib = cc.find_library('lz4', required: required_library, has_headers: ['lz4.h'])
if not lz4_lib.found()
builtin_lz4 = true
endif
endif
endif
if builtin_lz4
message('Using builtin LZ4 library')
lz4_lib = declare_dependency(
sources: 'contrib/lz4/lz4.c',
include_directories : include_directories('contrib/lz4'))
endif
crypto_deps = []
mbedcrypto_lib_found = false
if use_mbedtls
message('Building mbedtls')
subdir('contrib/mbedtls')
crypto_deps += mbedcrypto_lib
elif use_gnutls
crypto_deps = [dependency('nettle'), dependency('hogweed')]
test_mini_gmp = '''
#include <nettle/bignum.h>
#if !NETTLE_USE_MINI_GMP
#error "Need to link gmp"
#endif
'''
if not cc.compiles(test_mini_gmp, name: 'Nettle with mini-gmp?', dependencies: crypto_deps)
crypto_deps += dependency('gmp')
endif
crypto_deps += dependency('gnutls')#Just for random numbers at the moment :/
endif
deps += crypto_deps
subdir('include')
filter_obj = false
objcopy = find_program('objcopy', native: true, required: false)
if get_option('allow_obj_filter') and cc.get_id() == 'clang'
error('allow_obj_filter doesn\'t work with clang due to it not supporting pre-linking')
endif
if get_option('allow_obj_filter') and get_option('default_library') != 'shared' and not get_option('b_lto')
if objcopy.found()
message('Using objcopy to localize symbols in static library')
filter_obj = true
else
error('objcopy not found, unable to localize symbols in static library')
endif
endif
if not mbedcrypto_lib_found and not use_gnutls
platform_files += [
'contrib/aes.c',
'contrib/sha256.c',
'contrib/fastpbkdf2.c',
]
endif
have_srp = mbedcrypto_lib_found or use_gnutls
platform_files += 'src/crypto/random.c'
if have_srp
platform_files += 'src/proto/eap.c'
platform_files += 'src/crypto/srp_constants.c'
platform_files += 'src/crypto/srp.c'
endif
cdata.set10('HAVE_MBEDTLS', mbedcrypto_lib_found)
cdata.set10('HAVE_NETTLE', use_gnutls and not mbedcrypto_lib_found)
# Generate config.h
config_file = configure_file(output: 'config.h', configuration: cdata)
librist = library('librist',
'src/crypto/crypto.c',
'src/crypto/psk.c',
'src/proto/gre.c',
'src/proto/rtp.c',
'src/proto/rist_time.c',
'src/flow.c',
'src/logging.c',
'src/network.c',
'src/adv.c',
'src/adv_ctrl.c',
'src/rist.c',
'src/rist-common.c',
'src/rist_ref.c',
'src/rist-thread.c',
'src/mpegts.c',
'src/peer.c',
'src/udp.c',
'src/transport.c',
'src/stats.c',
'src/udpsocket.c',
'src/libevsocket.c',
'contrib/stdio-shim.c',
'contrib/time-shim.c',
'contrib/pthread-shim.c',
config_file,
platform_files,
rev_target,
include_directories: inc,
dependencies: [
deps,
stdatomic_dependency,
cjson_lib,
lz4_lib,
],
name_prefix : '',
version: librist_version,
soversion: librist_soversion,
prelink: filter_obj,
install: should_install)
objcopy_fake_file = ''
if filter_obj
lib_target = librist
if get_option('default_library') == 'both'
lib_target = librist.get_static_lib()
endif
objcopy_fake_file = custom_target('librist',
input: lib_target,
output: 'librist.is-stripped',
capture: true,
command: [
objcopy,
'--localize-hidden',
'-w',
'--localize-symbol=!rist*',
'--localize-symbol=!librist*',
'--localize-symbol=!udpsocket*',
'--localize-symbol=!evsocket*',
'--localize-symbol=*',
'@INPUT@',
],
build_by_default: true,
)
endif
pkg_mod = import('pkgconfig')
pkg_mod.generate(
libraries: librist,
version: meson.project_version(),
name: 'librist',
description: 'Reliable Internet Stream Transport (RIST)',
)
if get_option('static_analyze')
run_target('cppcheck', command : ['cppcheck',
'--quiet',
'--std=c99',
'--suppressions-list=' + join_paths(librist_src_root, 'common/configs/cppcheck-suppressions.txt'),
'--project=' + join_paths(meson.build_root(),
'compile_commands.json')])
run_target('analyze', command: ['bash', join_paths(librist_src_root, 'common/scripts/analyze.sh')])
endif
librist_dep = declare_dependency(include_directories: inc, link_with : librist, dependencies : stdatomic_dependency)
if get_option('built_tools')
message('Building tools')
subdir('tools')
endif
if get_option('test')
subdir('test')
endif