blob: fe26d9e4237b81b7628a2fa3f05bc0ffc0b6a325 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
|
# 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()
|