Skip to content

Commit e7a89c8

Browse files
committed
Enable code coverage.
1 parent 4690c6d commit e7a89c8

8 files changed

+857
-22
lines changed

.codecov.yml

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
coverage:
2+
precision: 2
3+
round: nearest
4+
range: "0...100"
5+
ignore:
6+
- "vendor/**/*"

.github/workflows/build-and-test.yml

+11-11
Original file line numberDiff line numberDiff line change
@@ -85,14 +85,14 @@ jobs:
8585
- name: Test
8686
run: ctest -C ${{ matrix.config }} --output-on-failure
8787
working-directory: build
88-
# - name: Code Coverage Analysis
89-
# if: "matrix.coverage"
90-
# run: make gcov
91-
# working-directory: build
92-
# - name: Upload Code Coverage Report
93-
# if: "matrix.coverage"
94-
# uses: codecov/codecov-action@v3
95-
# with:
96-
# flags: integration
97-
# functionalities: "gcov"
98-
# move_coverage_to_trash: true
88+
- name: Code Coverage Analysis
89+
if: "matrix.coverage"
90+
run: make gcov
91+
working-directory: build
92+
- name: Upload Code Coverage Report
93+
if: "matrix.coverage"
94+
uses: codecov/codecov-action@v3
95+
with:
96+
flags: integration
97+
functionalities: "gcov"
98+
move_coverage_to_trash: true

CMakeLists.txt

