BullseyeCoverage Up Contents Search

GCC and Clang

Cross Compiling

When cross compiling and BullseyeCoverage recognizes the compiler architecture, the appropriate run-time source file is automatically compiled and linked. For example, if the compiler option -dumpmachine output contains "linux", BullseyeCoverage compiles and links BullseyeCoverage/run/libcov-posix.c.

You have the option to manually build the run-time library with a special name so that it is linked automatically. This overrides the default behavior described above. The special library name format is:

BullseyeCoverage/lib/libcov-arch.a

The filename component arch is the string printed by the compiler option -dumpmachine. For example, if gcc -dumpmachine outputs arm-linux, then the special library name is BullseyeCoverage/lib/libcov-arm-linux.a.

Example 1

$ gcc -dumpmachine
nios2-elf
$ cd BullseyeCoverage/run
$ gcc -c libcov-printf.c
$ ar -r libcov-nios2-elf.a libcov-printf.o

Example 2

$ gcc -dumpmachine
arm-eabi
$ cd BullseyeCoverage/run
$ gcc -c libcov-userDefined.c
$ ar -r libcov-arm-eabi.a libcov-userDefined.o

If you build your cross-compiled run-time library from run/libcov-posix.c, set the COVFILE environment variable on the target device to the path of your coverage file located on your host system. You must have read and write access to the coverage file. For example:

$ export COVFILE=/host/project/test.cov
$ ./a.out

Precompiled Headers

Precompiled headers are not utilized with BullseyeCoverage because the compiler does not use precompiled headers when invoked for preprocessing (with -E).

Assess the Cost-Benefit

Because of potential complications of using precompiled headers, you may wish to first determine whether precompiled headers provide a significant reduction to your build time. Keep in mind that precompiled headers provide no benefit when BullseyeCoverage is enabled.

Recommended Organization

Ideally, when the compiler uses a header.h.gch file, the effect is identical to including the corresponding header.h, merely faster. To achieve this goal, follow the recommendations below.

  1. The .gch filename must match the header filename used to create it. That is, header.h.gch is created from header.h.

    Create .gch precompiled headers only from .h headers and never from .c or .cpp files. For example,

    g++ -x c++-header pch.c -o pch.h.gch    ← Wrong. Name mismatch
    g++ pch.h                               ← Correct. This creates pch.h.gch
    
  2. The source header should be located in the same directory as the .gch. If you use compiler option -o to locate the .gch in your output directory, then you should also link the source file to that location. For example,
    g++ pch.h -o x64/debug/pch.h.gch
    ln -s pch.h x64/debug/pch.h             ← Add this
    
  3. When creating a .gch file, do not use compiler option -include. Use the #include directive to include all headers during this build step. For example,
    g++ -include extra.h ... pch.h          ← Wrong
    

To verify your build process properly adheres to these recommendations:

  1. Disable BullseyeCoverage
  2. Disable creation of .gch files. To do this, remove compiler commands that:
  3. Perform a clean build. Add -I options to resolve errors due to headers not found until your build is successful.

Automatic Workaround

When BullseyeCoverage encounters a compile command that creates a .gch file in an output directory where the input header file does not exist, a symbolic link to the header is automatically created in the output directory.

g++ pch.h -o x64/debug/pch.h.gch
ln -s pch.h x64/debug/pch.h             ← BullseyeCoverage performs this automatically

Updated: 7 Mar 2024