diff --git a/unit_tests/CMakeLists.txt b/unit_tests/CMakeLists.txt index 8c9a6ad8d38f301ce638ce2e808a88c534c09ca0..cf7e896da87c9b08c08325874e78ad7957ec27da 100644 --- a/unit_tests/CMakeLists.txt +++ b/unit_tests/CMakeLists.txt @@ -1,4 +1,8 @@ -find_package(Catch2 QUIET) +# Catch2 configuration +set(CATCH2_MIN_VERSION 3.3.0) + +# Try to find system installed Catch2 +find_package(Catch2 ${CATCH2_MIN_VERSION} QUIET) if(NOT Catch2_FOUND) message(STATUS "Catch2 not found in system, retrieving from git") @@ -9,62 +13,93 @@ if(NOT Catch2_FOUND) GIT_REPOSITORY https://github.com/catchorg/Catch2.git GIT_TAG devel # or a later release ) - FetchContent_MakeAvailable(Catch2) + message(STATUS "Fetched Catch2 version ${Catch2_VERSION}") else() - message(STATUS "Found system Catch2 version ${Catch2_VERSION}") + message(STATUS "Using system Catch2 version ${Catch2_VERSION}") endif() +# Get all source files file(GLOB_RECURSE src_files "*.cpp") +# Create test executable add_executable(tests${module_name} ${src_files}) +# Set C++14 standard target_compile_features(tests${module_name} PRIVATE cxx_std_14) set(FORCE_CI TRUE) -if (NOT(FORCE_CI)) - -if (DOSANITIZE STREQUAL "ON") -set(SANITIZE_FLAGS -fsanitize=address,leak,undefined,float-divide-by-zero -fno-omit-frame-pointer) -#TODO sanitizer seems buggy in some situations with msvc, leading to linker errors, temporarily inactivating it -#set(SANITIZE_MSVC_FLAGS) -set(SANITIZE_MSVC_FLAGS /fsanitize=address) -target_compile_definitions(tests${module_name} PUBLIC _DISABLE_VECTOR_ANNOTATION) -else() -set(SANITIZE_FLAGS) -set(SANITIZE_MSVC_FLAGS) -endif() +# Compiler flags and options +if(NOT(FORCE_CI)) + # Sanitization configuration + if(DOSANITIZE STREQUAL "ON") + set(SANITIZE_FLAGS + -fsanitize=address,leak,undefined,float-divide-by-zero + -fno-omit-frame-pointer + ) + set(SANITIZE_MSVC_FLAGS /fsanitize=address) -set(STRICT_ALIASING_FLAGS -fstrict-aliasing -Wstrict-aliasing=2) - -# -fvisibility=hidden required by pybind11 -target_compile_options(tests${module_name} PUBLIC - $<$<OR:$<CXX_COMPILER_ID:Clang>,$<CXX_COMPILER_ID:AppleClang>,$<CXX_COMPILER_ID:GNU>>: - -fvisibility=hidden>) -target_compile_options(tests${module_name} PRIVATE -$<$<OR:$<CXX_COMPILER_ID:Clang>,$<CXX_COMPILER_ID:AppleClang>,$<CXX_COMPILER_ID:GNU>>: --Wall -Wextra -Wold-style-cast -pedantic -Werror=narrowing -Wshadow $<$<BOOL:${WERROR}>:-Werror> ${SANITIZE_FLAGS}>) -target_compile_options(tests${module_name} PRIVATE -$<$<CXX_COMPILER_ID:GNU>:${STRICT_ALIASING_FLAGS}>) -target_compile_options(${module_name} PRIVATE -$<$<CXX_COMPILER_ID:MSVC>: -/W4 /DWIN32 /D_WINDOWS /GR /EHsc /MP /Zc:__cplusplus /Zc:preprocessor /permissive- ${SANITIZE_MSVC_FLAGS}>) -if (DOSANITIZE STREQUAL "ON") - target_compile_options(${module_name} PRIVATE $<$<CXX_COMPILER_ID:MSVC>:/MDd>) -endif() -# TODO FIXME: I'm not sure it's a good idea to propagate this option but, at this point, it was the only way that worked to silence C4477 -target_compile_options(${module_name} PUBLIC $<$<CXX_COMPILER_ID:MSVC>: /wd4477>) + # Temporary workaround for MSVC sanitizer issues + target_compile_definitions(tests${module_name} PUBLIC _DISABLE_VECTOR_ANNOTATION) + else() + set(SANITIZE_FLAGS "") + set(SANITIZE_MSVC_FLAGS "") + endif() -target_link_options(tests${module_name} PUBLIC $<$<OR:$<CXX_COMPILER_ID:Clang>,$<CXX_COMPILER_ID:AppleClang>,$<CXX_COMPILER_ID:GNU>>:${SANITIZE_FLAGS}>) -#target_link_options(tests${module_name} PUBLIC $<$<CXX_COMPILER_ID:MSVC>:${SANITIZE_MSVC_FLAGS}>) + # Strict aliasing for better type safety + set(STRICT_ALIASING_FLAGS -fstrict-aliasing -Wstrict-aliasing=2) -endif() + # Compiler options for different toolchains + target_compile_options(tests${module_name} PUBLIC + $<$<OR:$<CXX_COMPILER_ID:Clang>,$<CXX_COMPILER_ID:AppleClang>,$<CXX_COMPILER_ID:GNU>>: + -fvisibility=hidden> # Hide symbols by default + ) # -fvisibility=hidden required by Pybind11 -target_link_libraries(tests${module_name} PRIVATE ${module_name}) + # Common warning and error flags + target_compile_options(tests${module_name} PRIVATE + $<$<OR:$<CXX_COMPILER_ID:Clang>,$<CXX_COMPILER_ID:AppleClang>,$<CXX_COMPILER_ID:GNU>>: + -Wall -Wextra -Wold-style-cast -pedantic -Werror=narrowing -Wshadow + $<$<BOOL:${WERROR}>:-Werror> + ${SANITIZE_FLAGS} + > + ) + # Strict aliasing for GCC + target_compile_options(tests${module_name} PRIVATE + $<$<CXX_COMPILER_ID:GNU>:${STRICT_ALIASING_FLAGS}> + ) -target_link_libraries(tests${module_name} PRIVATE Catch2::Catch2WithMain) + # MSVC-specific settings + target_compile_options(tests${module_name} PRIVATE + $<$<CXX_COMPILER_ID:MSVC>: + /W4 /DWIN32 /D_WINDOWS /GR /EHsc /MP + /Zc:__cplusplus /Zc:preprocessor /permissive- + ${SANITIZE_MSVC_FLAGS} + > + ) + + # Workaround for C4477 warning in MSVC + if(DOSANITIZE STREQUAL "ON") + target_compile_options(tests${module_name} PRIVATE $<$<CXX_COMPILER_ID:MSVC>:/MDd>) + endif() + + # TODO: Fix this once proper configuration is available + # only way to silence C4477 + target_compile_options(tests${module_name} PUBLIC $<$<CXX_COMPILER_ID:MSVC>: /wd4477>) +endif() +# Link libraries +target_link_libraries(tests${module_name} PRIVATE + ${module_name} + Catch2::Catch2WithMain +) + +# Setup testing list(APPEND CMAKE_MODULE_PATH ${catch2_SOURCE_DIR}/extras) include(CTest) include(Catch) + +# Discover and add tests catch_discover_tests(tests${module_name}) + +# Set test configuration for CTest +set(CTEST_CONFIGURATION_TYPE ${CMAKE_BUILD_TYPE}) \ No newline at end of file