1
0
mirror of https://github.com/pgbackrest/pgbackrest.git synced 2026-10-23 21:28:56 +03:00
Files
pgbackrest/meson.build
David Steele 84b031af68 Require the header when checking for libbacktrace.
On Linux gcc ships libbacktrace.a in its library directory and backtrace.h in its private include directory. Both compilers search the library directory but only gcc searches that include directory, so a clang build reported the library as found and then failed to compile stackTrace.c.
2026-08-18 21:00:28 +07:00

296 lines
12 KiB
Meson

####################################################################################################################################
# pgBackRest Project
####################################################################################################################################
project(
'pgbackrest',
['c'],
version: '2.60.0dev',
license: 'MIT',
meson_version: '>=0.55.3',
default_options: [
# Core options
'buildtype=release',
'warning_level=2',
# Base options
'b_ndebug=if-release',
# Perform unity builds in a single file
'unity_size=100000',
# Compiler options
'c_std=c11',
],
)
# Selected C compiler
cc = meson.get_compiler('c')
####################################################################################################################################
# Check for C11 compiler support (setting c_std has no effect -- works in 1.8.1 so likely a bug in our version)
####################################################################################################################################
c11_test = '''
#if !defined __STDC_VERSION__ || __STDC_VERSION__ < 201112L
# error "C compiler does not advertise C11 conformance"
#endif
'''
if not cc.compiles(c11_test)
if cc.compiles(c11_test, args: '-std=c11')
add_project_arguments('-std=c11', language: 'c')
else
error('C compiler does not support C11')
endif
endif
####################################################################################################################################
# OS-specific settings
####################################################################################################################################
if host_machine.system() == 'linux'
add_global_arguments('-D_POSIX_C_SOURCE=200809L', language: 'c')
elif host_machine.system() == 'darwin'
add_global_arguments('-D_DARWIN_C_SOURCE', language: 'c')
endif
####################################################################################################################################
# Enable/disable warnings
####################################################################################################################################
# Enable as many additional warnings as possible to catch potential errors
warning_enable = [
# Warn whenever a pointer is cast so as to remove a type qualifier from the target type
'-Wcast-qual',
# Warn for implicit conversions that may alter a value
'-Wconversion',
# Warn about duplicated conditions in an if-else-if chain
'-Wduplicated-cond',
# Warn when an if-else has identical branches
'-Wduplicated-branches',
# Warn if floating-point values are used in equality comparisons
'-Wfloat-equal',
# Enable -Wformat plus -Wnonnull, -Wformat-nonliteral, -Wformat-security, and -Wformat-y2k
'-Wformat=2',
# Warn about calls to formatted input/output functions such as sprintf and vsprintf that might overflow the destination buffer
'-Wformat-overflow=2',
# Warn if the format string requires an unsigned argument and the argument is signed and vice versa
'-Wformat-signedness',
# Warn about uninitialized variables which are initialized with themselves
'-Winit-self',
# Warn if a global function is defined without a previous prototype declaration
'-Wmissing-prototypes',
# Warn if a global variable is defined without a previous declaration
'-Wmissing-variable-declarations',
# Warn about anything that depends on the "size of" a function type or of void
'-Wpointer-arith',
# Warn if anything is declared more than once in the same scope, even when the extra declaration is valid and changes nothing
'-Wredundant-decls',
# Warn if a function is declared or defined without specifying the argument types
'-Wstrict-prototypes',
# Warn if a variable-length array is used
'-Wvla',
# Give string constants the type const char[length] so that copying the address of one into a non-const char * pointer produces
# a warning
'-Wwrite-strings',
]
# Disable various unhelpful warnings
warning_disable = [
# Warn for variables that might be changed by longjmp or vfork. Disable because of constant false positives/negatives.
'-Wno-clobbered',
# Warn if a structure's initializer has some fields missing. Disable so we can initialize with {0}.
'-Wno-missing-field-initializers',
]
add_project_arguments(cc.get_supported_arguments(warning_enable, warning_disable), language: 'c')
####################################################################################################################################
# Enable additional optimizations for appropriate levels
####################################################################################################################################
if get_option('optimization') in ['2', '3']
optimization_enable = [
# Unroll loops whose number of iterations can be determined at compile time or upon entry to the loop
'-funroll-loops',
# Perform loop vectorization on trees
'-ftree-vectorize',
]
add_project_arguments(cc.get_supported_arguments(optimization_enable), language: 'c')
endif
####################################################################################################################################
# Stop after the first error when error on warn enabled. Subsequent errors are often caused by the first error.
####################################################################################################################################
if get_option('fatal-errors')
add_project_arguments(cc.get_supported_arguments('-Wfatal-errors'), language: 'c')
endif
####################################################################################################################################
# Generate -fmacro-prefix-map so the relative path to the source directory is not included in the __FILE__ macro. This provides
# reproducible builds and minimizes the file path in debug messages, just like an in-tree make build. For test source, prefix with
# test/ in case there are any module name collisions.
####################################################################################################################################
python = import('python').find_installation()
file_prefix = run_command(
[
python,
'-c',
'import sys, os; print(os.path.relpath(sys.argv[1], sys.argv[2]))',
meson.current_source_dir(),
meson.current_build_dir(),
],
check: true,
).stdout().strip()
add_project_arguments(cc.get_supported_arguments('-fmacro-prefix-map=@0@/src/=' . format(file_prefix)), language: 'c')
add_project_arguments(cc.get_supported_arguments('-fmacro-prefix-map=@0@/test/src/=test/' . format(file_prefix)), language: 'c')
####################################################################################################################################
# Detect a distribution tarball, which is marked by the dist file written into the tarball root by meson dist. A distribution
# tarball ships the generated files, so the code generation tooling (build.py, the doc and test tools) is not used. A normal source
# tree such as a git checkout has no marker and generates the files.
####################################################################################################################################
dist = run_command(
[
python,
'-c',
'import os, sys; sys.exit(0 if os.path.exists(os.path.join(sys.argv[1], "dist")) else 1)',
meson.current_source_dir(),
],
check: false,
).returncode() == 0
####################################################################################################################################
# Build configuration
####################################################################################################################################
configuration = configuration_data()
# Ensure the C compiler supports __builtin_clzl()
if not cc.links('''int main(void) {__builtin_clzl(1);}''')
error('compiler must support __builtin_clzl()')
endif
# Ensure the C compiler supports __builtin_bswap64()
if not cc.links('''int main(void) {__builtin_bswap64(1);}''')
error('compiler must support __builtin_bswap64()')
endif
# Check C compiler support for __builtin_types_compatible_p
if cc.compiles('''int main(void) {__builtin_types_compatible_p(char *, const char *);}''')
configuration.set('HAVE_BUILTIN_TYPES_COMPATIBLE_P', true, description: 'Is __builtin_types_compatible_p present?')
endif
# Find optional backtrace library
lib_backtrace = cc.find_library('backtrace', required: false, has_headers: 'backtrace.h')
if lib_backtrace.found()
configuration.set('HAVE_LIBBACKTRACE', true, description: 'Is libbacktrace present?')
endif
# Find required bz2 library
lib_bz2 = cc.find_library('bz2')
# Find required lz4 library
lib_lz4 = dependency('liblz4')
# Find required openssl library
lib_openssl = dependency('openssl', version : '>=1.1.1')
# Find required pq library
lib_pq = dependency('libpq')
# Find required xml library
lib_xml = dependency('libxml-2.0')
# Find required gz library
lib_z = dependency('zlib')
configuration.set('ZLIB_CONST', true, description: 'Require zlib const input buffer')
# Find optional systemd library
lib_systemd = dependency('libsystemd', required: get_option('libsystemd'))
if lib_systemd.found()
configuration.set('HAVE_LIBSYSTEMD', true, description: 'Is libsystemd present?')
endif
# Find optional libssh2 library
lib_ssh2 = dependency('libssh2', required: get_option('libssh2'))
if lib_ssh2.found()
configuration.set('HAVE_LIBSSH2', true, description: 'Is libssh2 present?')
endif
# Find optional zstd library
lib_zstd = dependency('libzstd', version: '>=1.0', required: get_option('libzstd'))
if lib_zstd.found()
configuration.set('HAVE_LIBZST', true, description: 'Is libzstd present?')
endif
# Suppress -Wsign-conversion for C libraries (e.g. musl) that do no accept int without warning for FD_*() macros
if not cc.compiles(
'''#include <sys/select.h>
int main(void) {int fd = 1; fd_set s; FD_ZERO(&s); FD_SET(fd, &s); FD_ISSET(fd, &s);}''',
args: ['-Wsign-conversion', '-Werror'])
message('Disabling -Wsign-conversion because int is not accepted without warning by FD_*() macros')
add_project_arguments(cc.get_supported_arguments('-Wno-sign-conversion'), language: 'c')
endif
# Enable debug code
if get_option('debug')
configuration.set('DEBUG', true, description: 'Enable debug code')
# Enable Valgrind memcheck client requests when the header is available so allocators that retain freed memory for reuse keep
# use-after-free and uninitialized-read detection accurate under Valgrind. The requests are no-ops when not run under Valgrind.
if cc.has_header('valgrind/memcheck.h')
add_project_arguments('-DWITH_VALGRIND', language: 'c')
endif
endif
# Set configuration path
configuration.set_quoted('CFGOPTDEF_CONFIG_PATH', get_option('configdir'), description: 'Configuration path')
# Set VR_NON_STRING macro
if cc.compiles(
'''int main(void) {__attribute__((nonstring)) static char test[3] = "ABC";}''',
args: ['-Wattributes', '-Werror'])
configuration.set(
'VR_NON_STRING', '__attribute__((nonstring))',
description: 'Indicate that the char array is intentionally not NULL terminated')
else
configuration.set(
'VR_NON_STRING', '', description: 'Indicate that the char array is intentionally not NULL terminated')
endif
####################################################################################################################################
# Include subdirs
####################################################################################################################################
subdir('src')
# The smoke test is shipped in the distribution so packagers can verify a build. It is in a subdir because unit test builds comment
# out all subdirs, which excludes the smoke test from them.
subdir('test')
# A distribution tarball ships the generated files, so it neither generates them nor bakes them in
if not dist
# Bake the generated files and the dist marker into the tarball so it builds without the code generation tooling
meson.add_dist_script('build/dist.sh')
endif