blob: 43a576b4c57f4cf84251841f38d037e58a3a27a1 [file] [log] [blame]
Michal Vaskod77e5af2021-06-04 08:32:29 +02001# generate test code coverage report
2
3# check that coverage tools are available - always use before GEN_COVERAGE
4macro(GEN_COVERAGE_ENABLE ENABLE_TESTS)
5 # make into normal variable
6 set(TESTS_ENABLED ${ENABLE_TESTS})
7
8 set(GEN_COVERAGE_ENABLED ON)
9 if(NOT TESTS_ENABLED)
10 message(WARNING "You cannot generate coverage when tests are disabled. Enable test by additing parameter -DENABLE_BUILD_TESTS=ON or run cmake with Debug build target.")
11 set(GEN_COVERAGE_ENABLED OFF)
12 endif()
13
14 if(GEN_COVERAGE_ENABLED)
15 find_program(PATH_GCOV NAMES gcov)
16 if(NOT PATH_GCOV)
17 message(WARNING "gcov executable not found! Disabling building code coverage report.")
18 set(GEN_COVERAGE_ENABLED OFF)
19 endif()
20 endif()
21
22 if(GEN_COVERAGE_ENABLED)
23 find_program(PATH_LCOV NAMES lcov)
24 if(NOT PATH_LCOV)
25 message(WARNING "lcov executable not found! Disabling building code coverage report.")
26 set(GEN_COVERAGE_ENABLED OFF)
27 endif()
28 endif()
29
30 if(GEN_COVERAGE_ENABLED)
31 find_program(PATH_GENHTML NAMES genhtml)
32 if(NOT PATH_GENHTML)
33 message(WARNING "genhtml executable not found! Disabling building code coverage report.")
34 set(GEN_COVERAGE_ENABLED OFF)
35 endif()
36 endif()
37
38 if(GEN_COVERAGE_ENABLED)
39 if(NOT CMAKE_COMPILER_IS_GNUCC)
40 message(WARNING "Compiler is not gcc! Coverage may break the tests!")
41 endif()
42
43 # add specific required compile flags
44 set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} --coverage -fprofile-arcs -ftest-coverage")
45 endif()
46endmacro()
47
48# tests are always expected to be in ${CMAKE_SOURCE_DIR}/tests
49function(GEN_COVERAGE MATCH_TEST_REGEX EXCLUDE_TEST_REGEX)
50 if(NOT GEN_COVERAGE_ENABLED)
51 return()
52 endif()
53
54 # destination
55 set(COVERAGE_DIR "${CMAKE_BINARY_DIR}/code_coverage/")
56 set(COVERAGE_FILE_RAW "${CMAKE_BINARY_DIR}/coverage_raw.info")
57 set(COVERAGE_FILE_CLEAN "${CMAKE_BINARY_DIR}/coverage_clean.info")
58
59 # test match/exclude
60 if(MATCH_TEST_REGEX)
61 set(MATCH_TEST_ARGS -R \"${MATCH_TEST_REGEX}\")
62 endif()
63 if(EXCLUDE_TEST_REGEX)
64 set(EXCLUDE_TEST_ARGS -E \"${EXCLUDE_TEST_REGEX}\")
65 endif()
66
67 # coverage target
68 add_custom_target(coverage
69 COMMENT "Generating code coverage..."
70 WORKING_DIRECTORY "${CMAKE_BINARY_DIR}"
71 # Cleanup code counters
72 COMMAND "${PATH_LCOV}" --directory . --zerocounters --quiet
73
74 # Run tests
75 COMMAND "${CMAKE_CTEST_COMMAND}" --quiet ${MATCH_TEST_ARGS} ${EXCLUDE_TEST_ARGS}
76
77 # Capture the counters
78 COMMAND "${PATH_LCOV}"
79 --directory .
80 --rc lcov_branch_coverage=1
81 --rc 'lcov_excl_line=assert'
82 --capture --quiet
83 --output-file "${COVERAGE_FILE_RAW}"
84 # Remove coverage of tests, system headers, etc.
85 COMMAND "${PATH_LCOV}"
86 --remove "${COVERAGE_FILE_RAW}" '${CMAKE_SOURCE_DIR}/tests/*'
87 --rc lcov_branch_coverage=1
88 --quiet --output-file "${COVERAGE_FILE_CLEAN}"
89 # Generate HTML report
90 COMMAND "${PATH_GENHTML}"
91 --branch-coverage --function-coverage --quiet --title "${PROJECT_NAME}"
92 --legend --show-details --output-directory "${COVERAGE_DIR}"
93 "${COVERAGE_FILE_CLEAN}"
94 # Delete the counters
95 COMMAND "${CMAKE_COMMAND}" -E remove
96 ${COVERAGE_FILE_RAW} ${COVERAGE_FILE_CLEAN}
97 )
98
99 add_custom_command(TARGET coverage POST_BUILD
100 WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/tests"
101 COMMENT "To see the code coverage report, open ${COVERAGE_DIR}index.html"
102 COMMAND ;
103 )
104endfunction()