119 lines
4.4 KiB
CMake
119 lines
4.4 KiB
CMake
|
# generate test code coverage report
|
||
|
|
||
|
# check that coverage tools are available - always use before GEN_COVERAGE
|
||
|
macro(GEN_COVERAGE_ENABLE ENABLE_TESTS)
|
||
|
# make into normal variable
|
||
|
set(TESTS_ENABLED ${ENABLE_TESTS})
|
||
|
|
||
|
set(GEN_COVERAGE_ENABLED ON)
|
||
|
if(NOT TESTS_ENABLED)
|
||
|
message(WARNING "You cannot generate coverage when tests are disabled. Enable test by additing parameter -DENABLE_TESTS=ON or run cmake with Debug build target.")
|
||
|
set(GEN_COVERAGE_ENABLED OFF)
|
||
|
endif()
|
||
|
|
||
|
if(GEN_COVERAGE_ENABLED)
|
||
|
find_program(PATH_GCOV NAMES gcov)
|
||
|
if(NOT PATH_GCOV)
|
||
|
message(WARNING "gcov executable not found! Disabling building code coverage report.")
|
||
|
set(GEN_COVERAGE_ENABLED OFF)
|
||
|
endif()
|
||
|
endif()
|
||
|
|
||
|
if(GEN_COVERAGE_ENABLED)
|
||
|
find_program(PATH_LCOV NAMES lcov)
|
||
|
if(NOT PATH_LCOV)
|
||
|
message(WARNING "lcov executable not found! Disabling building code coverage report.")
|
||
|
set(GEN_COVERAGE_ENABLED OFF)
|
||
|
endif()
|
||
|
endif()
|
||
|
|
||
|
if(GEN_COVERAGE_ENABLED)
|
||
|
find_program(PATH_GENHTML NAMES genhtml)
|
||
|
if(NOT PATH_GENHTML)
|
||
|
message(WARNING "genhtml executable not found! Disabling building code coverage report.")
|
||
|
set(GEN_COVERAGE_ENABLED OFF)
|
||
|
endif()
|
||
|
endif()
|
||
|
|
||
|
if(GEN_COVERAGE_ENABLED)
|
||
|
if(NOT CMAKE_COMPILER_IS_GNUCC)
|
||
|
message(WARNING "Compiler is not gcc! Coverage may break the tests!")
|
||
|
endif()
|
||
|
|
||
|
execute_process(
|
||
|
COMMAND bash "-c" "${CMAKE_C_COMPILER} --version | head -n1 | sed \"s/.* (.*) \\([0-9]\\+.[0-9]\\+.[0-9]\\+ .*\\)/\\1/\""
|
||
|
OUTPUT_VARIABLE GCC_VERSION_FULL
|
||
|
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||
|
)
|
||
|
execute_process(
|
||
|
COMMAND bash "-c" "${PATH_GCOV} --version | head -n1 | sed \"s/.* (.*) \\([0-9]\\+.[0-9]\\+.[0-9]\\+ .*\\)/\\1/\""
|
||
|
OUTPUT_VARIABLE GCOV_VERSION_FULL
|
||
|
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||
|
)
|
||
|
if(NOT GCC_VERSION_FULL STREQUAL GCOV_VERSION_FULL)
|
||
|
message(WARNING "gcc and gcov versions do not match! Generating coverage may fail with errors.")
|
||
|
endif()
|
||
|
|
||
|
# add specific required compile flags
|
||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} --coverage -fprofile-arcs -ftest-coverage")
|
||
|
endif()
|
||
|
endmacro()
|
||
|
|
||
|
# tests are always expected to be in ${CMAKE_SOURCE_DIR}/tests
|
||
|
function(GEN_COVERAGE MATCH_TEST_REGEX EXCLUDE_TEST_REGEX)
|
||
|
if(NOT GEN_COVERAGE_ENABLED)
|
||
|
return()
|
||
|
endif()
|
||
|
|
||
|
# destination
|
||
|
set(COVERAGE_DIR "${CMAKE_BINARY_DIR}/code_coverage/")
|
||
|
set(COVERAGE_FILE_RAW "${CMAKE_BINARY_DIR}/coverage_raw.info")
|
||
|
set(COVERAGE_FILE_CLEAN "${CMAKE_BINARY_DIR}/coverage_clean.info")
|
||
|
|
||
|
# test match/exclude
|
||
|
if(MATCH_TEST_REGEX)
|
||
|
set(MATCH_TEST_ARGS -R \"${MATCH_TEST_REGEX}\")
|
||
|
endif()
|
||
|
if(EXCLUDE_TEST_REGEX)
|
||
|
set(EXCLUDE_TEST_ARGS -E \"${EXCLUDE_TEST_REGEX}\")
|
||
|
endif()
|
||
|
|
||
|
# coverage target
|
||
|
add_custom_target(coverage
|
||
|
COMMENT "Generating code coverage..."
|
||
|
WORKING_DIRECTORY "${CMAKE_BINARY_DIR}"
|
||
|
# Cleanup code counters
|
||
|
COMMAND "${PATH_LCOV}" --directory . --zerocounters --quiet
|
||
|
|
||
|
# Run tests
|
||
|
COMMAND "${CMAKE_CTEST_COMMAND}" --quiet ${MATCH_TEST_ARGS} ${EXCLUDE_TEST_ARGS}
|
||
|
|
||
|
# Capture the counters
|
||
|
COMMAND "${PATH_LCOV}"
|
||
|
--directory .
|
||
|
--rc lcov_branch_coverage=1
|
||
|
--rc 'lcov_excl_line=assert'
|
||
|
--capture --quiet
|
||
|
--output-file "${COVERAGE_FILE_RAW}"
|
||
|
# Remove coverage of tests, system headers, etc.
|
||
|
COMMAND "${PATH_LCOV}"
|
||
|
--remove "${COVERAGE_FILE_RAW}" '${CMAKE_SOURCE_DIR}/tests/*'
|
||
|
--rc lcov_branch_coverage=1
|
||
|
--quiet --output-file "${COVERAGE_FILE_CLEAN}"
|
||
|
# Generate HTML report
|
||
|
COMMAND "${PATH_GENHTML}"
|
||
|
--branch-coverage --function-coverage --quiet --title "${PROJECT_NAME}"
|
||
|
--legend --show-details --output-directory "${COVERAGE_DIR}"
|
||
|
"${COVERAGE_FILE_CLEAN}"
|
||
|
# Delete the counters
|
||
|
COMMAND "${CMAKE_COMMAND}" -E remove
|
||
|
${COVERAGE_FILE_RAW} ${COVERAGE_FILE_CLEAN}
|
||
|
)
|
||
|
|
||
|
add_custom_command(TARGET coverage POST_BUILD
|
||
|
WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/tests"
|
||
|
COMMENT "To see the code coverage report, open ${COVERAGE_DIR}index.html"
|
||
|
COMMAND ;
|
||
|
)
|
||
|
endfunction()
|