|
10 | 10 | # |
11 | 11 | # ====================================================================================== |
12 | 12 |
|
13 | | -#[=======================================================================[.rst: |
14 | | -Coverage.cmake |
15 | | ----------------------- |
16 | | -
|
17 | | -Including this module enables support for code coverage reports. |
18 | | -
|
19 | | -This module sets ``CTEST_COVERAGE_COMMAND`` to ``gcov``'s location, if it can be found. |
20 | | -
|
21 | | -Variables |
22 | | -^^^^^^^^^^ |
23 | | -
|
24 | | -.. variable:: GCOV_PROGRAM |
25 | | -
|
26 | | - Path to the ``gcov`` executable. |
27 | | -
|
28 | | -.. variable:: GENINFO_PROGRAM |
29 | | -
|
30 | | - Path to the ``geninfo`` executable. |
31 | | -
|
32 | | -.. variable:: GENHTML_PROGRAM |
33 | | -
|
34 | | - Path to the ``genhtml`` executable. |
35 | | -
|
36 | | -Targets |
37 | | -^^^^^^^^^ |
38 | | -
|
39 | | -Each target will only exist if all required tools could be found. |
40 | | -
|
41 | | -.. target:: coverage-clean |
42 | | -
|
43 | | - Executes a script to remove all previously generated coverage files from the build tree. |
44 | | - This can be useful if you get test output containing errors mentioning failure to merge |
45 | | - previous coverage output, etc. |
46 | | -
|
47 | | -.. target:: coverage-report |
48 | | -
|
49 | | - Builds a coverage report from coverage files found in the build tree. Requires that gcov, |
50 | | - geninfo, and genhtml could all be found. |
51 | | -
|
52 | | -.. target:: open-coverage |
53 | | -
|
54 | | - First builds ``coverage-report``, then opens the generated HTML in your default browser. |
55 | | -
|
56 | | -#]=======================================================================] |
| 13 | +# Including this module globally enables coverage flags. |
57 | 14 |
|
58 | 15 | include_guard (GLOBAL) |
59 | 16 |
|
60 | 17 | include (FeatureSummary) |
61 | 18 |
|
62 | | -# set up compiler flags to generate coverage output |
63 | | - |
64 | | -get_cmake_property (debug_configs DEBUG_CONFIGURATIONS) |
65 | | - |
66 | | -if (NOT debug_configs) |
67 | | - set (debug_configs Debug) |
68 | | -endif () |
69 | | - |
70 | | -list (JOIN debug_configs "," debug_configs) |
71 | | - |
72 | | -set (config_debug "$<CONFIG:${debug_configs}>") |
73 | | - |
74 | | -if (MSVC) |
75 | | - add_compile_options ("$<${config_debug}:/fsanitize-coverage=edge>") |
76 | | - return () |
77 | | -endif () |
78 | | - |
79 | | -add_compile_options ("$<${config_debug}:--coverage>") |
80 | | -add_link_options ("$<${config_debug}:--coverage>") |
81 | | - |
82 | | -if (APPLE) |
83 | | - add_compile_options ("$<${config_debug}:-fprofile-arcs>") |
84 | | - add_link_options ("$<${config_debug}:-fprofile-arcs>") |
85 | | -endif () |
86 | | - |
87 | | -if (CMAKE_C_COMPILER_ID MATCHES "Clang") |
88 | | - add_compile_options ( |
89 | | - "$<${config_debug}:-ftest-coverage;-fprofile-instr-generate;-fcoverage-mapping>" |
90 | | - ) |
91 | | -endif () |
92 | | - |
93 | | -# add custom target to clean old coverage output |
94 | | - |
95 | | -set (COVERAGE_OUTPUT_DIR "${CMAKE_BINARY_DIR}/coverage/$<CONFIG>") |
96 | | -set (COVERAGE_INFO_FILE "${COVERAGE_OUTPUT_DIR}/coverage.info") |
97 | | - |
98 | | -add_custom_target ( |
99 | | - coverage-clean |
100 | | - COMMAND |
101 | | - "${CMAKE_COMMAND}" -D "COVERAGE_OUTPUT_DIR=${COVERAGE_OUTPUT_DIR}" -D |
102 | | - "CMAKE_BINARY_DIR=${CMAKE_BINARY_DIR}" -D "CMAKE_SOURCE_DIR=${CMAKE_SOURCE_DIR}" -P |
103 | | - "${CMAKE_CURRENT_LIST_DIR}/detail/DeleteOldCoverageOutput.cmake" |
104 | | - COMMENT "[coverage] - Cleaning old coverage output files..." |
105 | | - VERBATIM |
106 | | -) |
107 | | - |
108 | | -# set up coverage reports |
109 | | - |
110 | | -find_program (GCOV_PROGRAM gcov DOC "gcov executable") |
111 | | -find_program (GENINFO_PROGRAM geninfo DOC "geninfo executable") |
112 | | -find_program (GENHTML_PROGRAM genhtml DOC "genhtml executable") |
113 | | - |
114 | | -mark_as_advanced (GCOV_PROGRAM GENINFO_PROGRAM GENHTML_PROGRAM) |
115 | | - |
116 | 19 | add_feature_info ( |
117 | | - CoverageReports "GENINFO_PROGRAM AND GENHTML_PROGRAM" |
118 | | - "Custom targets to generate/open coverage report (requires geninfo & genhtml)" |
| 20 | + coverage [[CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang" AND NOT WIN32]] |
| 21 | + "Enabled coverage reporting flags for debug configurations" |
119 | 22 | ) |
120 | 23 |
|
121 | | -if (NOT (GENINFO_PROGRAM AND GENHTML_PROGRAM)) |
122 | | - return () |
123 | | -endif () |
| 24 | +if (CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang" AND NOT WIN32) |
| 25 | + get_cmake_property (debug_configs DEBUG_CONFIGURATIONS) |
124 | 26 |
|
125 | | -include (FetchContent) |
| 27 | + if (NOT debug_configs) |
| 28 | + set (debug_configs Debug) |
| 29 | + endif () |
126 | 30 |
|
127 | | -add_custom_command ( |
128 | | - OUTPUT "${COVERAGE_INFO_FILE}" |
129 | | - COMMAND |
130 | | - "${GENINFO_PROGRAM}" "${CMAKE_SOURCE_DIR}" --exclude "${FETCHCONTENT_BASE_DIR}" --gcov-tool |
131 | | - "${GCOV_PROGRAM}" --branch-coverage --no-external --follow --forget-test-names |
132 | | - --demangle-cpp --keep-going --rc derive_function_end_line=0 -o "${COVERAGE_INFO_FILE}" |
133 | | - --ignore-errors empty,inconsistent,format,unsupported,category,range,source,unused |
134 | | - COMMENT "[coverage] - Running geninfo on .gcda coverage output files..." |
135 | | - VERBATIM |
136 | | -) |
| 31 | + if (APPLE) |
| 32 | + # On MacOS, UBSAN seems to interfere with coverage collection, it erroneously reports 0-4%, |
| 33 | + # so just disable it |
| 34 | + list (REMOVE_ITEM debug_configs UBSAN) |
| 35 | + endif () |
137 | 36 |
|
138 | | -set (index_html "${COVERAGE_OUTPUT_DIR}/index.html") |
| 37 | + list (JOIN debug_configs "," debug_configs) |
139 | 38 |
|
140 | | -add_custom_command ( |
141 | | - OUTPUT "${index_html}" |
142 | | - COMMAND |
143 | | - "${GENHTML_PROGRAM}" "${COVERAGE_INFO_FILE}" --header-title |
144 | | - "${CMAKE_PROJECT_NAME} coverage report" --prefix "${CMAKE_SOURCE_DIR}" --precision 1 |
145 | | - --filter "brace,blank,range,function" --show-zero-columns --suppress-aliases |
146 | | - --simplified-colors --elide-path-mismatch --sort --dark-mode --synthesize-missing |
147 | | - --show-navigation --legend --function-coverage --branch-coverage --demangle-cpp |
148 | | - --forget-test-names --keep-going -o "${COVERAGE_OUTPUT_DIR}" --ignore-errors |
149 | | - empty,inconsistent,format,unsupported,category,range,source |
150 | | - COMMAND "${CMAKE_COMMAND}" -E echo |
151 | | - "Coverage report generated. Open ${index_html} in your browser." |
152 | | - WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}" |
153 | | - DEPENDS "${COVERAGE_INFO_FILE}" |
154 | | - COMMENT "[coverage] - Running genhtml to create coverage report..." |
155 | | - VERBATIM |
156 | | -) |
| 39 | + set (config_debug "$<CONFIG:${debug_configs}>") |
157 | 40 |
|
158 | | -add_custom_target (coverage-report DEPENDS "${index_html}") |
| 41 | + add_compile_options ("$<${config_debug}:-g;-O0;--coverage>") |
| 42 | + add_link_options ("$<${config_debug}:--coverage>") |
159 | 43 |
|
160 | | -set_property (DIRECTORY APPEND PROPERTY ADDITIONAL_CLEAN_FILES "${COVERAGE_OUTPUT_DIR}") |
| 44 | + if (CMAKE_CXX_COMPILER_ID MATCHES "GNU") |
| 45 | + link_libraries ("$<${config_debug}:gcov>") |
| 46 | + endif () |
161 | 47 |
|
162 | | -if (WIN32) |
163 | | - set (open_cmd start) |
164 | | -else () |
165 | | - set (open_cmd open) |
166 | | -endif () |
167 | | - |
168 | | -add_custom_target (open-coverage COMMAND "${open_cmd}" "${index_html}") |
169 | | - |
170 | | -add_dependencies (open-coverage coverage-report) |
| 48 | + set (clean_script "${CMAKE_SOURCE_DIR}/scripts/CleanOldCoverageOutput.cmake") |
171 | 49 |
|
172 | | -set_target_properties (coverage-report coverage-clean open-coverage PROPERTIES FOLDER coverage) |
| 50 | + add_custom_target ( |
| 51 | + coverage-clean |
| 52 | + COMMAND "${CMAKE_COMMAND}" -D "BUILD_DIR=${CMAKE_BINARY_DIR}" -P "${clean_script}" |
| 53 | + COMMENT "Cleaning old coverage output files..." |
| 54 | + VERBATIM USES_TERMINAL |
| 55 | + SOURCES "${clean_script}" |
| 56 | + ) |
| 57 | +endif () |
0 commit comments