Reputation: 2650
I want to use code coverage tools(lcov) in my cmake project. I read the example here https://github.com/bilke/cmake-modules/blob/master/CodeCoverage.cmake The tests are added in my project using the 'add_test()' cmake function.
I want to create a custom target, something called 'test_coverage', that when invoked for execution should run all the tests, collect their coverage data and generate the html(using genhtml) in a directory 'code_coverage'.
Is there a way I could get the list of all the tests in my project and their directory paths, so that in the custom target 'test_coverage' I could execute each test individually and collect its coverage data ?
Upvotes: 29
Views: 31956
Reputation: 196
I am not a cmake expert and when I had similar problem in my small project I did not want to deal with CDash it just looked like a too big effort for my case. So I came up with easier solution - invoke lcov
and genhtml
from cmake.
In case if you use add_test
it is not that easy, since it does not support multiple commands and chaining command. But we can chain all the calls we need to generate coverage in a shell script (as suggested here. Simple example will look like this:
enable_testing()
add_library(coverage_options INTERFACE)
enable_coverage(coverage_options)
add_executable(example_test ${UNITTEST_FILES})
target_link_libraries(example_test PRIVATE coverage_options)
FILE(WRITE ${CMAKE_CURRENT_BINARY_DIR}/main.sh
"${CMAKE_CURRENT_BINARY_DIR}/example_test && lcov -q --capture --directory . --output-file=all_coverage.info && lcov -q --extract all_coverage.info \"${CMAKE_SOURCE_DIR}/*\" --output-file=coverage.info && rm all_coverage.info && genhtml coverage.info --output-directory=coverage_html")
add_test(
NAME example_test
COMMAND sh ${CMAKE_CURRENT_BINARY_DIR}/main.sh
)
enable_coverage
is a function from here. Namely
function(enable_coverage _project_name)
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID MATCHES ".*Clang")
target_compile_options(${_project_name} INTERFACE --coverage -O0 -g)
target_link_libraries(${_project_name} INTERFACE --coverage)
endif()
endfunction()
The solution is not ideal but I feel that it is easier to plug this in small projects than deal with CDash.
Upvotes: 0