diff --git a/.github/workflows/linux-meson-builds.yml b/.github/workflows/linux-meson-builds.yml new file mode 100644 index 00000000..9d9ef773 --- /dev/null +++ b/.github/workflows/linux-meson-builds.yml @@ -0,0 +1,43 @@ +name: Linux builds (basic) using meson build system + +on: [push, pull_request] + +jobs: + build: + name: meson ${{matrix.cxx}}, C++${{matrix.std}}, ${{matrix.build_type}} + runs-on: ubuntu-22.04 + strategy: + matrix: + cxx: + - g++-11 + - clang++-11 + build_type: [debug, release] + std: [14, 17] + include: + - cxx: clang++-11 + other_pkgs: clang-11 + + steps: + - uses: actions/checkout@v2 + + - name: Prepare environment + run: sudo apt-get install -y meson ninja-build ${{matrix.other_pkgs}} + + - name: Configure build + env: + CXX: ${{matrix.cxx}} + CXXFLAGS: -std=c++${{matrix.std}} ${{matrix.cxxflags}} + # Note: $GITHUB_WORKSPACE is distinct from ${{runner.workspace}}. + # This is important + run: | + meson -Dbuildtype=${{matrix.build_type}} ${{runner.workspace}}/meson-build + + - name: Build tests + lib + working-directory: ${{runner.workspace}}/meson-build + run: ninja + + - name: Run tests + working-directory: ${{runner.workspace}}/meson-build + # Hardcode 2 cores we know are there + run: | + meson test --verbose diff --git a/.gitignore b/.gitignore index cafbd6b2..27f6bc0b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ *.build +!meson.build *.pbxuser *.mode1v3 *.ncb diff --git a/meson.build b/meson.build new file mode 100644 index 00000000..644f0a24 --- /dev/null +++ b/meson.build @@ -0,0 +1,17 @@ +# Copyright Catch2 Authors +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at +# https://www.boost.org/LICENSE_1_0.txt) + +# SPDX-License-Identifier: BSL-1.0 + +project( + 'catch2', + 'cpp', + version : '3.1.0', # CML version placeholder, don't delete + license: 'BSL-1.0', + meson_version: '>=0.49.0' +) + +subdir('src/catch2') +subdir('tests') diff --git a/src/catch2/meson.build b/src/catch2/meson.build new file mode 100644 index 00000000..e3961585 --- /dev/null +++ b/src/catch2/meson.build @@ -0,0 +1,357 @@ +# Copyright Catch2 Authors +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at +# https://www.boost.org/LICENSE_1_0.txt) + +# SPDX-License-Identifier: BSL-1.0 +pkg = import('pkgconfig') + +conf_data = configuration_data() +conf_data.set('CATCH_CONFIG_DEFAULT_REPORTER', 'console') +conf_data.set('CATCH_CONFIG_CONSOLE_WIDTH', '80') + +configure_file( + input: 'catch_user_config.hpp.in', + output: 'catch_user_config.hpp', + format: 'cmake@', + install_dir: get_option('includedir') / 'catch2', + configuration: conf_data +) + +benchmark_headers = [ + 'benchmark/catch_benchmark.hpp', + 'benchmark/catch_benchmark_all.hpp', + 'benchmark/catch_chronometer.hpp', + 'benchmark/catch_clock.hpp', + 'benchmark/catch_constructor.hpp', + 'benchmark/catch_environment.hpp', + 'benchmark/catch_estimate.hpp', + 'benchmark/catch_execution_plan.hpp', + 'benchmark/catch_optimizer.hpp', + 'benchmark/catch_outlier_classification.hpp', + 'benchmark/catch_sample_analysis.hpp', + 'benchmark/detail/catch_analyse.hpp', + 'benchmark/detail/catch_benchmark_function.hpp', + 'benchmark/detail/catch_complete_invoke.hpp', + 'benchmark/detail/catch_estimate_clock.hpp', + 'benchmark/detail/catch_measure.hpp', + 'benchmark/detail/catch_repeat.hpp', + 'benchmark/detail/catch_run_for_at_least.hpp', + 'benchmark/detail/catch_stats.hpp', + 'benchmark/detail/catch_timing.hpp' +] + +benchmark_sources = [ + 'benchmark/catch_chronometer.cpp', + 'benchmark/detail/catch_benchmark_function.cpp', + 'benchmark/detail/catch_run_for_at_least.cpp', + 'benchmark/detail/catch_stats.cpp', +] + +internal_headers = [ + 'catch_all.hpp', + 'matchers/catch_matchers_all.hpp', + 'generators/catch_generators_all.hpp', + 'interfaces/catch_interfaces_all.hpp', + 'matchers/internal/catch_matchers_impl.hpp', + 'internal/catch_case_insensitive_comparisons.hpp', + 'internal/catch_console_width.hpp', + 'internal/catch_container_nonmembers.hpp', + 'internal/catch_noncopyable.hpp', + 'catch_approx.hpp', + 'internal/catch_assertion_handler.hpp', + 'catch_assertion_info.hpp', + 'catch_assertion_result.hpp', + 'internal/catch_test_macro_impl.hpp', + 'internal/catch_test_failure_exception.hpp', + 'internal/catch_case_sensitive.hpp', + 'internal/catch_clara.hpp', + 'internal/catch_commandline.hpp', + 'internal/catch_source_line_info.hpp', + 'internal/catch_compiler_capabilities.hpp', + 'catch_config.hpp', + 'internal/catch_config_android_logwrite.hpp', + 'internal/catch_config_counter.hpp', + 'internal/catch_config_uncaught_exceptions.hpp', + 'internal/catch_config_wchar.hpp', + 'internal/catch_console_colour.hpp', + 'internal/catch_context.hpp', + 'internal/catch_debug_console.hpp', + 'internal/catch_debugger.hpp', + 'internal/catch_decomposer.hpp', + 'internal/catch_enforce.hpp', + 'internal/catch_enum_values_registry.hpp', + 'internal/catch_errno_guard.hpp', + 'internal/catch_exception_translator_registry.hpp', + 'internal/catch_fatal_condition_handler.hpp', + 'internal/catch_floating_point_helpers.hpp', + 'internal/catch_istream.hpp', + 'internal/catch_unique_name.hpp', + 'internal/catch_sharding.hpp', + 'generators/catch_generator_exception.hpp', + 'generators/catch_generators.hpp', + 'generators/catch_generators_adapters.hpp', + 'generators/catch_generators_random.hpp', + 'generators/catch_generators_range.hpp', + 'interfaces/catch_interfaces_capture.hpp', + 'interfaces/catch_interfaces_config.hpp', + 'interfaces/catch_interfaces_enum_values_registry.hpp', + 'interfaces/catch_interfaces_exception.hpp', + 'interfaces/catch_interfaces_generatortracker.hpp', + 'interfaces/catch_interfaces_registry_hub.hpp', + 'interfaces/catch_interfaces_reporter.hpp', + 'interfaces/catch_interfaces_reporter_factory.hpp', + 'interfaces/catch_interfaces_reporter_registry.hpp', + 'interfaces/catch_interfaces_tag_alias_registry.hpp', + 'interfaces/catch_interfaces_testcase.hpp', + 'internal/catch_lazy_expr.hpp', + 'internal/catch_leak_detector.hpp', + 'internal/catch_list.hpp', + 'matchers/catch_matchers.hpp', + 'matchers/catch_matchers_container_properties.hpp', + 'matchers/catch_matchers_contains.hpp', + 'matchers/catch_matchers_exception.hpp', + 'matchers/catch_matchers_floating_point.hpp', + 'matchers/catch_matchers_predicate.hpp', + 'matchers/catch_matchers_quantifiers.hpp', + 'matchers/catch_matchers_string.hpp', + 'matchers/catch_matchers_templated.hpp', + 'matchers/catch_matchers_vector.hpp', + 'catch_message.hpp', + 'internal/catch_message_info.hpp', + 'internal/catch_meta.hpp', + 'internal/catch_move_and_forward.hpp', + 'internal/catch_optional.hpp', + 'internal/catch_output_redirect.hpp', + 'internal/catch_platform.hpp', + 'internal/catch_polyfills.hpp', + 'internal/catch_preprocessor.hpp', + 'internal/catch_preprocessor_remove_parens.hpp', + 'internal/catch_random_number_generator.hpp', + 'internal/catch_random_seed_generation.hpp', + 'internal/catch_reporter_registry.hpp', + 'internal/catch_reporter_spec_parser.hpp', + 'internal/catch_result_type.hpp', + 'internal/catch_run_context.hpp', + 'internal/catch_section.hpp', + 'internal/catch_stdstreams.hpp', + 'catch_section_info.hpp', + 'catch_session.hpp', + 'internal/catch_singletons.hpp', + 'internal/catch_startup_exception_registry.hpp', + 'internal/catch_reusable_string_stream.hpp', + 'internal/catch_stream_end_stop.hpp', + 'internal/catch_string_manip.hpp', + 'internal/catch_stringref.hpp', + 'catch_tag_alias.hpp', + 'catch_get_random_seed.hpp', + 'catch_tag_alias_autoregistrar.hpp', + 'internal/catch_tag_alias_registry.hpp', + 'catch_test_case_info.hpp', + 'internal/catch_test_case_registry_impl.hpp', + 'internal/catch_test_case_tracker.hpp', + 'catch_template_test_macros.hpp', + 'catch_test_macros.hpp', + 'internal/catch_template_test_registry.hpp', + 'internal/catch_test_registry.hpp', + 'catch_test_spec.hpp', + 'internal/catch_test_spec_parser.hpp', + 'internal/catch_textflow.hpp', + 'catch_timer.hpp', + 'internal/catch_to_string.hpp', + 'catch_tostring.hpp', + 'catch_totals.hpp', + 'catch_translate_exception.hpp', + 'internal/catch_uncaught_exceptions.hpp', + 'internal/catch_unique_ptr.hpp', + 'internal/catch_void_type.hpp', + 'catch_version.hpp', + 'catch_version_macros.hpp', + 'internal/catch_wildcard_pattern.hpp', + 'internal/catch_windows_h_proxy.hpp', + 'internal/catch_xmlwriter.hpp', + 'internal/catch_test_case_info_hasher.hpp' +] + +internal_sources = [ + 'catch_approx.cpp', + 'internal/catch_assertion_handler.cpp', + 'catch_assertion_result.cpp', + 'internal/catch_clara.cpp', + 'internal/catch_commandline.cpp', + 'internal/catch_source_line_info.cpp', + 'catch_config.cpp', + 'internal/catch_case_insensitive_comparisons.cpp', + 'internal/catch_console_colour.cpp', + 'internal/catch_context.cpp', + 'internal/catch_debug_console.cpp', + 'internal/catch_debugger.cpp', + 'internal/catch_enforce.cpp', + 'internal/catch_enum_values_registry.cpp', + 'internal/catch_exception_translator_registry.cpp', + 'internal/catch_fatal_condition_handler.cpp', + 'internal/catch_floating_point_helpers.cpp', + 'internal/catch_istream.cpp', + 'interfaces/catch_interfaces_generatortracker.cpp', + 'interfaces/catch_interfaces_reporter.cpp', + 'internal/catch_list.cpp', + 'matchers/catch_matchers_floating_point.cpp', + 'matchers/catch_matchers_quantifiers.cpp', + 'matchers/catch_matchers_string.cpp', + 'matchers/catch_matchers_templated.cpp', + 'catch_message.cpp', + 'internal/catch_output_redirect.cpp', + 'catch_registry_hub.cpp', + 'internal/catch_random_number_generator.cpp', + 'internal/catch_random_seed_generation.cpp', + 'internal/catch_reporter_registry.cpp', + 'internal/catch_reporter_spec_parser.cpp', + 'internal/catch_result_type.cpp', + 'internal/catch_run_context.cpp', + 'internal/catch_section.cpp', + 'internal/catch_stdstreams.cpp', + 'catch_session.cpp', + 'internal/catch_singletons.cpp', + 'internal/catch_reusable_string_stream.cpp', + 'internal/catch_stringref.cpp', + 'internal/catch_string_manip.cpp', + 'internal/catch_tag_alias_registry.cpp', + 'catch_test_case_info.cpp', + 'internal/catch_test_case_registry_impl.cpp', + 'internal/catch_test_case_tracker.cpp', + 'internal/catch_test_registry.cpp', + 'internal/catch_textflow.cpp', + 'catch_test_spec.cpp', + 'internal/catch_test_spec_parser.cpp', + 'catch_timer.cpp', + 'catch_tostring.cpp', + 'catch_totals.cpp', + 'catch_version.cpp', + 'internal/catch_wildcard_pattern.cpp', + 'internal/catch_xmlwriter.cpp', + 'internal/catch_test_case_info_hasher.cpp', + 'generators/catch_generators_random.cpp', + 'generators/catch_generator_exception.cpp', + 'generators/catch_generators.cpp', + 'matchers/catch_matchers.cpp', + 'matchers/catch_matchers_container_properties.cpp', + 'matchers/catch_matchers_exception.cpp', + 'matchers/catch_matchers_predicate.cpp', + 'matchers/internal/catch_matchers_impl.cpp', + 'catch_tag_alias_autoregistrar.cpp', + 'catch_get_random_seed.cpp', + 'internal/catch_decomposer.cpp', + 'internal/catch_errno_guard.cpp', + 'internal/catch_lazy_expr.cpp', + 'internal/catch_leak_detector.cpp', + 'internal/catch_message_info.cpp', + 'internal/catch_polyfills.cpp', + 'internal/catch_startup_exception_registry.cpp', + 'internal/catch_uncaught_exceptions.cpp', + 'interfaces/catch_interfaces_capture.cpp', + 'interfaces/catch_interfaces_config.cpp', + 'interfaces/catch_interfaces_exception.cpp', + 'interfaces/catch_interfaces_registry_hub.cpp', + 'interfaces/catch_interfaces_reporter_factory.cpp', + 'interfaces/catch_interfaces_reporter_registry.cpp', + 'interfaces/catch_interfaces_testcase.cpp', +] + +reporter_headers = [ + 'reporters/catch_reporters_all.hpp', + 'reporters/catch_reporter_automake.hpp', + 'reporters/catch_reporter_common_base.hpp', + 'reporters/catch_reporter_compact.hpp', + 'reporters/catch_reporter_console.hpp', + 'reporters/catch_reporter_cumulative_base.hpp', + 'reporters/catch_reporter_event_listener.hpp', + 'reporters/catch_reporter_helpers.hpp', + 'reporters/catch_reporter_junit.hpp', + 'reporters/catch_reporter_multi.hpp', + 'reporters/catch_reporter_registrars.hpp', + 'reporters/catch_reporter_sonarqube.hpp', + 'reporters/catch_reporter_streaming_base.hpp', + 'reporters/catch_reporter_tap.hpp', + 'reporters/catch_reporter_teamcity.hpp', + 'reporters/catch_reporter_xml.hpp' +] + +reporter_sources = [ + 'reporters/catch_reporter_automake.cpp', + 'reporters/catch_reporter_common_base.cpp', + 'reporters/catch_reporter_compact.cpp', + 'reporters/catch_reporter_console.cpp', + 'reporters/catch_reporter_cumulative_base.cpp', + 'reporters/catch_reporter_event_listener.cpp', + 'reporters/catch_reporter_helpers.cpp', + 'reporters/catch_reporter_junit.cpp', + 'reporters/catch_reporter_multi.cpp', + 'reporters/catch_reporter_registrars.cpp', + 'reporters/catch_reporter_sonarqube.cpp', + 'reporters/catch_reporter_streaming_base.cpp', + 'reporters/catch_reporter_tap.cpp', + 'reporters/catch_reporter_teamcity.cpp', + 'reporters/catch_reporter_xml.cpp', +] + +headers = benchmark_headers + internal_headers + reporter_headers +sources = benchmark_sources + internal_sources + reporter_sources + +# The headers must be installed with their full paths, which meson +# v0.63 supports using `preserve_path` for `install_headers`. We'd +# like to be compatible with Debian 11 (current stable) which has +# meson v0.56.2. Instead, let's use the technique from +# https://github.com/mesonbuild/meson/issues/14 with some tweaks to +# make it compatible with newer meson. +include_subdir = 'catch2' +foreach file : headers + file_path = file.split('/') + + folder = '' + foreach path : file_path + if path != file_path[-1] + folder = folder / path + endif + endforeach + + install_headers(file, subdir: join_paths(include_subdir, folder)) +endforeach + +catch2 = static_library( + 'Catch2', + sources, + include_directories : '..', + install : true +) + +catch2_dep = declare_dependency( + link_with: catch2, + include_directories: '..' +) + +pkg.generate( + catch2, + filebase: 'catch2', + description : 'A modern, C++-native, test framework for C++14 and above', + url: 'https://github.com/catchorg/Catch2' +) + +catch2_with_main = static_library( + 'Catch2Main', + [ 'internal/catch_main.cpp' ], + link_with: catch2, + include_directories : '..', + install : true +) + +catch2_with_main_dep = declare_dependency( + link_with: [ catch2, catch2_with_main ], + include_directories: '..' +) + +pkg.generate( + catch2_with_main, + filebase : 'catch2-with-main', + description : 'A modern, C++-native, test framework for C++14 and above (links in default main)', + requires : 'catch2 = ' + meson.project_version() +) diff --git a/tests/meson.build b/tests/meson.build new file mode 100644 index 00000000..a7670a99 --- /dev/null +++ b/tests/meson.build @@ -0,0 +1,71 @@ +# Copyright Catch2 Authors +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at +# https://www.boost.org/LICENSE_1_0.txt) + +# SPDX-License-Identifier: BSL-1.0 + +# define the sources of the self test +# Please keep these ordered alphabetically +self_test_sources = [ + 'SelfTest/TestRegistrations.cpp', + 'SelfTest/IntrospectiveTests/Clara.tests.cpp', + 'SelfTest/IntrospectiveTests/CmdLine.tests.cpp', + 'SelfTest/IntrospectiveTests/CmdLineHelpers.tests.cpp', + 'SelfTest/IntrospectiveTests/ColourImpl.tests.cpp', + 'SelfTest/IntrospectiveTests/Details.tests.cpp', + 'SelfTest/IntrospectiveTests/FloatingPoint.tests.cpp', + 'SelfTest/IntrospectiveTests/GeneratorsImpl.tests.cpp', + 'SelfTest/IntrospectiveTests/InternalBenchmark.tests.cpp', + 'SelfTest/IntrospectiveTests/PartTracker.tests.cpp', + 'SelfTest/IntrospectiveTests/RandomNumberGeneration.tests.cpp', + 'SelfTest/IntrospectiveTests/Reporters.tests.cpp', + 'SelfTest/IntrospectiveTests/Tag.tests.cpp', + 'SelfTest/IntrospectiveTests/TestCaseInfoHasher.tests.cpp', + 'SelfTest/IntrospectiveTests/TestSpecParser.tests.cpp', + 'SelfTest/IntrospectiveTests/TextFlow.tests.cpp', + 'SelfTest/IntrospectiveTests/Sharding.tests.cpp', + 'SelfTest/IntrospectiveTests/Stream.tests.cpp', + 'SelfTest/IntrospectiveTests/String.tests.cpp', + 'SelfTest/IntrospectiveTests/StringManip.tests.cpp', + 'SelfTest/IntrospectiveTests/Xml.tests.cpp', + 'SelfTest/IntrospectiveTests/ToString.tests.cpp', + 'SelfTest/IntrospectiveTests/UniquePtr.tests.cpp', + 'SelfTest/TimingTests/Sleep.tests.cpp', + 'SelfTest/UsageTests/Approx.tests.cpp', + 'SelfTest/UsageTests/BDD.tests.cpp', + 'SelfTest/UsageTests/Benchmark.tests.cpp', + 'SelfTest/UsageTests/Class.tests.cpp', + 'SelfTest/UsageTests/Compilation.tests.cpp', + 'SelfTest/UsageTests/Condition.tests.cpp', + 'SelfTest/UsageTests/Decomposition.tests.cpp', + 'SelfTest/UsageTests/EnumToString.tests.cpp', + 'SelfTest/UsageTests/Exception.tests.cpp', + 'SelfTest/UsageTests/Generators.tests.cpp', + 'SelfTest/UsageTests/Message.tests.cpp', + 'SelfTest/UsageTests/Misc.tests.cpp', + 'SelfTest/UsageTests/ToStringByte.tests.cpp', + 'SelfTest/UsageTests/ToStringChrono.tests.cpp', + 'SelfTest/UsageTests/ToStringGeneral.tests.cpp', + 'SelfTest/UsageTests/ToStringOptional.tests.cpp', + 'SelfTest/UsageTests/ToStringPair.tests.cpp', + 'SelfTest/UsageTests/ToStringTuple.tests.cpp', + 'SelfTest/UsageTests/ToStringVariant.tests.cpp', + 'SelfTest/UsageTests/ToStringVector.tests.cpp', + 'SelfTest/UsageTests/ToStringWhich.tests.cpp', + 'SelfTest/UsageTests/Tricky.tests.cpp', + 'SelfTest/UsageTests/VariadicMacros.tests.cpp', + 'SelfTest/UsageTests/MatchersRanges.tests.cpp', + 'SelfTest/UsageTests/Matchers.tests.cpp' +] + +# This isn't as good as the CMake tests, but it proves that we've +# actually put something in the library files. +self_test = executable( + 'SelfTest', + self_test_sources, + include_directories : '../src', + link_with : [ catch2_with_main, catch2 ] +) + +test('SelfTest', self_test) diff --git a/tools/scripts/releaseCommon.py b/tools/scripts/releaseCommon.py index 20ef1b0c..30a07658 100644 --- a/tools/scripts/releaseCommon.py +++ b/tools/scripts/releaseCommon.py @@ -15,6 +15,7 @@ versionPath = os.path.join( rootPath, "catch_version.cpp" ) definePath = os.path.join(rootPath, 'catch_version_macros.hpp') readmePath = os.path.join( catchPath, "README.md" ) cmakePath = os.path.join(catchPath, 'CMakeLists.txt') +mesonPath = os.path.join(catchPath, 'meson.build') class Version: def __init__(self): @@ -89,6 +90,16 @@ def updateCmakeFile(version): file.write(replacementRegex.sub(replacement, line)) +def updateMesonFile(version): + with open(mesonPath, 'rb') as file: + lines = file.readlines() + replacementRegex = re.compile(b'''version\s*:\s*'(\\d+.\\d+.\\d+)', # CML version placeholder, don't delete''') + replacement = '''version : '{0}', # CML version placeholder, don't delete'''.format(version.getVersionString()).encode('ascii') + with open(mesonPath, 'wb') as file: + for line in lines: + file.write(replacementRegex.sub(replacement, line)) + + def updateVersionDefine(version): # First member of the tuple is the compiled regex object, the second is replacement if it matches replacementRegexes = [(re.compile(b'#define CATCH_VERSION_MAJOR \\d+'),'#define CATCH_VERSION_MAJOR {}'.format(version.majorVersion).encode('ascii')), @@ -132,4 +143,5 @@ def performUpdates(version): generateAmalgamatedFiles.generate_cpp() updateCmakeFile(version) + updateMesonFile(version) updateDocumentationVersionPlaceholders(version)