Search code examples
cgcccode-coveragegcovgcc11

On `gcc` 11, how to change the prefix of `.gcno` files when using `--coverage` so they match what `gcov` expects?


I'm adding code coverage on a C project of mine. The process I'm following is this:

# compile a .c file, expecting two new files "a.out" and "main.gcno"
gcc --coverage main.c

# run executable to get coverage data, expecting to create a new "main.gcda" file
./a.out

# use `gcov` to get formatted reports
gcov main.c

When I'm using gcc on version 10.3.0, this all works as expected without issues. When using gcc with version 11.1.0 however, both the main.gcno and main.gcda files have a different name, which breaks the flow as explained below.

Using gcc --coverage main.c produces two files, a.out and a-main.gcno. Then running the executable with ./a.out creates a new file a-main.gcda. Notice the prefix a- on the coverage files. When running the next command gcov main.c, I get the following error:

main.gcno:cannot open notes file
main.gcda:cannot open data file, assuming not executed

Because it is looking for the files main.gcno and main.gcda, but it can't find them.

Why does the new version of gcc do that? Everything I read online assumes that the output of the compiler should be in sync with gcov when run on the same source file. I couldn't find anywhere a way to change the output name of coverage files.

In case it helps, I also noticed the a- prefix depends on the output name. So if an output name is specified (gcc --coverage main.c -o test) then the coverage files will have that as prefix (test-main.gcno and test-main.gcda).

I've also tried manually renaming the files to remove the prefix, and gcov seems happy with that. The problem is that I'm trying to automate the process, and I'd like a more robust way than trying to guess what output name the compiler uses for coverage files.

For reference, I'm also using gcov on version 11.1.0. It's not clear to me if that's related to the gcc being the same version.


Solution

  • Why does the new version of gcc do that?

    See the release notes for GCC 11, specifically the third bullet of the Caveats which starts "Naming and location of auxiliary and dump output files changed".

    Everything I read online assumes that the output of the compiler should be in sync with gcov when run on the same source file. I couldn't find anywhere a way to change the output name of coverage files.

    As it says in the release notes, the -dumpbase option is what you want. To remove any prefix, use -dumpbase ''

    I'm not sure whether gcov should have been updated, or if the gcc-11 change should not have affected the coverage files. Edit: This is behaving as expected.

    Another solution is to compile and link in two separate steps:

    gcc --coverage main.c -c
    gcc --coverage main.o
    

    This way the coverage data files do not get the prefix, and gcov finds them as expected.