blob: dd1e6ce9e867c9e9d73013dc26aad27d01bb0be0 [file] [log] [blame]
Imre Kise6bf9e62020-01-20 11:34:24 +01001#
2# Copyright (c) 2020, Arm Limited. All rights reserved.
3#
4# SPDX-License-Identifier: BSD-3-Clause
5#
6
7include_guard(DIRECTORY)
8
9# Checking GCC
10if (NOT CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
11 message(FATAL_ERROR "Coverage measurement is only supported when using GCC")
12endif()
13
14# Checking lcov
15find_program(LCOV_COMMAND "lcov")
16if (NOT LCOV_COMMAND)
17 message(FATAL_ERROR "Please install lcov")
18endif()
19
20# Checking c-picker-coverage-mapper
21find_program(CPICKER_COVERAGE_MAPPER_COMMAND "c-picker-coverage-mapper")
22if (NOT CPICKER_COVERAGE_MAPPER_COMMAND)
23 message(FATAL_ERROR "Please install c-picker-coverage-mapper using pip (part of c-picker)")
24endif()
25
26# Checking genhtml
27find_program(GENHTML_COMMAND "genhtml")
28if (NOT GENHTML_COMMAND)
29 message(FATAL_ERROR "Please install genhtml with genhtml (part of lcov)")
30endif()
31
32# Including this file enables code coverage measurement by adding the necessary compiler and
33# linker flags.
34set(CMAKE_C_FLAGS "-g -O0 -fprofile-arcs -ftest-coverage")
35set(CMAKE_CXX_FLAGS "-g -O0 -fprofile-arcs -ftest-coverage -fno-exceptions")
36set(CMAKE_EXE_LINKER_FLAGS "-fprofile-arcs -ftest-coverage")
37
38# Adding custom targets
39add_custom_target(coverage)
40add_custom_target(coverage_report)
41
Imre Kisc73346f2020-02-07 15:26:27 +010042# Adds a file to the dependency list of the target by inserting an accessory
43# custom target. The name of the custom target is properly escaped.
44function(add_coverage_dependency)
45 set(_OPTIONS_ARGS)
46 set(_ONE_VALUE_ARGS TARGET DEPENDS)
47 set(_MULTI_VALUE_ARGS)
48 cmake_parse_arguments(_MY_PARAMS "${_OPTIONS_ARGS}" "${_ONE_VALUE_ARGS}" "${_MULTI_VALUE_ARGS}" ${ARGN})
49
50 set(TARGET ${_MY_PARAMS_TARGET})
51 set(DEPENDS ${_MY_PARAMS_DEPENDS})
52
53 string(REGEX REPLACE "\\/" "_" CUSTOM_TARGET_SUFFIX ${DEPENDS})
54
55 add_custom_target(${TARGET}_target_${CUSTOM_TARGET_SUFFIX} DEPENDS ${DEPENDS})
56 add_dependencies(${TARGET} ${TARGET}_target_${CUSTOM_TARGET_SUFFIX})
57endfunction()
58
Imre Kise6bf9e62020-01-20 11:34:24 +010059# Generates LCOV coverage info file by processing the .gcda and .gcno files.
60# The function also maps coverage of the c-picker generated files to the original source lines
Imre Kise6bf9e62020-01-20 11:34:24 +010061function(coverage_generate)
62 set(_OPTIONS_ARGS)
Imre Kis335834e2020-02-07 15:44:38 +010063 set(_ONE_VALUE_ARGS NAME SOURCE_DIR BINARY_DIR CPICKER_MAPPING_PATH OUTPUT_FILE)
Imre Kise6bf9e62020-01-20 11:34:24 +010064 set(_MULTI_VALUE_ARGS)
65 cmake_parse_arguments(_MY_PARAMS "${_OPTIONS_ARGS}" "${_ONE_VALUE_ARGS}" "${_MULTI_VALUE_ARGS}" ${ARGN})
66
67 set(TEST_NAME ${_MY_PARAMS_NAME})
Imre Kis335834e2020-02-07 15:44:38 +010068 set(SOURCE_DIR ${_MY_PARAMS_SOURCE_DIR})
69 set(BINARY_DIR ${_MY_PARAMS_BINARY_DIR})
70 set(CPICKER_MAPPING_PATH ${_MY_PARAMS_CPICKER_MAPPING_PATH})
Imre Kisc73346f2020-02-07 15:26:27 +010071 set(TEMP_FILE ${_MY_PARAMS_OUTPUT_FILE}_temp)
Imre Kise6bf9e62020-01-20 11:34:24 +010072 set(OUTPUT_FILE ${_MY_PARAMS_OUTPUT_FILE})
73
Imre Kise6bf9e62020-01-20 11:34:24 +010074 # Collecting information from .gcda and .gcno files into an lcov .info file
75 # Mapping c-picker generated files' coverage info to the original source lines
76 add_custom_command(
77 OUTPUT ${TEMP_FILE} ${OUTPUT_FILE}
78 COMMAND ${LCOV_COMMAND}
79 --capture
80 --test-name ${TEST_NAME}
Imre Kis335834e2020-02-07 15:44:38 +010081 --directory ${BINARY_DIR}
82 --base-directory ${SOURCE_DIR}
Imre Kise6bf9e62020-01-20 11:34:24 +010083 --output-file ${TEMP_FILE}
84 COMMAND ${CPICKER_COVERAGE_MAPPER_COMMAND}
85 --input ${TEMP_FILE}
86 --output ${OUTPUT_FILE}
Imre Kis335834e2020-02-07 15:44:38 +010087 --mapping-path ${CPICKER_MAPPING_PATH}
Imre Kise6bf9e62020-01-20 11:34:24 +010088 )
Imre Kisc73346f2020-02-07 15:26:27 +010089
90 add_coverage_dependency(
91 TARGET coverage
92 DEPENDS ${OUTPUT_FILE}
93 )
Imre Kise6bf9e62020-01-20 11:34:24 +010094endfunction()
95
96# Filters coverage info of files from the matching directory
97function(coverage_filter)
98 set(_OPTIONS_ARGS)
99 set(_ONE_VALUE_ARGS INPUT_FILE OUTPUT_FILE INCLUDE_DIRECTORY)
100 set(_MULTI_VALUE_ARGS)
101 cmake_parse_arguments(_MY_PARAMS "${_OPTIONS_ARGS}" "${_ONE_VALUE_ARGS}" "${_MULTI_VALUE_ARGS}" ${ARGN})
102
Imre Kisc73346f2020-02-07 15:26:27 +0100103 set(INPUT_FILE ${_MY_PARAMS_INPUT_FILE})
104 set(OUTPUT_FILE ${_MY_PARAMS_OUTPUT_FILE})
105 set(INCLUDE_DIRECTORY ${_MY_PARAMS_INCLUDE_DIRECTORY})
106
Imre Kise6bf9e62020-01-20 11:34:24 +0100107 # The pattern must be an absolute path ending with an asterisk
Imre Kisc73346f2020-02-07 15:26:27 +0100108 get_filename_component(INCLUDE_DIRECTORY_ABSPATH "${INCLUDE_DIRECTORY}" ABSOLUTE)
Imre Kise6bf9e62020-01-20 11:34:24 +0100109 set(INCLUDE_DIRECTORY_ABSPATH "${INCLUDE_DIRECTORY_ABSPATH}/*")
110
111 add_custom_command(
Imre Kisc73346f2020-02-07 15:26:27 +0100112 OUTPUT ${OUTPUT_FILE}
Imre Kise6bf9e62020-01-20 11:34:24 +0100113 COMMAND ${LCOV_COMMAND}
Imre Kisc73346f2020-02-07 15:26:27 +0100114 --extract ${INPUT_FILE} \"${INCLUDE_DIRECTORY_ABSPATH}\"
115 --output-file ${OUTPUT_FILE}
116 DEPENDS ${INPUT_FILE}
Imre Kise6bf9e62020-01-20 11:34:24 +0100117 )
118
Imre Kisc73346f2020-02-07 15:26:27 +0100119 add_coverage_dependency(
120 TARGET coverage
121 DEPENDS ${OUTPUT_FILE}
122 )
Imre Kise6bf9e62020-01-20 11:34:24 +0100123endfunction()
124
125# Generated an HTML report from the LCOV info file
126function(coverage_generate_report)
127 set(_OPTIONS_ARGS)
128 set(_ONE_VALUE_ARGS INPUT_FILE OUTPUT_DIRECTORY)
129 set(_MULTI_VALUE_ARGS)
130 cmake_parse_arguments(_MY_PARAMS "${_OPTIONS_ARGS}" "${_ONE_VALUE_ARGS}" "${_MULTI_VALUE_ARGS}" ${ARGN})
131
Imre Kisc73346f2020-02-07 15:26:27 +0100132 set(INPUT_FILE ${_MY_PARAMS_INPUT_FILE})
133 set(OUTPUT_DIRECTORY ${_MY_PARAMS_OUTPUT_DIRECTORY})
134
Imre Kise6bf9e62020-01-20 11:34:24 +0100135 add_custom_command(
Imre Kisc73346f2020-02-07 15:26:27 +0100136 OUTPUT ${OUTPUT_DIRECTORY}
137 COMMAND genhtml ${INPUT_FILE}
Imre Kise6bf9e62020-01-20 11:34:24 +0100138 --show-details
Imre Kisc73346f2020-02-07 15:26:27 +0100139 --output-directory ${OUTPUT_DIRECTORY}
140 DEPENDS ${INPUT_FILE}
Imre Kise6bf9e62020-01-20 11:34:24 +0100141 )
142
Imre Kisc73346f2020-02-07 15:26:27 +0100143 add_coverage_dependency(
144 TARGET coverage_report
145 DEPENDS ${OUTPUT_DIRECTORY}
146 )
Imre Kise6bf9e62020-01-20 11:34:24 +0100147endfunction()