blob: 0c93f8530c1185115b3585f420c52b342890bcdc [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
61# Global dependencies:
62# CPICKER_CACHE_PATH: root directory of the c-picker generated files
63function(coverage_generate)
64 set(_OPTIONS_ARGS)
65 set(_ONE_VALUE_ARGS NAME OUTPUT_FILE)
66 set(_MULTI_VALUE_ARGS)
67 cmake_parse_arguments(_MY_PARAMS "${_OPTIONS_ARGS}" "${_ONE_VALUE_ARGS}" "${_MULTI_VALUE_ARGS}" ${ARGN})
68
69 set(TEST_NAME ${_MY_PARAMS_NAME})
Imre Kisc73346f2020-02-07 15:26:27 +010070 set(TEMP_FILE ${_MY_PARAMS_OUTPUT_FILE}_temp)
Imre Kise6bf9e62020-01-20 11:34:24 +010071 set(OUTPUT_FILE ${_MY_PARAMS_OUTPUT_FILE})
72
Imre Kise6bf9e62020-01-20 11:34:24 +010073 # Collecting information from .gcda and .gcno files into an lcov .info file
74 # Mapping c-picker generated files' coverage info to the original source lines
75 add_custom_command(
76 OUTPUT ${TEMP_FILE} ${OUTPUT_FILE}
77 COMMAND ${LCOV_COMMAND}
78 --capture
79 --test-name ${TEST_NAME}
80 --directory ${CMAKE_CURRENT_BINARY_DIR}
81 --base-directory ${TF_A_PATH}
82 --output-file ${TEMP_FILE}
83 COMMAND ${CPICKER_COVERAGE_MAPPER_COMMAND}
84 --input ${TEMP_FILE}
85 --output ${OUTPUT_FILE}
86 --mapping-path ${CPICKER_CACHE_PATH}
Imre Kise6bf9e62020-01-20 11:34:24 +010087 )
Imre Kisc73346f2020-02-07 15:26:27 +010088
89 add_coverage_dependency(
90 TARGET coverage
91 DEPENDS ${OUTPUT_FILE}
92 )
Imre Kise6bf9e62020-01-20 11:34:24 +010093endfunction()
94
95# Filters coverage info of files from the matching directory
96function(coverage_filter)
97 set(_OPTIONS_ARGS)
98 set(_ONE_VALUE_ARGS INPUT_FILE OUTPUT_FILE INCLUDE_DIRECTORY)
99 set(_MULTI_VALUE_ARGS)
100 cmake_parse_arguments(_MY_PARAMS "${_OPTIONS_ARGS}" "${_ONE_VALUE_ARGS}" "${_MULTI_VALUE_ARGS}" ${ARGN})
101
Imre Kisc73346f2020-02-07 15:26:27 +0100102 set(INPUT_FILE ${_MY_PARAMS_INPUT_FILE})
103 set(OUTPUT_FILE ${_MY_PARAMS_OUTPUT_FILE})
104 set(INCLUDE_DIRECTORY ${_MY_PARAMS_INCLUDE_DIRECTORY})
105
Imre Kise6bf9e62020-01-20 11:34:24 +0100106 # The pattern must be an absolute path ending with an asterisk
Imre Kisc73346f2020-02-07 15:26:27 +0100107 get_filename_component(INCLUDE_DIRECTORY_ABSPATH "${INCLUDE_DIRECTORY}" ABSOLUTE)
Imre Kise6bf9e62020-01-20 11:34:24 +0100108 set(INCLUDE_DIRECTORY_ABSPATH "${INCLUDE_DIRECTORY_ABSPATH}/*")
109
110 add_custom_command(
Imre Kisc73346f2020-02-07 15:26:27 +0100111 OUTPUT ${OUTPUT_FILE}
Imre Kise6bf9e62020-01-20 11:34:24 +0100112 COMMAND ${LCOV_COMMAND}
Imre Kisc73346f2020-02-07 15:26:27 +0100113 --extract ${INPUT_FILE} \"${INCLUDE_DIRECTORY_ABSPATH}\"
114 --output-file ${OUTPUT_FILE}
115 DEPENDS ${INPUT_FILE}
Imre Kise6bf9e62020-01-20 11:34:24 +0100116 )
117
Imre Kisc73346f2020-02-07 15:26:27 +0100118 add_coverage_dependency(
119 TARGET coverage
120 DEPENDS ${OUTPUT_FILE}
121 )
Imre Kise6bf9e62020-01-20 11:34:24 +0100122endfunction()
123
124# Generated an HTML report from the LCOV info file
125function(coverage_generate_report)
126 set(_OPTIONS_ARGS)
127 set(_ONE_VALUE_ARGS INPUT_FILE OUTPUT_DIRECTORY)
128 set(_MULTI_VALUE_ARGS)
129 cmake_parse_arguments(_MY_PARAMS "${_OPTIONS_ARGS}" "${_ONE_VALUE_ARGS}" "${_MULTI_VALUE_ARGS}" ${ARGN})
130
Imre Kisc73346f2020-02-07 15:26:27 +0100131 set(INPUT_FILE ${_MY_PARAMS_INPUT_FILE})
132 set(OUTPUT_DIRECTORY ${_MY_PARAMS_OUTPUT_DIRECTORY})
133
Imre Kise6bf9e62020-01-20 11:34:24 +0100134 add_custom_command(
Imre Kisc73346f2020-02-07 15:26:27 +0100135 OUTPUT ${OUTPUT_DIRECTORY}
136 COMMAND genhtml ${INPUT_FILE}
Imre Kise6bf9e62020-01-20 11:34:24 +0100137 --show-details
Imre Kisc73346f2020-02-07 15:26:27 +0100138 --output-directory ${OUTPUT_DIRECTORY}
139 DEPENDS ${INPUT_FILE}
Imre Kise6bf9e62020-01-20 11:34:24 +0100140 )
141
Imre Kisc73346f2020-02-07 15:26:27 +0100142 add_coverage_dependency(
143 TARGET coverage_report
144 DEPENDS ${OUTPUT_DIRECTORY}
145 )
Imre Kise6bf9e62020-01-20 11:34:24 +0100146endfunction()