diff options
author | David Robillard <d@drobilla.net> | 2022-06-28 14:30:55 -0400 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2022-06-28 15:10:13 -0400 |
commit | b5a4d1f58efd8e7976349ac2592b5ae2dbb86fc2 (patch) | |
tree | 393e01dfa4dbf60de1173dd43346a50762e8db66 | |
parent | 12775e4e85fdfbf4690ee8f0ad46dbcf2a212b40 (diff) | |
download | zix-b5a4d1f58efd8e7976349ac2592b5ae2dbb86fc2.tar.gz zix-b5a4d1f58efd8e7976349ac2592b5ae2dbb86fc2.tar.bz2 zix-b5a4d1f58efd8e7976349ac2592b5ae2dbb86fc2.zip |
Clean up meson configuration
-rw-r--r-- | meson.build | 338 | ||||
-rw-r--r-- | meson/library/meson.build | 31 | ||||
-rw-r--r-- | meson/suppressions/meson.build | 73 | ||||
-rw-r--r-- | meson/warnings/meson.build | 174 | ||||
-rw-r--r-- | meson_options.txt | 2 |
5 files changed, 384 insertions, 234 deletions
diff --git a/meson.build b/meson.build index 2700a76..62314c2 100644 --- a/meson.build +++ b/meson.build @@ -1,184 +1,39 @@ -# Copyright 2020-2021 David Robillard <d@drobilla.net> +# Copyright 2020-2022 David Robillard <d@drobilla.net> # SPDX-License-Identifier: CC0-1.0 OR ISC project('zix', ['c'], version: '0.0.3', license: 'ISC', - meson_version: '>= 0.49.0', + meson_version: '>= 0.56.0', default_options: [ 'b_ndebug=if-release', 'buildtype=release', 'c_std=c99', - 'default_library=shared', - 'warning_level=3', ]) major_version = meson.project_version().split('.')[0] version_suffix = '-@0@'.format(major_version) versioned_name = 'zix' + version_suffix -# -# General Setup -# +####################### +# Compilers and Flags # +####################### -# Load build tools +# Required tools pkg = import('pkgconfig') cc = meson.get_compiler('c') -# Suppress unavoidable present even in default build -c_warnings = [] -c_suppressions = [] -if cc.get_id() == 'clang' - c_warnings = [ - '-Wno-nullability-extension', - ] -elif cc.get_id() == 'msvc' - c_warnings += [ - '/wd4706', # assignment within conditional expression - ] +# Set global warning flags +if get_option('strict') and not meson.is_subproject() + subdir('meson/warnings') endif +subdir('meson/suppressions') -# Set ultra strict warnings for developers, if requested -if get_option('strict') - if cc.get_id() == 'clang' - c_warnings += [ - '-Weverything', - '-Wno-bad-function-cast', - '-Wno-c11-extensions', # Glib - '-Wno-implicit-fallthrough', # Really for clang < 12 - '-Wno-padded', - '-Wno-reserved-id-macro', - ] - elif cc.get_id() == 'gcc' - c_warnings += [ - # '-Waggregate-return', - '-Walloc-size-larger-than=16384', - '-Walloc-zero', - '-Walloca', - '-Wanalyzer-too-complex', - '-Warith-conversion', - '-Warray-bounds=2', - '-Wattribute-alias=2', - '-Wcast-align=strict', - '-Wcast-qual', - '-Wconversion', - '-Wdate-time', - '-Wdisabled-optimization', - '-Wdouble-promotion', - '-Wduplicated-branches', - '-Wduplicated-cond', - '-Wfloat-equal', - '-Wformat-overflow=2', - '-Wformat-signedness', - '-Wformat-truncation=2', - '-Wformat=2', - '-Wframe-larger-than=2048', - '-Wimplicit-fallthrough=2', - '-Winit-self', - # '-Winline', - '-Winvalid-pch', - # '-Wlarger-than=', - '-Wlogical-op', - '-Wmissing-declarations', - '-Wmissing-include-dirs', - '-Wmultichar', - '-Wnormalized=nfc', - '-Wnull-dereference', - '-Wpacked', - # '-Wpadded', - '-Wredundant-decls', - '-Wscalar-storage-order', - '-Wshadow', - '-Wshift-overflow=2', - '-Wsizeof-array-argument', - '-Wstack-protector', - '-Wstack-usage=2048', - '-Wstrict-aliasing=3', - # '-Wstrict-overflow=5', - '-Wstringop-overflow=3', - '-Wsuggest-attribute=cold', - '-Wsuggest-attribute=const', - '-Wsuggest-attribute=format', - '-Wsuggest-attribute=malloc', - '-Wsuggest-attribute=noreturn', - '-Wsuggest-attribute=pure', - # '-Wswitch-default', - '-Wswitch-enum', - '-Wsync-nand', - # '-Wsystem-headers', - # '-Wtraditional', - # '-Wtraditional-conversion', - '-Wtrampolines', - '-Wundef', - '-Wunused-const-variable=2', - '-Wunused-macros', - '-Wvarargs', - '-Wvector-operation-performance', - '-Wvla', - '-Wwrite-strings', - ] - elif cc.get_id() == 'msvc' - c_warnings += [ - '/Wall', # everything, except... - '/wd4191', # unsafe function conversion - '/wd4200', # zero-sized array in struct/union - '/wd4365', # signed/unsigned mismatch - '/wd4514', # unreferenced inline function has been removed - '/wd4710', # function not inlined - '/wd4711', # function selected for automatic inline expansion - '/wd4777', # format string and argument mismatch - '/wd4800', # implicit conversion to bool - '/wd4820', # padding added after construct - '/wd5045', # will insert Spectre mitigation for memory load - ] - endif - - if cc.get_id() == 'gcc' and host_machine.system() == 'windows' - c_warnings += [ - '-Wno-cast-function-type', - '-Wno-format', - '-Wno-suggest-attribute=format', - '-Wno-suggest-attribute=pure', - ] - endif - -endif - -add_project_arguments(cc.get_supported_arguments(c_warnings), language: ['c']) +add_project_arguments(all_c_warnings + c_suppressions, language: ['c']) -if cc.get_id() == 'msvc' - # Build as C++ - add_project_arguments(['/TP'], language: ['c']) - - # Suppress warnings in system headers - add_project_arguments(['/experimental:external', - '/external:W0', - '/external:anglebrackets'], - language: ['c']) -endif - -# Determine library type and the flags needed to build it -if get_option('default_library') == 'both' - if host_machine.system() == 'windows' - error('default_library=both is not supported on Windows') - endif - - library_type = 'both_libraries' - library_args = ['-DZIX_INTERNAL'] - prog_args = [] -elif get_option('default_library') == 'shared' - library_type = 'shared_library' - library_args = ['-DZIX_INTERNAL'] - prog_args = [] -else - library_type = 'static_library' - library_args = ['-DZIX_INTERNAL', '-DZIX_STATIC'] - prog_args = ['-DZIX_STATIC'] -endif - -# -# System Checks and Dependencies -# +################ +# Dependencies # +################ # Check for mlock() (used by ZixRing) mlock_fragment = '''#include <sys/mman.h> @@ -187,11 +42,28 @@ if cc.compiles(mlock_fragment, name: 'mlock') add_project_arguments(['-DHAVE_MLOCK'], language: 'c') endif -# -# Library -# +########### +# Library # +########### + +include_dirs = include_directories(['include']) -sources = [ +c_headers = files( + 'include/zix/allocator.h', + 'include/zix/attributes.h', + 'include/zix/bitset.h', + 'include/zix/btree.h', + 'include/zix/bump_allocator.h', + 'include/zix/common.h', + 'include/zix/digest.h', + 'include/zix/hash.h', + 'include/zix/ring.h', + 'include/zix/sem.h', + 'include/zix/thread.h', + 'include/zix/tree.h', +) + +sources = files( 'src/allocator.c', 'src/bitset.c', 'src/btree.c', @@ -200,99 +72,101 @@ sources = [ 'src/hash.c', 'src/ring.c', 'src/tree.c', -] +) -# Build shared and/or static library/libraries -libzix = build_target( - versioned_name, +# Set appropriate arguments for building against the library type +subdir('meson/library') +if get_option('default_library') == 'static' + add_project_arguments(['-DZIX_STATIC'], language: ['c']) +endif + +# Build shared and/or static library +libzix = library( + meson.project_name() + library_suffix, sources, - version: meson.project_version(), - include_directories: include_directories(['include']), - c_args: library_args, + c_args: ['-DZIX_INTERNAL'], gnu_symbol_visibility: 'hidden', + include_directories: include_dirs, install: true, - target_type: library_type) + version: meson.project_version()) +# Declare dependency for internal meson dependants zix_dep = declare_dependency( - link_with: libzix, - include_directories: include_directories(['include'])) - -# -# Installation -# + include_directories: include_dirs, + link_with: libzix) -# Generage pkg-config file +# Generage pkg-config file for external dependants pkg.generate( libzix, - name: 'Zix', + description: 'A lightweight portability and data structure C library', filebase: versioned_name, + name: 'Zix', subdirs: [versioned_name], - version: meson.project_version(), - description: 'A lightweight portability and data structure C library') - -headers = [ - 'include/zix/allocator.h', - 'include/zix/attributes.h', - 'include/zix/bitset.h', - 'include/zix/btree.h', - 'include/zix/bump_allocator.h', - 'include/zix/common.h', - 'include/zix/digest.h', - 'include/zix/hash.h', - 'include/zix/ring.h', - 'include/zix/sem.h', - 'include/zix/thread.h', - 'include/zix/tree.h', -] + version: meson.project_version()) # Install headers to a versioned include directory -install_headers(headers, subdir: versioned_name / 'zix') +install_headers(c_headers, subdir: versioned_name / 'zix') -# -# Tests -# +######### +# Tests # +######### -tests = [ +sequential_tests = [ 'allocator_test', 'bitset_test', 'btree_test', 'digest_test', 'hash_test', - 'ring_test', - 'sem_test', 'strerror_test', 'tree_test', ] -# Build and run tests -if get_option('tests') +threaded_tests = [ + 'ring_test', + 'sem_test', +] + +if not get_option('tests').disabled() # Check licensing metadata - reuse = find_program('reuse', required: false) + reuse = find_program('reuse', required: get_option('tests')) if reuse.found() - test('REUSE', reuse, + test('REUSE', + reuse, args: ['--root', meson.current_source_dir(), 'lint'], suite: 'data') endif - thread_dep = dependency('threads') - dl_dep = cc.find_library('dl', required: false) + common_test_sources = files('test/failing_allocator.c') - foreach test : tests - sources = files('test/@0@.c'.format(test), 'test/failing_allocator.c') + foreach test : sequential_tests + sources = common_test_sources + files('test/@0@.c'.format(test)) test(test, executable(test, sources, - include_directories: include_directories(['include']), - c_args: prog_args, - dependencies: [dl_dep, zix_dep, thread_dep]), + dependencies: [zix_dep], + include_directories: include_dirs), timeout: 120) endforeach + + thread_dep = dependency('threads', required: get_option('tests')) + if thread_dep.found() + foreach test : threaded_tests + sources = common_test_sources + files('test/@0@.c'.format(test)) + + test(test, + executable(test, + sources, + dependencies: [zix_dep, thread_dep], + include_directories: include_dirs), + timeout: 120) + endforeach + endif endif -# -# Benchmarks -# +############## +# Benchmarks # +############## benchmarks = [ 'dict_bench', @@ -302,37 +176,35 @@ benchmarks = [ build_benchmarks = false if not get_option('benchmarks').disabled() glib_dep = dependency('glib-2.0', - version: '>= 2.0.0', - required: get_option('benchmarks')) + required: get_option('benchmarks'), + version: '>= 2.0.0') - build_benchmarks = glib_dep.found() + if glib_dep.found() + build_benchmarks = true - benchmark_c_args = [] - if cc.get_id() == 'clang' - benchmark_c_args += [ - '-Wno-reserved-identifier', - ] - endif + benchmark_c_args = [] + if cc.get_id() == 'clang' + benchmark_c_args += [ + '-Wno-reserved-identifier', + ] + endif - benchmark_c_args = cc.get_supported_arguments(benchmark_c_args) + benchmark_c_args = cc.get_supported_arguments(benchmark_c_args) - if build_benchmarks foreach benchmark : benchmarks benchmark(benchmark, executable(benchmark, 'benchmark/@0@.c'.format(benchmark), - include_directories: include_directories(['include']), + include_directories: include_dirs, c_args: benchmark_c_args, dependencies: [zix_dep, glib_dep])) endforeach - else - warning('Not building benchmarks because glib was not found') endif endif -if not meson.is_subproject() and meson.version().version_compare('>=0.53.0') +if not meson.is_subproject() summary('Benchmarks', build_benchmarks, bool_yn: true) - summary('Tests', get_option('tests'), bool_yn: true) + summary('Tests', not get_option('tests').disabled(), bool_yn: true) summary('Install prefix', get_option('prefix')) summary('Headers', get_option('prefix') / get_option('includedir')) diff --git a/meson/library/meson.build b/meson/library/meson.build new file mode 100644 index 0000000..fffc831 --- /dev/null +++ b/meson/library/meson.build @@ -0,0 +1,31 @@ +# Copyright 2020-2022 David Robillard <d@drobilla.net> +# SPDX-License-Identifier: CC0-1.0 OR ISC + +# General definitions for building libraries. +# +# These are essentially workarounds for Meson/Windows/MSVC. Unfortunately, +# Meson's default_library option doesn't support shared and static builds very +# well. In particular, it's often necessary to define different symbols for +# static and shared builds of libraries so that symbols can be exported. To +# work around this, default_library=both isn't supported on Windows. On other +# platforms with GCC-like compilers, we can support both because symbols can +# safely be exported in the same way (giving them default visibility) in both +# static and shared builds. + +default_library = get_option('default_library') +host_system = host_machine.system() + +# Abort on Windows with default_library=both +if host_system == 'windows' and default_library == 'both' + error('default_library=both is not supported on Windows') +endif + +# Set library_suffix to the suffix for libraries +if host_system == 'windows' and default_library == 'shared' + # Meson appends a version to the name only for DLLs, which leads to + # inconsistent library names, like `mylib-1-1`. So, provide no suffix to + # ultimately get the same name as on other platforms, like `mylib-1`. + library_suffix = '' +else + library_suffix = '-@0@'.format(meson.project_version().split('.')[0]) +endif diff --git a/meson/suppressions/meson.build b/meson/suppressions/meson.build new file mode 100644 index 0000000..1ffc1a0 --- /dev/null +++ b/meson/suppressions/meson.build @@ -0,0 +1,73 @@ +# Copyright 2020-2022 David Robillard <d@drobilla.net> +# SPDX-License-Identifier: CC0-1.0 OR ISC + +# Project-specific warning suppressions. +# +# This should be used in conjunction with the generic "warnings" sibling that +# enables all reasonable warnings for the compiler. It lives here just to keep +# the top-level meson.build more readable. + +##### +# C # +##### + +if is_variable('cc') + c_suppressions = [] + + if get_option('strict') + if cc.get_id() == 'clang' + c_suppressions += [ + '-Wno-bad-function-cast', + '-Wno-c11-extensions', # Glib + '-Wno-implicit-fallthrough', # Really for clang < 12 + '-Wno-padded', + '-Wno-reserved-id-macro', + ] + + elif cc.get_id() == 'gcc' + c_suppressions += [ + '-Wno-bad-function-cast', + '-Wno-cast-function-type', + '-Wno-inline', + '-Wno-padded', + '-Wno-strict-overflow', + '-Wno-switch-default', + '-Wno-unsuffixed-float-constants', + ] + + if host_machine.system() == 'windows' + c_suppressions += [ + '-Wno-format', + '-Wno-suggest-attribute=format', + '-Wno-suggest-attribute=pure', + ] + endif + + elif cc.get_id() == 'msvc' + c_suppressions += [ + '/wd4191', # unsafe function conversion + '/wd4200', # zero-sized array in struct/union + '/wd4365', # signed/unsigned mismatch + '/wd4514', # unreferenced inline function has been removed + '/wd4710', # function not inlined + '/wd4711', # function selected for automatic inline expansion + '/wd4777', # format string and argument mismatch + '/wd4800', # implicit conversion to bool + '/wd4820', # padding added after construct + '/wd5045', # will insert Spectre mitigation for memory load + ] + endif + endif + + if cc.get_id() == 'clang' + c_suppressions += [ + '-Wno-nullability-extension', + ] + elif cc.get_id() == 'msvc' + c_suppressions += [ + '/wd4706', # assignment within conditional expression + ] + endif + + c_suppressions = cc.get_supported_arguments(c_suppressions) +endif diff --git a/meson/warnings/meson.build b/meson/warnings/meson.build new file mode 100644 index 0000000..f9cc63f --- /dev/null +++ b/meson/warnings/meson.build @@ -0,0 +1,174 @@ +# Copyright 2020-2022 David Robillard <d@drobilla.net> +# SPDX-License-Identifier: CC0-1.0 OR ISC + +# General code to enable approximately all warnings in GCC 12, clang, and MSVC. +# +# This is trivial for clang and MSVC, but GCC doesn't have an "everything" +# option, so we need to enable everything we want explicitly. Wall is assumed, +# but Wextra is not, for stability. +# +# These are collected from common.opt and c.opt in the GCC source, and manually +# curated with the help of the GCC documentation. Warnings that are +# application-specific, historical, or about compatibility between specific +# language revisions are omitted. The intent here is to have roughly the same +# meaning as clang's Weverything: extremely strict, but general. Specifically +# omitted are: +# +# General: +# +# Wabi= +# Waggregate-return +# Walloc-size-larger-than=BYTES +# Walloca-larger-than=BYTES +# Wframe-larger-than=BYTES +# Wlarger-than=BYTES +# Wstack-usage=BYTES +# Wsystem-headers +# Wtraditional +# Wtraditional-conversion +# Wtrampolines +# Wvla-larger-than=BYTES +# +# Build specific: +# +# Wpoison-system-directories +# +# C Specific: +# +# Wc11-c2x-compat +# Wc90-c99-compat +# Wc99-c11-compat +# Wdeclaration-after-statement +# Wtraditional +# Wtraditional-conversion +# +# C++ Specific: +# +# Wc++0x-compat +# Wc++1z-compat +# Wc++2a-compat +# Wctad-maybe-unsupported +# Wnamespaces +# Wtemplates + +# GCC warnings that apply to all C-family languages +gcc_common_warnings = [ + '-Walloc-zero', + '-Walloca', + '-Wanalyzer-too-complex', + '-Warith-conversion', + '-Warray-bounds=2', + '-Wattribute-alias=2', + '-Wbidi-chars=ucn', + '-Wcast-align=strict', + '-Wcast-function-type', + '-Wcast-qual', + '-Wclobbered', + '-Wconversion', + '-Wdate-time', + '-Wdisabled-optimization', + '-Wdouble-promotion', + '-Wduplicated-branches', + '-Wduplicated-cond', + '-Wempty-body', + '-Wendif-labels', + '-Wfloat-equal', + '-Wformat-overflow=2', + '-Wformat-signedness', + '-Wformat-truncation=2', + '-Wformat=2', + '-Wignored-qualifiers', + '-Wimplicit-fallthrough=3', + '-Winit-self', + '-Winline', + '-Winvalid-pch', + '-Wlogical-op', + '-Wmissing-declarations', + '-Wmissing-field-initializers', + '-Wmissing-include-dirs', + '-Wmultichar', + '-Wnormalized=nfc', + '-Wnull-dereference', + '-Wopenacc-parallelism', + '-Woverlength-strings', + '-Wpacked', + '-Wpacked-bitfield-compat', + '-Wpadded', + '-Wpointer-arith', + '-Wredundant-decls', + '-Wshadow', + '-Wshift-negative-value', + '-Wshift-overflow=2', + '-Wstack-protector', + '-Wstrict-aliasing=3', + '-Wstrict-overflow=5', + '-Wstring-compare', + '-Wstringop-overflow=3', + '-Wsuggest-attribute=cold', + '-Wsuggest-attribute=const', + '-Wsuggest-attribute=format', + '-Wsuggest-attribute=malloc', + '-Wsuggest-attribute=noreturn', + '-Wsuggest-attribute=pure', + '-Wswitch-default', + '-Wswitch-enum', + '-Wtrampolines', + '-Wtrivial-auto-var-init', + '-Wtype-limits', + '-Wundef', + '-Wuninitialized', + '-Wunsafe-loop-optimizations', + '-Wunused', + '-Wunused-const-variable=2', + '-Wunused-macros', + '-Wvector-operation-performance', + '-Wvla', + '-Wwrite-strings', +] + +##### +# C # +##### + +if is_variable('cc') + # Set all_c_warnings for the current C compiler + all_c_warnings = [] + + if cc.get_id() == 'clang' + all_c_warnings += ['-Weverything'] + + if not meson.is_cross_build() + all_c_warnings += [ + '-Wno-poison-system-directories', + ] + endif + + elif cc.get_id() == 'gcc' + all_c_warnings += gcc_common_warnings + [ + '-Wabsolute-value', + '-Wbad-function-cast', + '-Wc++-compat', + '-Wenum-conversion', + '-Wjump-misses-init', + '-Wmissing-parameter-type', + '-Wmissing-prototypes', + '-Wnested-externs', + '-Wold-style-declaration', + '-Wold-style-definition', + '-Woverride-init', + '-Wsign-compare', + '-Wstrict-prototypes', + '-Wunsuffixed-float-constants', + ] + + elif cc.get_id() == 'msvc' + all_c_warnings += [ + '/Wall', + '/experimental:external', + '/external:W0', + '/external:anglebrackets', + ] + endif + + all_c_warnings = cc.get_supported_arguments(all_c_warnings) +endif diff --git a/meson_options.txt b/meson_options.txt index 659c74c..4f5c9b4 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -4,5 +4,5 @@ option('benchmarks', type: 'feature', value: 'auto', yield: true, option('strict', type: 'boolean', value: false, yield: true, description: 'Enable ultra-strict warnings') -option('tests', type: 'boolean', value: true, yield: true, +option('tests', type: 'feature', value: 'auto', yield: true, description: 'Build tests') |