blob: 4b930b801320bb2500bcad7a40689228bc34764a [file] [log] [blame]
Javier Almansa Sobrino576071e2022-09-09 16:01:17 +01001#
2# SPDX-License-Identifier: BSD-3-Clause
3# SPDX-FileCopyrightText: Copyright TF-RMM Contributors.
4#
5
6arm_config_option(
7 NAME RMM_COVERAGE
8 HELP "Enable coverage tests"
9 TYPE BOOL
10 DEFAULT "OFF")
11
12arm_config_option(
13 NAME RMM_HTML_COV_REPORT
14 HELP "Enable html coverage report"
15 TYPE BOOL
16 DEPENDS RMM_COVERAGE
17 DEFAULT "ON")
18
19arm_config_option(
20 NAME COVERAGE_REPORT_NAME
21 HELP "Canonical name for the coverage report"
22 TYPE STRING
23 DEPENDS RMM_COVERAGE
24 DEFAULT "tf-rmm-coverage"
25 ADVANCED)
26
27macro(check_and_prepare_c_coverage_flags)
28 # Store a copy of CMAKE_C_FLAGS
29 set(CMAKE_C_FLAGS_BACKUP "${CMAKE_C_FLAGS}")
30
31 foreach(flag ${ARGN})
32 string(REPLACE "-" "_" flag_no_hyphen ${flag})
33 check_c_compiler_flag("-${flag}" COVERAGE_C_FLAG_${flag_no_hyphen})
34 if (COVERAGE_C_FLAG_${flag_no_hyphen})
35 # Some of the coverage flags depend on the previous ones being
36 # enabled, so add them to the C Flags now for the next check.
37 string(APPEND CMAKE_C_FLAGS " -${flag}")
38 string(APPEND COVERAGE_C_FLAGS " -${flag}")
39 else()
40 set(COVERAGE_SUPPORTED "FALSE")
41 endif()
42 endforeach()
43
44 # Restore CMAKE_C_FLAGS
45 set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS_BACKUP}")
46endmacro(check_and_prepare_c_coverage_flags)
47
48macro(check_and_prepare_cxx_coverage_flags)
49 # Store a copy of CMAKE_CXX_FLAGS
50 set(CMAKE_CXX_FLAGS_BACKUP "${CMAKE_CXX_FLAGS}")
51
52 foreach(flag ${ARGN})
53 string(REPLACE "-" "_" flag_no_hyphen ${flag})
54 check_cxx_compiler_flag("-${flag}" COVERAGE_CXX_FLAG_${flag_no_hyphen})
55 if (COVERAGE_CXX_FLAG_${flag_no_hyphen})
56 # Some of the coverage flags depend on the previous ones being
57 # enabled, so add them to the CXX Flags now for the next check.
58 string(APPEND CMAKE_CXX_FLAGS " -${flag}")
59 string(APPEND COVERAGE_CXX_FLAGS " -${flag}")
60 endif()
61 endforeach()
62
63 # Restore CMAKE_CXX_FLAGS
64 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS_BACKUP}")
65endmacro(check_and_prepare_cxx_coverage_flags)
66
67if(RMM_COVERAGE)
68
69 find_program(GCOVR_EXECUTABLE "gcovr" DOC "Path to gcovr")
70
71 if(${GCOVR_EXECUTABLE} STREQUAL "GCOVR_EXECUTABLE-NOTFOUND")
72 message (WARNING "gcovr executable not found. Coverage tests disabled")
73 return()
74 endif()
75
76 include(CheckCCompilerFlag)
77 include(CheckCXXCompilerFlag)
78
79 if(CMAKE_C_COMPILER_ID STREQUAL "Clang")
80 # Using LLVM. Select the coverage flags to test
81 set(COVERAGE_FLAGS
82 ftest-coverage
83 fprofile-instr-generate
84 fprofile-arcs
85 fcoverage-mapping)
86
87 # Setup the right coverage tool if using llvm
88 set(GCOVR_EXE_OPTION --gcov-executable "llvm-cov gcov"
89 CACHE INTERNAL "GCOV_EXECUTABLE")
90
91 elseif(CMAKE_C_COMPILER_ID STREQUAL "GNU")
92 # Using GNU. Select the coverage flags to test
93 set(COVERAGE_FLAGS
94 -coverage)
95
96 # Flags needed to enable coverage testing
97 string(APPEND CMAKE_EXE_LINKER_FLAGS " -coverage -lgcov ")
98 else()
99 message(WARNING "Toolchain ${CMAKE_C_COMPILER_ID} does not support coverage")
100 return()
101 endif()
102
103 set(COVERAGE_SUPPORTED "TRUE")
104 check_and_prepare_c_coverage_flags(${COVERAGE_FLAGS})
105 check_and_prepare_cxx_coverage_flags(${COVERAGE_FLAGS})
106
107 # If coverage is not supported by the C compiler, or the C and C++
108 # compilers do not support the same set of coverage flags (which can
109 # lead to link problems), abort.
110 if ((COVERAGE_SUPPORTED STREQUAL "FALSE") OR
111 (NOT (COVERAGE_C_FLAGS STREQUAL COVERAGE_CXX_FLAGS)))
112 message (WARNING "Toolchain ${CMAKE_C_COMPILER_ID} does not support coverage")
113 return()
114 endif()
115
116 # Setup flags for coverage
117 foreach(language in ITEMS C CXX)
118 string(APPEND CMAKE_${language}_FLAGS
119 " ${COVERAGE_${language}_FLAGS} ")
120 endforeach()
121
122 # Directory where to store the results
123 set(COVERAGE_DIRECTORY
124 "${CMAKE_BINARY_DIR}/$<CONFIG>/coverage")
125
126 set(COVERAGE_OUTPUT "${COVERAGE_DIRECTORY}/${COVERAGE_REPORT_NAME}")
127
128 if(RMM_HTML_COV_REPORT)
129 set(HTML_REPORT --html-details ${COVERAGE_OUTPUT}.html)
130 endif()
131
132 #
133 # Rules for coverage report generation
134 #
135 add_custom_target(run-coverage
136 COMMAND ${CMAKE_COMMAND} -E make_directory "${COVERAGE_DIRECTORY}"
137 COMMAND ${GCOVR_EXECUTABLE}
138 ${GCOVR_EXE_OPTION}
139 --exclude "'((.+)ext(.+))|((.+)CMakeFiles(.+)\..)|((.+)\.cpp)|((.+)test(.+))'"
140 -r ${CMAKE_SOURCE_DIR}
141 -x ${COVERAGE_OUTPUT}.xml
142 ${HTML_REPORT}
143 ${CMAKE_BINARY_DIR})
Javier Almansa Sobrino576071e2022-09-09 16:01:17 +0100144endif() # RMM_COVERAGE