The following script creates a library with a function int add(int a, int b)
and a test application that links to the library and calls add
CMakeLists.txt
cmake_minimum_required(VERSION 3.25)
project(CoverageTest)
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/lib.cpp" "int add(int a, int b) { return a + b; }")
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/test.cpp" "extern int add(int, int); int main() { return add(1, 2) == 3 ? 0 : 1; }")
add_library(mylib STATIC ${CMAKE_CURRENT_BINARY_DIR}/lib.cpp)
add_executable(testapp ${CMAKE_CURRENT_BINARY_DIR}/test.cpp)
# All targets requireing coverage analysis need the following compile options
target_compile_options(testapp PRIVATE -g -fprofile-arcs -ftest-coverage)
target_compile_options(mylib PRIVATE -g -fprofile-arcs -ftest-coverage)
# And we need to link to libgcov.a
target_link_libraries(testapp mylib gcov)
# Tell ctest what the test application is
add_test(NAME testLib
COMMAND testapp
)
# This include is needed to avoid the `Binary directory is not set. No coverage checking will be performed.` error when running ctest
include(CTest)
enable_testing()
Configure build and run:
cmake -B build
cmake --build build
ctest --test-dir build -T Test -T Coverage
This will output:
[~/projects/experiments/coverage]$ cmake -B build
-- The C compiler identification is GNU 11.1.0
-- The CXX compiler identification is GNU 11.1.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /usr/bin/cc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: ~/projects/experiments/coverage/build
[~/projects/experiments/coverage]$ cmake --build build
[ 25%] Building CXX object CMakeFiles/mylib.dir/lib.cpp.o
[ 50%] Linking CXX static library libmylib.a
[ 50%] Built target mylib
[ 75%] Building CXX object CMakeFiles/testapp.dir/test.cpp.o
[100%] Linking CXX executable testapp
[100%] Built target testapp
[~/projects/experiments/coverage]$ ctest --test-dir build -T Test -T Coverage
Internal ctest changing into directory: ~/projects/experiments/coverage/build
Site: THS-LT-12
Build name: Linux-c++
Create new tag: 20230608-1145 - Experimental
Test project ~/projects/experiments/coverage/build
Start 1: testLib
1/1 Test #1: testLib .......................... Passed 0.02 sec
100% tests passed, 0 tests failed out of 1
Total Test time (real) = 0.06 sec
Performing coverage
Processing coverage (each . represents one file):
..
Accumulating results (each . represents one file):
..
Covered LOC: 2
Not covered LOC: 0
Total LOC: 2
Percentage Coverage: 100.00%