Skip to content

Commit c5ea9cc

Browse files
committed
Add coverage support (minimal)
1 parent 4cebccb commit c5ea9cc

File tree

7 files changed

+125
-5
lines changed

7 files changed

+125
-5
lines changed

CMakeLists.txt

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,19 +21,29 @@ if(CMAKE_CONFIGURATION_TYPES)
2121
set(CMAKE_CONFIGURATION_TYPES "${CMAKE_CONFIGURATION_TYPES}" CACHE STRING "" FORCE)
2222
endif()
2323

24+
# Add custom "Coverage" build type
25+
if(CMAKE_CONFIGURATION_TYPES)
26+
list(APPEND CMAKE_CONFIGURATION_TYPES Coverage)
27+
list(REMOVE_DUPLICATES CMAKE_CONFIGURATION_TYPES)
28+
set(CMAKE_CONFIGURATION_TYPES "${CMAKE_CONFIGURATION_TYPES}" CACHE STRING "" FORCE)
29+
endif()
30+
2431
# Load cmake modules
2532
list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
2633

27-
# Warnings, sanitizers, Link Time Optimization (LTO)
34+
# Warnings, Sanitizers, Link Time Optimization (LTO)
2835
include(options/LTO)
2936
include(options/Warnings)
3037
include(options/Sanitizers)
3138

39+
# Coverage
40+
include(tools/Coverage)
41+
3242
# === Libraries ===
3343
add_subdirectory(src) # modern_cpp_project::math
3444

3545
# === Application ===
36-
if(BUILD_APP)
46+
if(BUILD_APP AND NOT CMAKE_BUILD_TYPE STREQUAL "Coverage")
3747
add_subdirectory(app) # modern_cpp_project_app
3848
endif()
3949

@@ -43,8 +53,10 @@ if(ENABLE_TESTING)
4353
add_subdirectory(tests)
4454
endif()
4555

46-
if(ENABLE_BENCHMARKS AND NOT CMAKE_BUILD_TYPE STREQUAL "Sanitize")
47-
add_subdirectory(benchmarks)
56+
if(ENABLE_BENCHMARKS)
57+
if (NOT CMAKE_BUILD_TYPE STREQUAL "Coverage" AND NOT CMAKE_BUILD_TYPE STREQUAL "Sanitize")
58+
add_subdirectory(benchmarks)
59+
endif()
4860
endif()
4961

5062
# === Docs ===

CMakePresets.json

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,22 @@
4343
"name": "gcc-RelWithDebInfo-lto",
4444
"inherits": "gcc-RelWithDebInfo",
4545
"cacheVariables": {
46+
"CMAKE_C_COMPILER": "gcc",
47+
"CMAKE_CXX_COMPILER": "g++",
4648
"CMAKE_INTERPROCEDURAL_OPTIMIZATION": "TRUE"
4749
},
4850
"description": "GCC RelWithDebInfo build with Link Time Optimization (LTO)"
4951
},
52+
{
53+
"name": "gcc-Coverage",
54+
"inherits": "base",
55+
"cacheVariables": {
56+
"CMAKE_C_COMPILER": "gcc",
57+
"CMAKE_CXX_COMPILER": "g++",
58+
"CMAKE_BUILD_TYPE": "Coverage"
59+
},
60+
"description": "GCC build with coverage"
61+
},
5062
{
5163
"name": "clang-RelWithDebInfo",
5264
"inherits": "base",
@@ -71,9 +83,21 @@
7183
"name": "clang-RelWithDebInfo-lto",
7284
"inherits": "clang-RelWithDebInfo",
7385
"cacheVariables": {
86+
"CMAKE_C_COMPILER": "clang",
87+
"CMAKE_CXX_COMPILER": "clang++",
7488
"CMAKE_INTERPROCEDURAL_OPTIMIZATION": "TRUE"
7589
},
7690
"description": "Clang RelWithDebInfo build with Link Time Optimization (LTO)"
91+
},
92+
{
93+
"name": "clang-Coverage",
94+
"inherits": "base",
95+
"cacheVariables": {
96+
"CMAKE_C_COMPILER": "clang",
97+
"CMAKE_CXX_COMPILER": "clang++",
98+
"CMAKE_BUILD_TYPE": "Coverage"
99+
},
100+
"description": "Clang build with coverage"
77101
}
78102
],
79103
"buildPresets": [
@@ -103,6 +127,12 @@
103127
"configurePreset": "gcc-RelWithDebInfo-lto",
104128
"description": "Build using GCC + LTO (RelWithDebInfo)"
105129
},
130+
{
131+
"name": "gcc-Coverage",
132+
"inherits": "build-base",
133+
"configurePreset": "gcc-Coverage",
134+
"description": "Build using GCC + Coverage"
135+
},
106136
{
107137
"name": "clang-RelWithDebInfo",
108138
"inherits": "build-base",
@@ -120,6 +150,12 @@
120150
"inherits": "build-base",
121151
"configurePreset": "clang-RelWithDebInfo-lto",
122152
"description": "Build using Clang + LTO (RelWithDebInfo)"
153+
},
154+
{
155+
"name": "clang-Coverage",
156+
"inherits": "build-base",
157+
"configurePreset": "clang-Coverage",
158+
"description": "Build using Clang + Coverage"
123159
}
124160
],
125161
"testPresets": [
@@ -153,6 +189,12 @@
153189
"configurePreset": "gcc-RelWithDebInfo-lto",
154190
"description": "Test using GCC + LTO (RelWithDebInfo)"
155191
},
192+
{
193+
"name": "gcc-Coverage",
194+
"inherits": "test-base",
195+
"configurePreset": "gcc-Coverage",
196+
"description": "Test using GCC + Coverage"
197+
},
156198
{
157199
"name": "clang-RelWithDebInfo",
158200
"inherits": "test-base",
@@ -170,6 +212,12 @@
170212
"inherits": "test-base",
171213
"configurePreset": "clang-RelWithDebInfo-lto",
172214
"description": "Test using Clang + LTO (RelWithDebInfo)"
215+
},
216+
{
217+
"name": "clang-Coverage",
218+
"inherits": "test-base",
219+
"configurePreset": "clang-Coverage",
220+
"description": "Test using Clang + Coverage"
173221
}
174222
]
175-
}
223+
}