+8-8
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ set(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake")
1919
include(CMakeDependentOption)
2020

2121
cmake_dependent_option(${PROJECT_NAME}_BUILD_TESTING "Build ${PROJECT_NAME} testing targets" ON "${PROJECT_NAME}_IS_TOP_LEVEL" OFF)
22-
#option(${PROJECT_NAME}_COVERAGE "Add ${PROJECT_NAME} coverage reports" OFF)
22+
option(${PROJECT_NAME}_COVERAGE "Add ${PROJECT_NAME} coverage reports" OFF)
2323
#cmake_dependent_option(${PROJECT_NAME}_BUILD_EXAMPLES "Build ${PROJECT_NAME} examples" ON "${PROJECT_NAME}_IS_TOP_LEVEL" OFF)
2424
cmake_dependent_option(${PROJECT_NAME}_WARNINGS_AS_ERRORS "Treat warnings in ${PROJECT_NAME} as errors" ON "${PROJECT_NAME}_IS_TOP_LEVEL" OFF)
2525

@@ -32,10 +32,10 @@ include(compiler-flags)
3232
# Set up testing/coverage
3333
if (${PROJECT_NAME}_BUILD_TESTING)
3434
enable_testing()
35-
# if (${PROJECT_NAME}_COVERAGE)
36-
# set(ENABLE_COVERAGE ON CACHE BOOL "" FORCE)
37-
# find_package(codecov)
38-
# endif ()
35+
if (${PROJECT_NAME}_COVERAGE)
36+
set(ENABLE_COVERAGE ON CACHE BOOL " " FORCE)
37+
find_package(codecov)
38+
endif ()
3939
endif ()
4040

4141
if (HPWHSIM_ABRIDGED)
@@ -47,7 +47,7 @@ add_subdirectory(src)
4747

4848
if (${PROJECT_NAME}_BUILD_TESTING)
4949
add_subdirectory(test)
50-
# if (${PROJECT_NAME}_COVERAGE)
51-
# coverage_evaluate()
52-
# endif ()
50+
if (${PROJECT_NAME}_COVERAGE)
51+
coverage_evaluate()
52+
endif ()
5353
endif ()

cmake/FindGcov.cmake

+158
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
# This file is part of CMake-codecov.
2+
#
3+
# Copyright (c)
4+
# 2015-2017 RWTH Aachen University, Federal Republic of Germany
5+
#
6+
# See the LICENSE file in the package base directory for details
7+
#
8+
# Written by Alexander Haase, [email protected]
9+
#
10+
11+
12+
# include required Modules
13+
include(FindPackageHandleStandardArgs)
14+
15+
16+
# Search for gcov binary.
17+
set(CMAKE_REQUIRED_QUIET_SAVE ${CMAKE_REQUIRED_QUIET})
18+
set(CMAKE_REQUIRED_QUIET ${codecov_FIND_QUIETLY})
19+
20+
get_property(ENABLED_LANGUAGES GLOBAL PROPERTY ENABLED_LANGUAGES)
21+
foreach (LANG ${ENABLED_LANGUAGES})
22+
# Gcov evaluation is dependent on the used compiler. Check gcov support for
23+
# each compiler that is used. If gcov binary was already found for this
24+
# compiler, do not try to find it again.
25+
if (NOT GCOV_${CMAKE_${LANG}_COMPILER_ID}_BIN)
26+
get_filename_component(COMPILER_PATH "${CMAKE_${LANG}_COMPILER}" PATH)
27+
28+
if ("${CMAKE_${LANG}_COMPILER_ID}" STREQUAL "GNU")
29+
# Some distributions like OSX (homebrew) ship gcov with the compiler
30+
# version appended as gcov-x. To find this binary we'll build the
31+
# suggested binary name with the compiler version.
32+
string(REGEX MATCH "^[0-9]+" GCC_VERSION
33+
"${CMAKE_${LANG}_COMPILER_VERSION}")
34+
35+
find_program(GCOV_BIN NAMES gcov-${GCC_VERSION} gcov
36+
HINTS ${COMPILER_PATH})
37+
38+
elseif ("${CMAKE_${LANG}_COMPILER_ID}" MATCHES "^(Apple)?Clang$")
39+
# Some distributions like Debian ship llvm-cov with the compiler
40+
# version appended as llvm-cov-x.y. To find this binary we'll build
41+
# the suggested binary name with the compiler version.
42+
string(REGEX MATCH "^[0-9]+.[0-9]+" LLVM_VERSION
43+
"${CMAKE_${LANG}_COMPILER_VERSION}")
44+
45+
# llvm-cov prior version 3.5 seems to be not working with coverage
46+
# evaluation tools, but these versions are compatible with the gcc
47+
# gcov tool.
48+
if(LLVM_VERSION VERSION_GREATER 3.4)
49+
find_program(LLVM_COV_BIN NAMES "llvm-cov-${LLVM_VERSION}"
50+
"llvm-cov" HINTS ${COMPILER_PATH})
51+
mark_as_advanced(LLVM_COV_BIN)
52+
53+
if (LLVM_COV_BIN)
54+
find_program(LLVM_COV_WRAPPER "llvm-cov-wrapper" PATHS
55+
${CMAKE_MODULE_PATH})
56+
if (LLVM_COV_WRAPPER)
57+
set(GCOV_BIN "${LLVM_COV_WRAPPER}" CACHE FILEPATH "")
58+
59+
# set additional parameters
60+
set(GCOV_${CMAKE_${LANG}_COMPILER_ID}_ENV
61+
"LLVM_COV_BIN=${LLVM_COV_BIN}" CACHE STRING
62+
"Environment variables for llvm-cov-wrapper.")
63+
mark_as_advanced(GCOV_${CMAKE_${LANG}_COMPILER_ID}_ENV)
64+
endif ()
65+
endif ()
66+
endif ()
67+
68+
if (NOT GCOV_BIN)
69+
# Fall back to gcov binary if llvm-cov was not found or is
70+
# incompatible. This is the default on OSX, but may crash on
71+
# recent Linux versions.
72+
find_program(GCOV_BIN gcov HINTS ${COMPILER_PATH})
73+
endif ()
74+
endif ()
75+
76+
77+
if (GCOV_BIN)
78+
set(GCOV_${CMAKE_${LANG}_COMPILER_ID}_BIN "${GCOV_BIN}" CACHE STRING
79+
"${LANG} gcov binary.")
80+
81+
if (NOT CMAKE_REQUIRED_QUIET)
82+
message("-- Found gcov evaluation for "
83+
"${CMAKE_${LANG}_COMPILER_ID}: ${GCOV_BIN}")
84+
endif()
85+
86+
unset(GCOV_BIN CACHE)
87+
endif ()
88+
endif ()
89+
endforeach ()
90+
91+
92+
93+
94+
# Add a new global target for all gcov targets. This target could be used to
95+
# generate the gcov files for the whole project instead of calling <TARGET>-gcov
96+
# for each target.
97+
if (NOT TARGET gcov)
98+
add_custom_target(gcov)
99+
endif (NOT TARGET gcov)
100+
101+
102+
103+
# This function will add gcov evaluation for target <TNAME>. Only sources of
104+
# this target will be evaluated and no dependencies will be added. It will call
105+
# Gcov on any source file of <TNAME> once and store the gcov file in the same
106+
# directory.
107+
function (add_gcov_target TNAME)
108+
get_target_property(TBIN_DIR ${TNAME} BINARY_DIR)
109+
set(TDIR ${TBIN_DIR}/CMakeFiles/${TNAME}.dir)
110+
111+
# We don't have to check, if the target has support for coverage, thus this
112+
# will be checked by add_coverage_target in Findcoverage.cmake. Instead we
113+
# have to determine which gcov binary to use.
114+
get_target_property(TSOURCES ${TNAME} SOURCES)
115+
set(SOURCES "")
116+
set(TCOMPILER "")
117+
foreach (FILE ${TSOURCES})
118+
codecov_path_of_source(${FILE} FILE)
119+
if (NOT "${FILE}" STREQUAL "")
120+
codecov_lang_of_source(${FILE} LANG)
121+
if (NOT "${LANG}" STREQUAL "")
122+
list(APPEND SOURCES "${FILE}")
123+
set(TCOMPILER ${CMAKE_${LANG}_COMPILER_ID})
124+
endif ()
125+
endif ()
126+
endforeach ()
127+
128+
# If no gcov binary was found, coverage data can't be evaluated.
129+
if (NOT GCOV_${TCOMPILER}_BIN)
130+
message(WARNING "No coverage evaluation binary found for ${TCOMPILER}.")
131+
return()
132+
endif ()
133+
134+
set(GCOV_BIN "${GCOV_${TCOMPILER}_BIN}")
135+
set(GCOV_ENV "${GCOV_${TCOMPILER}_ENV}")
136+
137+
138+
set(BUFFER "")
139+
foreach(FILE ${SOURCES})
140+
get_filename_component(FILE_PATH "${TDIR}/${FILE}" PATH)
141+
142+
# call gcov
143+
add_custom_command(OUTPUT ${TDIR}/${FILE}.gcov
144+
COMMAND ${GCOV_ENV} ${GCOV_BIN} ${TDIR}/${FILE}.gcno > /dev/null
145+
DEPENDS ${TNAME} ${TDIR}/${FILE}.gcno
146+
WORKING_DIRECTORY ${FILE_PATH}
147+
)
148+
149+
list(APPEND BUFFER ${TDIR}/${FILE}.gcov)
150+
endforeach()
151+
152+
153+
# add target for gcov evaluation of <TNAME>
154+
add_custom_target(${TNAME}-gcov DEPENDS ${BUFFER})
155+
156+
# add evaluation target to the global gcov target.
157+
add_dependencies(gcov ${TNAME}-gcov)
158+
endfunction (add_gcov_target)

0 commit comments

Comments
 (0)