Javier Almansa Sobrino | 576071e | 2022-09-09 16:01:17 +0100 | [diff] [blame] | 1 | # |
| 2 | # SPDX-License-Identifier: BSD-3-Clause |
| 3 | # SPDX-FileCopyrightText: Copyright TF-RMM Contributors. |
| 4 | # |
| 5 | |
| 6 | arm_config_option( |
| 7 | NAME RMM_COVERAGE |
| 8 | HELP "Enable coverage tests" |
| 9 | TYPE BOOL |
| 10 | DEFAULT "OFF") |
| 11 | |
| 12 | arm_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 | |
| 19 | arm_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 | |
| 27 | macro(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}") |
| 46 | endmacro(check_and_prepare_c_coverage_flags) |
| 47 | |
| 48 | macro(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}") |
| 65 | endmacro(check_and_prepare_cxx_coverage_flags) |
| 66 | |
| 67 | if(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 Sobrino | 576071e | 2022-09-09 16:01:17 +0100 | [diff] [blame] | 144 | endif() # RMM_COVERAGE |