# Copyright (c) 2019-2024 Morwenn # SPDX-License-Identifier: MIT cmake_minimum_required(VERSION 3.24.0) include(FetchContent) # Test suite options option(GFX_TIMSORT_USE_VALGRIND "Whether to run the tests with Valgrind" OFF) set(GFX_TIMSORT_SANITIZE "" CACHE STRING "Comma-separated list of options to pass to -fsanitize") # Find/download Catch2 FetchContent_Declare( Catch2 GIT_REPOSITORY https://github.com/catchorg/Catch2 GIT_TAG fa43b77429ba76c462b1898d6cd2f2d7a9416b14 # v3.7.1 SYSTEM FIND_PACKAGE_ARGS 3.1.0 ) FetchContent_MakeAvailable(Catch2) list(APPEND CMAKE_MODULE_PATH ${catch2_SOURCE_DIR}/extras) include(Catch) # Configure Valgrind if (${GFX_TIMSORT_USE_VALGRIND}) find_program(MEMORYCHECK_COMMAND valgrind) set(MEMORYCHECK_COMMAND_OPTIONS "--leak-check=full --track-origins=yes --error-exitcode=1 --show-reachable=no") endif() macro(configure_tests target) # Add required dependencies to tests target_link_libraries(${target} PRIVATE Catch2::Catch2WithMain gfx::timsort ) target_compile_definitions(${target} PRIVATE # Somewhat speed up Catch2 compile times CATCH_CONFIG_FAST_COMPILE # Fortify test suite for more thorough checks _FORTIFY_SOURCE=3 _GLIBCXX_ASSERTIONS _LIBCPP_ENABLE_ASSERTIONS=1 GFX_TIMSORT_ENABLE_ASSERT ) # Add warnings if (CMAKE_CXX_COMPILER_FRONTEND_VARIANT STREQUAL "GNU") target_compile_options(${target} PRIVATE -Wall -Wextra -Wcast-align -Wmissing-declarations -Wmissing-include-dirs -Wnon-virtual-dtor -Wodr -Wpedantic -Wredundant-decls -Wundef -Wunreachable-code $<$:-Wlogical-op -Wuseless-cast> ) elseif (MSVC) target_compile_options(${target} PRIVATE /W4) endif() # Configure optimization options if (CMAKE_CXX_COMPILER_FRONTEND_VARIANT STREQUAL "GNU") target_compile_options(${target} PRIVATE $<$,$>:-O0> $<$,$>:-Og> ) endif() # Use lld or the gold linker if possible if (UNIX AND NOT APPLE) if (CMAKE_CXX_COMPILER_ID MATCHES "Clang") set_property(TARGET ${target} APPEND_STRING PROPERTY LINK_FLAGS " -fuse-ld=lld") else() set_property(TARGET ${target} APPEND_STRING PROPERTY LINK_FLAGS " -fuse-ld=gold") endif() endif() # Optionally enable sanitizers if (UNIX AND GFX_TIMSORT_SANITIZE) target_compile_options(${target} PRIVATE -fsanitize=${GFX_TIMSORT_SANITIZE} -fno-sanitize-recover=all ) set_property(TARGET ${target} APPEND_STRING PROPERTY LINK_FLAGS " -fsanitize=${GFX_TIMSORT_SANITIZE}" ) endif() endmacro() # Tests that can run with C++98 add_executable(cxx_98_tests cxx_98_tests.cpp verbose_abort.cpp ) configure_tests(cxx_98_tests) target_compile_features(cxx_98_tests PRIVATE cxx_std_98) # Tests requiring C++11 support add_executable(cxx_11_tests merge_cxx_11_tests.cpp cxx_11_tests.cpp verbose_abort.cpp ) configure_tests(cxx_11_tests) target_compile_features(cxx_11_tests PRIVATE cxx_std_11) # Tests requiring C++17 support add_executable(cxx_17_tests cxx_17_tests.cpp verbose_abort.cpp ) configure_tests(cxx_17_tests) target_compile_features(cxx_17_tests PRIVATE cxx_std_17) # Tests requiring C++20 support add_executable(cxx_20_tests cxx_20_tests.cpp verbose_abort.cpp ) configure_tests(cxx_20_tests) target_compile_features(cxx_20_tests PRIVATE cxx_std_20) # Tests requiring C++23 support if ("cxx_std_23" IN_LIST CMAKE_CXX_COMPILE_FEATURES) add_executable(cxx_23_tests cxx_23_tests.cpp verbose_abort.cpp ) configure_tests(cxx_23_tests) target_compile_features(cxx_23_tests PRIVATE cxx_std_23) endif() # Windows-specific tests if (WIN32) add_executable(windows_tests windows.cpp ) configure_tests(windows_tests) target_compile_features(windows_tests PRIVATE cxx_std_98) endif() include(CTest) include(Catch) string(RANDOM LENGTH 5 ALPHABET 123456789 RNG_SEED) catch_discover_tests(cxx_98_tests EXTRA_ARGS --rng-seed ${RNG_SEED}) catch_discover_tests(cxx_11_tests EXTRA_ARGS --rng-seed ${RNG_SEED}) catch_discover_tests(cxx_17_tests EXTRA_ARGS --rng-seed ${RNG_SEED}) catch_discover_tests(cxx_20_tests EXTRA_ARGS --rng-seed ${RNG_SEED}) if ("cxx_std_23" IN_LIST CMAKE_CXX_COMPILE_FEATURES) catch_discover_tests(cxx_23_tests EXTRA_ARGS --rng-seed ${RNG_SEED}) endif() if (WIN32) catch_discover_tests(windows_tests EXTRA_ARGS --rng-seed ${RNG_SEED}) endif()