|
| 1 | +function(omath_setup_coverage_for_root OMATH_PROJECT) |
| 2 | + # Configure compilation properties for coverage helper translation units |
| 3 | + # (use project root paths so this behaves the same regardless of where |
| 4 | + # the file is included from). |
| 5 | + set(OMATH_SRC_DIR "${CMAKE_SOURCE_DIR}") |
| 6 | + set(OMATH_BIN_DIR "${CMAKE_BINARY_DIR}") |
| 7 | + |
| 8 | + # If forward_helpers.cpp is present, compile it with inlining disabled. |
| 9 | + if (EXISTS "${OMATH_SRC_DIR}/source/coverage/forward_helpers.cpp") |
| 10 | + if (CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang|AppleClang") |
| 11 | + set_source_files_properties(${OMATH_SRC_DIR}/source/coverage/forward_helpers.cpp PROPERTIES COMPILE_FLAGS "-fno-inline") |
| 12 | + elseif (MSVC) |
| 13 | + set_source_files_properties(${OMATH_SRC_DIR}/source/coverage/forward_helpers.cpp PROPERTIES COMPILE_FLAGS "/Ob0") |
| 14 | + endif() |
| 15 | + endif() |
| 16 | + |
| 17 | + # Always provide the coverage_coalescer tool target if the source exists. |
| 18 | + if (EXISTS "${OMATH_SRC_DIR}/tools/coverage_coalescer.cpp" AND NOT TARGET coverage_coalescer) |
| 19 | + add_executable(coverage_coalescer ${OMATH_SRC_DIR}/tools/coverage_coalescer.cpp) |
| 20 | + set_target_properties(coverage_coalescer PROPERTIES |
| 21 | + RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/tools" |
| 22 | + OUTPUT_NAME "coverage_coalescer" |
| 23 | + ) |
| 24 | + endif() |
| 25 | + |
| 26 | + # Also disable inlining for other coverage helper translation units. |
| 27 | + if (EXISTS "${OMATH_SRC_DIR}/source/coverage/linear_algebra_wrappers.cpp") |
| 28 | + if (CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang|AppleClang") |
| 29 | + set_source_files_properties(${OMATH_SRC_DIR}/source/coverage/linear_algebra_wrappers.cpp PROPERTIES COMPILE_FLAGS "-fno-inline") |
| 30 | + elseif (MSVC) |
| 31 | + set_source_files_properties(${OMATH_SRC_DIR}/source/coverage/linear_algebra_wrappers.cpp PROPERTIES COMPILE_FLAGS "/Ob0") |
| 32 | + endif() |
| 33 | + endif() |
| 34 | + |
| 35 | + if (EXISTS "${OMATH_SRC_DIR}/source/coverage/extra_linear_algebra_coverage.cpp") |
| 36 | + if (CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang|AppleClang") |
| 37 | + set_source_files_properties(${OMATH_SRC_DIR}/source/coverage/extra_linear_algebra_coverage.cpp PROPERTIES COMPILE_FLAGS "-fno-inline") |
| 38 | + elseif (MSVC) |
| 39 | + set_source_files_properties(${OMATH_SRC_DIR}/source/coverage/extra_linear_algebra_coverage.cpp PROPERTIES COMPILE_FLAGS "/Ob0") |
| 40 | + endif() |
| 41 | + endif() |
| 42 | + |
| 43 | + if (EXISTS "${OMATH_SRC_DIR}/source/coverage/explicit_instantiations.cpp") |
| 44 | + if (CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang|AppleClang") |
| 45 | + set_source_files_properties(${OMATH_SRC_DIR}/source/coverage/explicit_instantiations.cpp PROPERTIES COMPILE_FLAGS "-fno-inline") |
| 46 | + elseif (MSVC) |
| 47 | + set_source_files_properties(${OMATH_SRC_DIR}/source/coverage/explicit_instantiations.cpp PROPERTIES COMPILE_FLAGS "/Ob0") |
| 48 | + endif() |
| 49 | + endif() |
| 50 | + |
| 51 | + # Add additional debug-related flags to coverage-related TUs |
| 52 | + set(COVERAGE_TUS |
| 53 | + ${OMATH_SRC_DIR}/source/coverage/forward_helpers.cpp |
| 54 | + ${OMATH_SRC_DIR}/source/coverage/explicit_instantiations.cpp |
| 55 | + ${OMATH_SRC_DIR}/source/coverage/force_instantiations.cpp |
| 56 | + ${OMATH_SRC_DIR}/source/coverage/linear_algebra_wrappers.cpp |
| 57 | + ${OMATH_SRC_DIR}/source/coverage/extra_linear_algebra_coverage.cpp) |
| 58 | + |
| 59 | + foreach(_tu IN LISTS COVERAGE_TUS) |
| 60 | + if (EXISTS "${_tu}") |
| 61 | + if (CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang|AppleClang") |
| 62 | + set_source_files_properties(${_tu} PROPERTIES COMPILE_FLAGS "-g -O0 -fno-omit-frame-pointer -fno-inline") |
| 63 | + elseif (MSVC) |
| 64 | + set_source_files_properties(${_tu} PROPERTIES COMPILE_FLAGS "/Zo /Oy- /Ob0") |
| 65 | + endif() |
| 66 | + endif() |
| 67 | + endforeach() |
| 68 | + |
| 69 | + # Project-level coverage configuration (compiler/linker flags and coverage targets) |
| 70 | + if(CMAKE_HOST_LINUX AND OMATH_BUILD_TESTS) |
| 71 | + if (CMAKE_CXX_COMPILER_ID MATCHES "Clang|AppleClang") |
| 72 | + target_compile_options(${OMATH_PROJECT} PRIVATE |
| 73 | + $<$<CONFIG:Debug>:-g> |
| 74 | + $<$<CONFIG:Debug>:-fprofile-instr-generate> |
| 75 | + $<$<CONFIG:Debug>:-fcoverage-mapping> |
| 76 | + ) |
| 77 | + else() |
| 78 | + target_compile_options(${OMATH_PROJECT} PRIVATE |
| 79 | + $<$<CONFIG:Debug>:-g> |
| 80 | + $<$<CONFIG:Debug>:-fprofile-arcs> |
| 81 | + $<$<CONFIG:Debug>:-ftest-coverage> |
| 82 | + ) |
| 83 | + target_link_libraries(${OMATH_PROJECT} PRIVATE |
| 84 | + $<$<CONFIG:Debug>:-fprofile-arcs> |
| 85 | + $<$<CONFIG:Debug>:-ftest-coverage> |
| 86 | + ) |
| 87 | + endif() |
| 88 | + |
| 89 | + if (CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang|AppleClang") |
| 90 | + file(TO_CMAKE_PATH "${OMATH_SRC_DIR}" OMATH_SRC_PATH) |
| 91 | + file(TO_CMAKE_PATH "${OMATH_BIN_DIR}" OMATH_BUILD_PATH) |
| 92 | + string(REPLACE "/" "\\/" OMATH_SRC_PATH_ESCAPED "${OMATH_SRC_PATH}") |
| 93 | + string(REPLACE "/" "\\/" OMATH_BUILD_PATH_ESCAPED "${OMATH_BUILD_PATH}") |
| 94 | + |
| 95 | + target_compile_options(${OMATH_PROJECT} PRIVATE |
| 96 | + $<$<CONFIG:Debug>:-ffile-prefix-map=${OMATH_SRC_PATH}=..> |
| 97 | + $<$<CONFIG:Debug>:-ffile-prefix-map=${OMATH_BUILD_PATH}=.> |
| 98 | + $<$<CONFIG:Debug>:-fdebug-prefix-map=${OMATH_SRC_PATH}=..> |
| 99 | + $<$<CONFIG:Debug>:-fdebug-prefix-map=${OMATH_BUILD_PATH}=.> |
| 100 | + ) |
| 101 | + endif() |
| 102 | + |
| 103 | + # Expose variables for coverage script substitution and configure script |
| 104 | + set(OMATH_LCOV_IGNORE_ERRORS "mismatch,inconsistent") |
| 105 | + set(OMATH_BR_EXCLUSION "LCOV_EXCL_BR_LINE|assert\\(") |
| 106 | + set(OMATH_LCOV_EXTRACT_PATHS "\"${OMATH_SRC_DIR}/include/omath/linear_algebra/*\" \"${OMATH_SRC_DIR}/include/omath/*\" \"${OMATH_SRC_DIR}/include/*\" \"${OMATH_SRC_DIR}/source/*\"") |
| 107 | + |
| 108 | + set(LCOV_IGNORE_ERRORS "${OMATH_LCOV_IGNORE_ERRORS}") |
| 109 | + set(BR_EXCLUSION "${OMATH_BR_EXCLUSION}") |
| 110 | + set(LCOV_EXTRACT_PATHS "${OMATH_LCOV_EXTRACT_PATHS}") |
| 111 | + |
| 112 | + configure_file( |
| 113 | + "${OMATH_SRC_DIR}/scripts/coverage.sh.in" |
| 114 | + "${OMATH_BIN_DIR}/scripts/coverage.sh" |
| 115 | + @ONLY) |
| 116 | + |
| 117 | + # Ensure the coverage_coalescer tool is available (guard already above). |
| 118 | + |
| 119 | + # Add coverage helper make clean files and targets |
| 120 | + set_property( |
| 121 | + DIRECTORY |
| 122 | + APPEND |
| 123 | + PROPERTY ADDITIONAL_MAKE_CLEAN_FILES "coverage.info") |
| 124 | + set_property( |
| 125 | + DIRECTORY |
| 126 | + APPEND |
| 127 | + PROPERTY ADDITIONAL_MAKE_CLEAN_FILES "coverage.cleaned.info") |
| 128 | + set_property( |
| 129 | + DIRECTORY |
| 130 | + APPEND |
| 131 | + PROPERTY ADDITIONAL_MAKE_CLEAN_FILES "coverage") |
| 132 | + add_custom_target( |
| 133 | + coverage |
| 134 | + DEPENDS unit_tests |
| 135 | + COMMAND bash "${OMATH_BIN_DIR}/scripts/coverage.sh" |
| 136 | + "${OMATH_SRC_DIR}" "${OMATH_BIN_DIR}" |
| 137 | + WORKING_DIRECTORY "${OMATH_BIN_DIR}" |
| 138 | + COMMENT "Run coverage: run tests, collect via gcov, postprocess and generate HTML") |
| 139 | + add_custom_target( |
| 140 | + clean-coverage |
| 141 | + COMMAND lcov --rc branch_coverage=1 --directory |
| 142 | + '${OMATH_BIN_DIR}' --zerocounters |
| 143 | + COMMENT "Zeroing counters") |
| 144 | + endif() |
| 145 | +endfunction() |
| 146 | + |
| 147 | +function(omath_setup_coverage_for_test TEST_TARGET) |
| 148 | + # Called from tests/CMakeLists; CMAKE_CURRENT_SOURCE_DIR will be the tests/ dir |
| 149 | + set(TEST_SRC_DIR "${CMAKE_CURRENT_SOURCE_DIR}") |
| 150 | + |
| 151 | + # Compile specific TU without inlining to help coverage attribute header lines |
| 152 | + set_source_files_properties( |
| 153 | + ${TEST_SRC_DIR}/general/coverage_instantiations.cpp |
| 154 | + ${TEST_SRC_DIR}/general/coverage_utility_instantiations.cpp |
| 155 | + PROPERTIES COMPILE_OPTIONS "-fno-inline") |
| 156 | + |
| 157 | + # If building with Clang and coverage enabled, remove any GCC-style |
| 158 | + # coverage link flags that might have been propagated to the test target |
| 159 | + # so that Clang's instrumentation flags control the coverage output. |
| 160 | + if (CMAKE_CXX_COMPILER_ID MATCHES "Clang|AppleClang") |
| 161 | + string(REPLACE "-fprofile-arcs" "" _tmp_link_opts "${CMAKE_SHARED_LINKER_FLAGS}") |
| 162 | + string(REPLACE "-ftest-coverage" "" _tmp_link_opts "${_tmp_link_opts}") |
| 163 | + set_target_properties(${TEST_TARGET} PROPERTIES LINK_FLAGS "${_tmp_link_opts}") |
| 164 | + target_compile_options(${TEST_TARGET} PRIVATE |
| 165 | + $<$<CONFIG:Debug>:-fprofile-instr-generate> |
| 166 | + $<$<CONFIG:Debug>:-fcoverage-mapping> |
| 167 | + $<$<CONFIG:Debug>:-g> |
| 168 | + ) |
| 169 | + if(EMSCRIPTEN) |
| 170 | + target_compile_options(${TEST_TARGET} PRIVATE -fexceptions) |
| 171 | + target_link_options(${TEST_TARGET} PRIVATE -fexceptions) |
| 172 | + endif() |
| 173 | + if (CMAKE_VERSION VERSION_GREATER "3.13") |
| 174 | + target_link_options(${TEST_TARGET} PRIVATE $<$<CONFIG:Debug>:-fprofile-instr-generate> $<$<CONFIG:Debug>:-fcoverage-mapping>) |
| 175 | + else() |
| 176 | + string(APPEND _tmp_link_flags " -fprofile-instr-generate -fcoverage-mapping") |
| 177 | + set_target_properties(${TEST_TARGET} PROPERTIES LINK_FLAGS "${_tmp_link_flags}") |
| 178 | + endif() |
| 179 | + endif() |
| 180 | + |
| 181 | + # Discover tests except on platforms where test binaries cannot run |
| 182 | + if (NOT (ANDROID OR IOS OR EMSCRIPTEN)) |
| 183 | + include(GoogleTest) |
| 184 | + gtest_discover_tests(${TEST_TARGET}) |
| 185 | + endif() |
| 186 | +endfunction() |
0 commit comments