gccgcovgcovr

gcov and gcovr: no .gcno files are generated after compiling


I am trying to get code coverage in my unit test project in windows system.

Description

After compiling with -fprofile-arcs -ftest-coverage, I found out the execution file is generated and works fine. However there's no any .gcno files in the folder. So I cannot output the coverage report properly by gcovr.

Software version

gcc 8.1.0/gcov 8.1.0/gcovr 5.1/python 3.10.2

Steps

Here's what I've done during the whole process. Please help me if there's something wrong.

  1. There are only .c and .h files in one folder

  2. Compile my project using gcc

gcc -Wall -Wno-unknown-pragmas -fcompare-debug-second -fprofile-arcs -ftest-coverage -DUTEST AllTests.c CuTest.c BZR2.c BZR2_test.c -o beta.exe

  1. Then I got beta.exe in the folder.

  2. After runing beta.exe, there's my test result(All tests are passed.) showing in the command line window. Besides there're .gcda files with the same filename as my .c files.

  3. Then I run gcovr -r ., the result is showing below. I think the reson why gcovr can't show the coverage information is there's no any .gcno files generated after compiling my project. But I don't understand why and how to solve this.

------------------------------------------------------------------------------
                           GCC Code Coverage Report
Directory: .
------------------------------------------------------------------------------
File                                       Lines    Exec  Cover   Missing
------------------------------------------------------------------------------
------------------------------------------------------------------------------
TOTAL                                          0       0    --%
------------------------------------------------------------------------------

Thanks for your time!


Solution

  • Remove the -fcompare-debug-second option. It is used for debugging the compiler itself, and causes the compiler

    to silence warnings, and omitting other options that would cause the compiler to produce output to files or to standard output as a side effect.

    (see: https://gcc.gnu.org/onlinedocs/gcc-8.5.0/gcc/Developer-Options.html)

    Creation of gcno files is such a side effect.


    General tips:

    Instead of -fprofile-arcs -test-coverage you can simply use the --coverage option.

    When you compile multiple source files in one go, then GCC tries to figure out file names for intermediate files, and also automatically derives some name for secondary outputs like gcno files. This used to be somewhat unintuitive, at least until reasonable behaviour was implemented in GCC 11.

    To compile all of the files individually, we would use the structure:

    OPTIONS="-Wall -Wno-unknown-pragmas --coverage -DUTEST"
    
    # compile the individual compilation units
    gcc -c $OPTIONS AllTests.c -o AllTests.o
    gcc -c $OPTIONS BZR2.c -o BZR2.o
    gcc -c $OPTIONS BZR2_test.c -o BZR2_test.o
    
    # we should now have three gcno files
    ls *.gcno
    
    # link the final executable
    gcc $OPTIONS CuTest.o BZR2.o BZR2_test.o -o beta.exe
    

    At this point, it's typically appropriate to use a build system, for example by writing a Makefile:

    CFLAGS += -Wall -Wno-unknown-pragmas --coverage -DUTEST
    
    SOURCES = AllTests.c BZR2.c BZR2_tests.c
    OBJECTS = $(SOURCES:.c=.o)
    
    beta.exe: $(OBJECTS)
        $(CC) $(CFLAGS) $^ -o $@