cmake/tools/Coverage.cmake

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
function(enable_coverage target)
2+
if(CMAKE_BUILD_TYPE STREQUAL "Coverage")
3+
target_compile_options(${target} PRIVATE --coverage -O0 -g)
4+
target_link_options(${target} PRIVATE --coverage)
5+
message(STATUS "Coverage enabled for target ${target}")
6+
endif()
7+
endfunction()
8+
9+
find_program(LCOV_EXECUTABLE lcov)
10+
find_program(GENHTML_EXECUTABLE genhtml)
11+
12+
if(LCOV_EXECUTABLE)
13+
set(COVERAGE_INFO "${CMAKE_BINARY_DIR}/coverage.info")
14+
set(COVERAGE_CLEANED "${CMAKE_BINARY_DIR}/coverage.info.cleaned")
15+
set(COVERAGE_REPORT_DIR "${CMAKE_BINARY_DIR}/coverage-report")
16+
17+
add_custom_target(coverage
18+
COMMAND ${LCOV_EXECUTABLE} --directory . --capture --output-file ${COVERAGE_INFO} --ignore-errors mismatch
19+
COMMAND ${LCOV_EXECUTABLE} --remove ${COVERAGE_INFO}
20+
/usr/* ${CMAKE_BINARY_DIR}/*
21+
--output-file ${COVERAGE_CLEANED}
22+
COMMAND ${GENHTML_EXECUTABLE} ${COVERAGE_CLEANED}
23+
--output-directory ${COVERAGE_REPORT_DIR}
24+
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
25+
COMMENT "Generating code coverage report with lcov + genhtml"
26+
VERBATIM
27+
)
28+
29+
message(STATUS "Coverage support enabled (run: cmake --build --target coverage)")
30+
endif()
31+
32+
if(GENHTML_EXECUTABLE)
33+
add_custom_target(genhtml
34+
COMMAND ${GENHTML_EXECUTABLE}
35+
${CMAKE_BINARY_DIR}/coverage.info.cleaned
36+
--output-directory ${CMAKE_BINARY_DIR}/coverage-report
37+
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
38+
COMMENT "Generating HTML coverage report with genhtml"
39+
VERBATIM
40+
)
41+
else()
42+
message(STATUS "genhtml not found — 'genhtml' target will not be available.")
43+
endif()

include/math/arithmetic.hpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,15 @@ int add(int left, int right);
2727
*/
2828
int subtract(int left, int right);
2929

30+
/**
31+
* @brief Multiplies two integers.
32+
*
33+
* @param left First integer.
34+
* @param right Second integer.
35+
* @return Multiplication of left and right.
36+
*/
37+
int multiply(int left, int right);
38+
3039
} // namespace math
3140

3241
#endif

src/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ target_include_directories(math
1010
$<INSTALL_INTERFACE:include>
1111
)
1212

13+
enable_coverage(math)
14+
1315
enable_lto(math)
1416
enable_sanitizers(math)
1517
enable_strict_warnings(math)

src/arithmetic.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,9 @@ int subtract(int left, int right)
1313
return left - right;
1414
}
1515

16+
int multiply(int left, int right)
17+
{
18+
return left * right;
19+
}
20+
1621
} // namespace math

tests/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ target_link_libraries(unit_tests
2525
)
2626

2727
enable_warnings(unit_tests)
28+
enable_coverage(unit_tests)
2829
enable_sanitizers(unit_tests)
2930

3031
# Automatically discover and register all test cases

0 commit comments

Comments
 (0)