Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

gcov with CMake using a separate build directory

Tags:

c++

cmake

gcov

I'm struggling to get coverage information for gcov. No errors during compilation and linking, but when I run the executable, no coverage data is produced.

I'm using CMake with a separate build directory, passing flags to the compiler and linker in this way:

add_definitions(--coverage)
set(CMAKE_EXE_LINKER_FLAGS ${CMAKE_EXE_LINKER_FLAGS} " --coverage")

Does the executable expect the source code to be in a specific location? What do I have to add to my CMakeLists.txt to get things going?

Kind regards, Bjoern

like image 303
Bjoern Avatar asked May 22 '11 16:05

Bjoern


People also ask

How do I use CMake GCOV?

To perform an out-of-source build, run the following commands from the project root directory: mkdir build cd build cmake .. From the build directory you may build the project using make . The coverage files from gcov can be generated using make gcov .

Does CMake create build directory?

This will make a build directory ( -B ) if it does not exist, with the source directory defined as -S . CMake will configure and generate makefiles by default, as well as set all options to their default settings and cache them into a file called CMakeCache. txt , which will sit in the build directory.

What does GCOV do?

Gcov is a source code coverage analysis and statement-by-statement profiling tool. Gcov generates exact counts of the number of times each statement in a program is executed and annotates source code to add instrumentation. Gcov comes as a standard utility with the GNU Compiler Collection (GCC) suite.


4 Answers

CMake seems to put the code coverage (*.gcda, *.gcdo) files with the object files of your project. If your executable was named "tester" then they would appear in the following path

${CMAKE_BINARY_DIR}/CMakeFiles/tester.dir/

CMake seems to name the source files in a way that isn't very compatible with gcov though. For example if I had a source file called "mytestprog.cpp" it would be build

mytestprog.cpp.o
mytestprog.cpp.gcda
mytestprog.cpp.gcdno

where as gcov seems to expect

mytestprog.gcda
mytestprog.gcdno

I'm not really sure how to fix it. I've tried using LCov instead and that "appeared" to work but I'm not really sure if it did.

like image 110
delcypher Avatar answered Oct 16 '22 11:10

delcypher


Delcypher pointed out the problem.

Solution 1: you can ask cmake to name object files as main.o instead of main.cpp.o etc. using the undocumented CMAKE_CXX_OUTPUT_EXTENSION_REPLACE switch:

cmake -DCMAKE_CXX_OUTPUT_EXTENSION_REPLACE=ON ...

Solution 2: if you do not need the .gcov files you can call lcov from the build directory:

lcov --capture --directory . --output-file coverage.info
genhtml coverage.info --output-directory out

You will find the coverage information in the out directory in html form.

like image 31
robert Avatar answered Oct 16 '22 11:10

robert


Not sure where you got --coverage from, but these are the arguments I use on Linux to get coverage information using gcc and gcov:

set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fprofile-arcs -ftest-coverage")
set(CMAKE_EXE_LINKER_FLAGS
    "${CMAKE_EXE_LINKER_FLAGS} -fprofile-arcs -ftest-coverage")

Here's what gcc --help --verbose has to say about those options:

-ftest-coverage Create data files needed by "gcov"

-fprofile-arcs Insert arc-based program profiling code

like image 4
richq Avatar answered Oct 16 '22 11:10

richq


You don't need to pass --coverage to the linker. --coverage will pass -fprofile-arcs -ftest-coverage to the compiler and -lgcov to the linker.

Are you sure that it isn't creating any gcdo or gcda files? Where are you looking for these files? It should put the gcov file for each object file into the same directory as the object file. Do a find for .gcda files at the top of your build directory. If nothing shows up, gcov might not be getting linked in. Run the following command to see if it is:

nm name_of_binary | grep "gcov"

If it is getting linked in, then gcov might not have permission to write files to where you are running the executable. If it has permission, then I am stumped.

like image 1
able Avatar answered Oct 16 '22 12:10

able