5

I am using QT Creator to work on a medium-sized project in C++.

The project structure basically looks like this

  1. Project

    • Group A
      • Library A1
    • Group B
      • Library B1
      • Library B2
      • ...etc
    • Test

      • LibA1_Test
      • LibB1_Test
      • LibB2_Test
      • ...etc

The libraries are tested by the executables in the test project. I've managed to compile the tests themselves with gcov enabled, and produce code coverage reports with lcov, but all that they were showing the coverage for were the test cases, not the actual code that I'm testing. I've also tried compiling the static libraries with gcov as well, but when I run the tests against those libraries it does not generate any of the gcov output files.

How could I generate the gcov output files by linking my project libraries against the tests? I want to see if there are any gaps in my unit tests.

alayers2
  • 510
  • 5
  • 16

2 Answers2

2

From the ld manual

--whole-archive
For each archive mentioned on the command line after the --whole-archive option, include every object file in the archive in the link, rather than searching the archive for the required object files.

So link your static-library into your test using --whole-archive, which will result in your test binary having the entire static-library, and give gcov visibility of the entire code

Steve Lorimer
  • 27,059
  • 17
  • 118
  • 213
  • Since I was specifically using QT Creator to build my project, I just wanted to add what steps I had to take. In my test applications I added: `QMAKE_CXXFLAGS += -g -Wall -fprofile-arcs -ftest-coverage -O0` and `QMAKE_LFLAGS += -g -Wall -Wl,--whole-archive -lLibA1 -Wl,--no-whole-archive -fprofile-arcs -ftest-coverage -O0` to the .proj file, as well as `LIBS += -lgcov`. If you don't specify the libraries to include in the whole archive command and then remember to close it, you'll get lots of errors. – alayers2 Jun 30 '16 at 14:30
  • Remember to add --coverage (or specific flags) also to all compilation units composing the static library and not just to the test ones. – ocirocir Mar 19 '18 at 13:28
1

To be honest, you don't really need --whole-archive, it's enough to just add the following to all the staticlibs and Unit-Tests, that you want gcov information from:

# only apply codecoverage when CodeCoverage is set and debug-mode is active
CodeCoverage
{
    debug:QMAKE_CXXFLAGS_DEBUG += --coverage    # -fprofile-arcs -ftest-coverage
    debug:QMAKE_LFLAGS_DEBUG   += --coverage    # -lgcov
}

--coverage is context-sensitive and the meaning of it depends on whether you pass it to CXXFLAGS or LFLAGS: https://gcc.gnu.org/onlinedocs/gcc/Instrumentation-Options.html#Instrumentation-Options

Also mentioned in https://stackoverflow.com/a/5352713/7820869. So no need to add -fprofile-arcs or any other mixture of flags. In your case, add those Flags to A1.pro, B1.pro and B2.pro.

The added scope around the flags just prevent that the codecoverage-flags pollute your build in Release- or Debug-mode. Just pass "CONFIG+=CodeCoverage" to qmake.exe, so it will build with code-coverage: https://doc.qt.io/archives/qt-4.8/qmake-advanced-usage.html#configuration-and-scopes

After that just check whether after compilation the *.gcno files and after running the Unit-Test's the *.gcda files have been generated in the build-directory and call lcov on them: https://gcc.gnu.org/onlinedocs/gcc/Gcov-Data-Files.html#Gcov-Data-Files

Additional Info

The stackoverflow, that helped me solving my problems I run into: Where are the gcov symbols?

in case you are running into linker errors like (undefined reference to __gcov_init and __gcov_merge_add), watch out that you are really adding those flags to every unit: https://www.spinics.net/lists/gcchelp/msg29518.html

Robert
  • 127
  • 1
  • 10