From fe17d32e9bcbfabcb25cc4d00a810bcd8527e8c4 Mon Sep 17 00:00:00 2001 From: Roland Reichwein Date: Wed, 6 May 2026 11:10:14 +0200 Subject: [PATCH] Fix meson build (#1431) Co-authored-by: John Wellbelove --- .github/workflows/meson-gcc-c++23-no-stl.yml | 31 ++++ docs/meson.md | 116 +++++++++++++ meson_options.txt | 1 + test/meson.build | 162 ++++++++++++++----- 4 files changed, 274 insertions(+), 36 deletions(-) create mode 100644 .github/workflows/meson-gcc-c++23-no-stl.yml create mode 100644 docs/meson.md diff --git a/.github/workflows/meson-gcc-c++23-no-stl.yml b/.github/workflows/meson-gcc-c++23-no-stl.yml new file mode 100644 index 00000000..d8767317 --- /dev/null +++ b/.github/workflows/meson-gcc-c++23-no-stl.yml @@ -0,0 +1,31 @@ +name: meson-gcc-c++23-no-stl +on: + push: + branches: [ master, development, pull-request/* ] + pull_request: + branches: [ master, development, pull-request/* ] + types: [opened, synchronize, reopened] + +jobs: + + build-meson-gcc-cpp23-no-stl: + name: Meson GCC C++23 Linux - No STL + runs-on: ubuntu-24.04 + + steps: + - uses: actions/checkout@v6 + + - name: Install Meson + run: sudo apt-get install -y meson + + - name: Configure + run: | + export CC=gcc + export CXX=g++ + meson setup builddir -Duse_stl=false -Dcpp_std=c++23 + + - name: Build + run: meson compile -C builddir + + - name: Run tests + run: meson test -C builddir -v diff --git a/docs/meson.md b/docs/meson.md new file mode 100644 index 00000000..3fb318d3 --- /dev/null +++ b/docs/meson.md @@ -0,0 +1,116 @@ +# Building ETL with Meson + +## Prerequisites + +- [Meson](https://mesonbuild.com/) >= 0.57.0 +- A C++17 compiler (GCC, Clang, or MSVC) +- [Ninja](https://ninja-build.org/) (default Meson backend) + +UnitTest++ is fetched automatically as a Meson subproject — no manual dependency installation is needed. + +## Quick Start + +```bash +# Configure (from the project root) +meson setup builddir + +# Build +meson compile -C builddir + +# Run tests +meson test -C builddir +``` + +## Build Options + +### ETL project options + +| Option | Type | Default | Description | +|---------------------|------|---------|-------------------------------------------------------------------| +| `use_stl` | bool | `true` | Build with STL support. When `false`, defines `ETL_NO_STL`. | +| `enable_sanitizer` | bool | `false` | Enable AddressSanitizer and UndefinedBehaviorSanitizer (GCC/Clang only). | + +### Meson built-in options + +| Option | Type | Default | Description | +|-------------|--------|----------|----------------------------------------------------------| +| `cpp_std` | string | `c++17` | C++ standard to compile with (e.g. `c++20`, `c++23`). | +| `buildtype` | string | `debug` | Build type: `plain`, `debug`, `debugoptimized`, `release`, `minsize`. | +| `werror` | bool | `false` | Treat compiler warnings as errors. | + +These are handled by Meson directly — no `get_option()` call is needed in the build files. + +### Examples + +```bash +# No STL, C++23 +meson setup builddir -Duse_stl=false -Dcpp_std=c++23 + +# Release build with sanitizers +meson setup builddir -Dbuildtype=release -Denable_sanitizer=true + +# Override the C++ standard on an existing build directory +meson configure builddir -Dcpp_std=c++20 +``` + +## Selecting a Compiler + +The compiler is chosen at configure time via environment variables: + +```bash +# GCC +CC=gcc CXX=g++ meson setup builddir + +# Clang +CC=clang CXX=clang++ meson setup builddir + +# Specific versions +CC=gcc-14 CXX=g++-14 meson setup builddir +CC=clang-18 CXX=clang++-18 meson setup builddir +``` + +To switch compilers on an existing build directory, wipe it first: + +```bash +CC=clang CXX=clang++ meson setup --wipe builddir +``` + +Or use separate directories per compiler: + +```bash +CC=gcc CXX=g++ meson setup build-gcc +CC=clang CXX=clang++ meson setup build-clang +``` + +## Running Tests + +```bash +# Run all tests +meson test -C builddir + +# Verbose output (shows individual test results) +meson test -C builddir -v + +# Run the test binary directly +./builddir/test/etl_unit_tests +``` + +## Sanitizers + +On GCC and Clang, AddressSanitizer and UndefinedBehaviorSanitizer can be enabled via the `enable_sanitizer` option: + +```bash +meson setup builddir -Denable_sanitizer=true +``` + +Note: UBSan may prevent certain `constexpr` evaluations involving function pointers from compiling (e.g. in the closure tests). This matches the CMake build, where sanitizers are also opt-in via `ETL_ENABLE_SANITIZER=ON`. + +## Using ETL as a Subproject + +ETL can be consumed as a Meson subproject. In your project's `subprojects/` directory, create an `etl.wrap` file, then use: + +```meson +etl_dep = dependency('etl', fallback: ['etl', 'etl_dep']) +``` + +When built as a subproject, the ETL test suite is not compiled. diff --git a/meson_options.txt b/meson_options.txt index 6f64d611..5845d5f3 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -1 +1,2 @@ option('use_stl', description: 'Compiling for STL', type: 'boolean', value: true) +option('enable_sanitizer', description: 'Enable address and undefined behavior sanitizers', type: 'boolean', value: false) diff --git a/test/meson.build b/test/meson.build index b84a21be..8de41419 100644 --- a/test/meson.build +++ b/test/meson.build @@ -1,4 +1,3 @@ - etl_test_sources = files( 'main.cpp', 'murmurhash3.cpp', @@ -8,48 +7,91 @@ etl_test_sources = files( 'test_array_view.cpp', 'test_array_wrapper.cpp', 'test_atomic.cpp', - 'test_base64_RFC2152_decoder.cppp', - 'test_base64_RFC2152_encoder.cppp', - 'test_base64_RFC3501_decoder.cppp', - 'test_base64_RFC3501_encoder.cppp', - 'test_base64_RFC4648_decoder_with_no_padding.cppp', - 'test_base64_RFC4648_decoder_with_padding.cppp', - 'test_base64_RFC4648_encoder_with_no_padding.cppp', - 'test_base64_RFC4648_encoder_with_padding.cppp', - 'test_base64_RFC4648_URL_decoder_with_no_padding.cppp', - 'test_base64_RFC4648_URL_decoder_with_padding.cppp', - 'test_base64_RFC4648_URL_encoder_with_no_padding.cppp', + 'test_base64_RFC2152_decoder.cpp', + 'test_base64_RFC2152_encoder.cpp', + 'test_base64_RFC3501_decoder.cpp', + 'test_base64_RFC3501_encoder.cpp', + 'test_base64_RFC4648_URL_decoder_with_no_padding.cpp', + 'test_base64_RFC4648_URL_decoder_with_padding.cpp', + 'test_base64_RFC4648_URL_encoder_with_no_padding.cpp', 'test_base64_RFC4648_URL_encoder_with_padding.cpp', + 'test_base64_RFC4648_decoder_with_no_padding.cpp', + 'test_base64_RFC4648_decoder_with_padding.cpp', + 'test_base64_RFC4648_encoder_with_no_padding.cpp', + 'test_base64_RFC4648_encoder_with_padding.cpp', 'test_binary.cpp', 'test_bip_buffer_spsc_atomic.cpp', 'test_bit.cpp', - 'test_bitset_legacy.cpp', - 'test_bitset_new_default_element_type.cpp', - 'test_bitset_new_explicit_single_element_type.cpp', - 'test_bitset_new_ext_default_element_type.cpp', - 'test_bitset_new_ext_explicit_single_element_type.cpp', 'test_bit_stream.cpp', 'test_bit_stream_reader_big_endian.cpp', 'test_bit_stream_reader_little_endian.cpp', 'test_bit_stream_writer_big_endian.cpp', 'test_bit_stream_writer_little_endian.cpp', - 'test_byte.cpp', - 'test_byte_stream.cpp', + 'test_bitset_legacy.cpp', + 'test_bitset_new_comparisons.cpp', + 'test_bitset_new_default_element_type.cpp', + 'test_bitset_new_explicit_single_element_type.cpp', + 'test_bitset_new_ext_default_element_type.cpp', + 'test_bitset_new_ext_explicit_single_element_type.cpp', 'test_bloom_filter.cpp', 'test_bresenham_line.cpp', 'test_bsd_checksum.cpp', 'test_buffer_descriptors.cpp', + 'test_byte.cpp', + 'test_byte_stream.cpp', 'test_callback_service.cpp', 'test_callback_timer.cpp', 'test_callback_timer_atomic.cpp', + 'test_callback_timer_deferred_locked.cpp', 'test_callback_timer_interrupt.cpp', 'test_callback_timer_locked.cpp', + 'test_char_traits.cpp', 'test_checksum.cpp', + 'test_chrono_clocks.cpp', + 'test_chrono_day.cpp', + 'test_chrono_duration.cpp', + 'test_chrono_hh_mm_ss.cpp', + 'test_chrono_literals.cpp', + 'test_chrono_month.cpp', + 'test_chrono_month_day.cpp', + 'test_chrono_month_day_last.cpp', + 'test_chrono_month_weekday.cpp', + 'test_chrono_month_weekday_last.cpp', + 'test_chrono_operators.cpp', + 'test_chrono_time_point.cpp', + 'test_chrono_weekday.cpp', + 'test_chrono_weekday_indexed.cpp', + 'test_chrono_weekday_last.cpp', + 'test_chrono_year.cpp', + 'test_chrono_year_month.cpp', + 'test_chrono_year_month_day.cpp', + 'test_chrono_year_month_day_last.cpp', + 'test_chrono_year_month_weekday.cpp', + 'test_chrono_year_month_weekday_last.cpp', 'test_circular_buffer.cpp', 'test_circular_buffer_external_buffer.cpp', 'test_circular_iterator.cpp', + 'test_closure_with_default_delegate.cpp', + 'test_closure_with_default_delegate_constexpr.cpp', + 'test_closure_with_inplace_function.cpp', 'test_compare.cpp', - 'test_compiler_settings.cpp', + 'test_concepts.cpp', + 'test_const_map.cpp', + 'test_const_map_constexpr.cpp', + 'test_const_map_ext.cpp', + 'test_const_map_ext_constexpr.cpp', + 'test_const_multimap.cpp', + 'test_const_multimap_constexpr.cpp', + 'test_const_multimap_ext.cpp', + 'test_const_multimap_ext_constexpr.cpp', + 'test_const_multiset.cpp', + 'test_const_multiset_constexpr.cpp', + 'test_const_multiset_ext.cpp', + 'test_const_multiset_ext_constexpr.cpp', + 'test_const_set.cpp', + 'test_const_set_constexpr.cpp', + 'test_const_set_ext.cpp', + 'test_const_set_ext_constexpr.cpp', 'test_constant.cpp', 'test_container.cpp', 'test_correlation.cpp', @@ -69,9 +111,12 @@ etl_test_sources = files( 'test_crc16_en13757.cpp', 'test_crc16_genibus.cpp', 'test_crc16_kermit.cpp', + 'test_crc16_m17.cpp', 'test_crc16_maxim.cpp', 'test_crc16_mcrf4xx.cpp', 'test_crc16_modbus.cpp', + 'test_crc16_opensafety_a.cpp', + 'test_crc16_opensafety_b.cpp', 'test_crc16_profibus.cpp', 'test_crc16_riello.cpp', 'test_crc16_t10dif.cpp', @@ -90,6 +135,7 @@ etl_test_sources = files( 'test_crc32_q.cpp', 'test_crc32_xfer.cpp', 'test_crc64_ecma.cpp', + 'test_crc64_iso.cpp', 'test_crc8_ccitt.cpp', 'test_crc8_cdma2000.cpp', 'test_crc8_darc.cpp', @@ -97,21 +143,29 @@ etl_test_sources = files( 'test_crc8_ebu.cpp', 'test_crc8_icode.cpp', 'test_crc8_itu.cpp', + 'test_crc8_j1850.cpp', + 'test_crc8_j1850_zero.cpp', 'test_crc8_maxim.cpp', + 'test_crc8_nrsc5.cpp', + 'test_crc8_opensafety.cpp', 'test_crc8_rohc.cpp', 'test_crc8_wcdma.cpp', 'test_cyclic_value.cpp', 'test_debounce.cpp', 'test_delegate.cpp', 'test_delegate_cpp03.cpp', + 'test_delegate_observable.cpp', 'test_delegate_service.cpp', 'test_delegate_service_compile_time.cpp', + 'test_delegate_service_cpp03.cpp', 'test_deque.cpp', 'test_endian.cpp', 'test_enum_type.cpp', 'test_error_handler.cpp', + 'test_etl_assert.cpp', 'test_etl_traits.cpp', 'test_exception.cpp', + 'test_expected.cpp', 'test_fixed_iterator.cpp', 'test_fixed_sized_memory_block_allocator.cpp', 'test_flags.cpp', @@ -120,18 +174,24 @@ etl_test_sources = files( 'test_flat_multiset.cpp', 'test_flat_set.cpp', 'test_fnv_1.cpp', + 'test_format.cpp', 'test_format_spec.cpp', 'test_forward_list.cpp', 'test_forward_list_shared_pool.cpp', 'test_fsm.cpp', 'test_function.cpp', + 'test_function_traits.cpp', 'test_functional.cpp', 'test_gamma.cpp', 'test_hash.cpp', 'test_hfsm.cpp', + 'test_hfsm_recurse_to_inner_state_on_start.cpp', + 'test_hfsm_transition_on_enter.cpp', 'test_histogram.cpp', + 'test_index_of_type.cpp', 'test_indirect_vector.cpp', 'test_indirect_vector_external_buffer.cpp', + 'test_inplace_function.cpp', 'test_instance_count.cpp', 'test_integral_limits.cpp', 'test_intrusive_forward_list.cpp', @@ -140,7 +200,9 @@ etl_test_sources = files( 'test_intrusive_queue.cpp', 'test_intrusive_stack.cpp', 'test_invert.cpp', + 'test_invoke.cpp', 'test_io_port.cpp', + 'test_is_invocable.cpp', 'test_iterator.cpp', 'test_jenkins.cpp', 'test_largest.cpp', @@ -148,14 +210,17 @@ etl_test_sources = files( 'test_limits.cpp', 'test_list.cpp', 'test_list_shared_pool.cpp', + 'test_macros.cpp', 'test_make_string.cpp', + 'test_manchester.cpp', 'test_map.cpp', 'test_math.cpp', 'test_math_functions.cpp', 'test_mean.cpp', 'test_mem_cast.cpp', 'test_mem_cast_ptr.cpp', - 'test_memory.cpp', + 'test_memory.cpp', + 'test_message.cpp', 'test_message_broker.cpp', 'test_message_bus.cpp', 'test_message_packet.cpp', @@ -163,18 +228,23 @@ etl_test_sources = files( 'test_message_router_registry.cpp', 'test_message_timer.cpp', 'test_message_timer_atomic.cpp', - 'test_message_timer_interrupt.cpp', + 'test_message_timer_interrupt.cpp', 'test_message_timer_locked.cpp', - 'test_multimap.cpp', - 'test_multiset.cpp', 'test_multi_array.cpp', 'test_multi_range.cpp', + 'test_multi_span.cpp', 'test_multi_vector.cpp', + 'test_multimap.cpp', + 'test_multiset.cpp', 'test_murmur3.cpp', + 'test_not_null_pointer.cpp', + 'test_not_null_pointer_constexpr.cpp', + 'test_not_null_unique_pointer.cpp', 'test_nth_type.cpp', 'test_numeric.cpp', 'test_observer.cpp', 'test_optional.cpp', + 'test_overload.cpp', 'test_packet.cpp', 'test_parameter_pack.cpp', 'test_parameter_type.cpp', @@ -184,6 +254,7 @@ etl_test_sources = files( 'test_poly_span_fixed_extent.cpp', 'test_pool.cpp', 'test_pool_external_buffer.cpp', + 'test_print.cpp', 'test_priority_queue.cpp', 'test_pseudo_moving_average.cpp', 'test_quantize.cpp', @@ -200,45 +271,54 @@ etl_test_sources = files( 'test_queue_spsc_locked.cpp', 'test_queue_spsc_locked_small.cpp', 'test_random.cpp', + 'test_ranges.cpp', + 'test_ratio.cpp', 'test_reference_flat_map.cpp', 'test_reference_flat_multimap.cpp', 'test_reference_flat_multiset.cpp', 'test_reference_flat_set.cpp', 'test_rescale.cpp', + 'test_result.cpp', 'test_rms.cpp', + 'test_rounded_integral_division.cpp', 'test_scaled_rounding.cpp', 'test_set.cpp', 'test_shared_message.cpp', + 'test_signal.cpp', 'test_singleton.cpp', + 'test_singleton_base.cpp', 'test_smallest.cpp', 'test_span_dynamic_extent.cpp', 'test_span_fixed_extent.cpp', 'test_stack.cpp', 'test_standard_deviation.cpp', 'test_state_chart.cpp', - 'test_state_chart_with_data_parameter.cpp', - 'test_state_chart_with_rvalue_data_parameter.cpp', 'test_state_chart_compile_time.cpp', 'test_state_chart_compile_time_with_data_parameter.cpp', + 'test_state_chart_with_data_parameter.cpp', + 'test_state_chart_with_rvalue_data_parameter.cpp', 'test_string_char.cpp', 'test_string_char_external_buffer.cpp', 'test_string_stream.cpp', - 'test_string_u8.cpp', - 'test_string_u8_external_buffer.cpp', 'test_string_stream_u16.cpp', 'test_string_stream_u32.cpp', + 'test_string_stream_u8.cpp', 'test_string_stream_wchar_t.cpp', 'test_string_u16.cpp', 'test_string_u16_external_buffer.cpp', 'test_string_u32.cpp', 'test_string_u32_external_buffer.cpp', + 'test_string_u8.cpp', + 'test_string_u8_external_buffer.cpp', 'test_string_utilities.cpp', 'test_string_utilities_std.cpp', 'test_string_utilities_std_u16.cpp', 'test_string_utilities_std_u32.cpp', + 'test_string_utilities_std_u8.cpp', 'test_string_utilities_std_wchar_t.cpp', 'test_string_utilities_u16.cpp', 'test_string_utilities_u32.cpp', + 'test_string_utilities_u8.cpp', 'test_string_utilities_wchar_t.cpp', 'test_string_view.cpp', 'test_string_wchar_t.cpp', @@ -246,17 +326,25 @@ etl_test_sources = files( 'test_successor.cpp', 'test_task_scheduler.cpp', 'test_threshold.cpp', + 'test_to_arithmetic.cpp', + 'test_to_arithmetic_u16.cpp', + 'test_to_arithmetic_u32.cpp', + 'test_to_arithmetic_u8.cpp', + 'test_to_arithmetic_wchar_t.cpp', 'test_to_string.cpp', - 'test_to_u8string.cpp', 'test_to_u16string.cpp', 'test_to_u32string.cpp', + 'test_to_u8string.cpp', 'test_to_wstring.cpp', + 'test_tuple.cpp', 'test_type_def.cpp', + 'test_type_list.cpp', 'test_type_lookup.cpp', 'test_type_select.cpp', 'test_type_traits.cpp', 'test_unaligned_type.cpp', - 'test_unaligned_type_constexpr.cpp', + 'test_unaligned_type_ext.cpp', + 'test_uncopyable.cpp', 'test_unordered_map.cpp', 'test_unordered_multimap.cpp', 'test_unordered_multiset.cpp', @@ -265,9 +353,9 @@ etl_test_sources = files( 'test_utility.cpp', 'test_variance.cpp', 'test_variant_legacy.cpp', - 'test_variant_variadic.cpp', 'test_variant_pool.cpp', 'test_variant_pool_external_buffer.cpp', + 'test_variant_variadic.cpp', 'test_vector.cpp', 'test_vector_external_buffer.cpp', 'test_vector_non_trivial.cpp', @@ -280,24 +368,26 @@ etl_test_sources = files( compile_args = [ '-DENABLE_ETL_UNIT_TESTS', - '-DETL_DEBUG', ] link_args = [] if get_option('use_stl') compile_args += '-DETL_NO_STL=0' -elif +else compile_args += '-DETL_NO_STL=1' endif if meson.get_compiler('cpp').get_argument_syntax() == 'gcc' - compile_args += '-fsanitize=address,undefined' compile_args += '-fexceptions' compile_args += '-Wall' - compile_args += '-Wextra' + compile_args += '-Wextra' compile_args += '-Wno-non-virtual-dtor' #TODO remove and fix warning in code compile_args += '-Werror' - link_args += '-fsanitize=address,undefined' + + if get_option('enable_sanitizer') + compile_args += '-fsanitize=address,undefined' + link_args += '-fsanitize=address,undefined' + endif endif threads_dep = dependency('threads')