How to do code coverage in cmake
Asked Answered
V

1

29

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 ?

Vivien answered 10/6, 2015 at 17:16 Comment(6)
From your decription I assume you have already read Detailed guide on using gcov with CMake/CDash?. But did you see e.g. github.com/stepcode/stepcode/blob/master/lcov.cmake ? CTest knows/can extract the list of test in your CMake's binary output directory and with its script mode ctest -S ... you can automate the whole build, test and collect coverage data process.Durkheim
Also useful could be How to run ctest after building my project with cmakeDurkheim
@Durkheim I don't see a ctest_coverage call in the lcov.cmake example? Also, are you saying you can perform the coverage analysis without a script (-S) at all? Can you point to an example of how to do that? I'm interested in coverage analysis of all of the test targets in aggregate.Thither
Maybe this module which we are using is useful for you: code.cor-lab.de/projects/rsc/repository/entry/cmake/Modules/…. It uses lcov and gcovr to generate the reports. It still doesn't help to automatically collect the test targets, but maybe it saves some time to write your coverage logic.Sapless
This is now answered here: #13116988Salo
Does this answer your question? Detailed guide on using gcov with CMake/CDash?Seato
C
0

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.

Croteau answered 1/6 at 22:27 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.