简体   繁体   中英

How to properly configure CodeCov for a C++ w/ CMake project in TravisCI?

I was trying to configure CodeCov on my GitHub repo with TravisCI. Since my repo is in C++ and I used CMake already, I essentially copy-pasted the after_success label of this example into my .travis.yml file:

after_success:
    # Creating report
  - cd ${TRAVIS_BUILD_DIR}
  - lcov --directory . --capture --output-file coverage.info coverage info
  - lcov --remove coverage.info '/usr/*' --output-file coverage.info 
  - lcov --list coverage.info
  # Uploading report to CodeCov
  - bash <(curl -s https://codecov.io/bash) || echo "Codecov did not collect coverage reports"

I pushed a custom .codecov.yml file to provide my token and notification settings, but the after_success is just the one suggested in the example. I'm really not familiar with lcov , so I have no idea whether something else is missing or what those calls are for.

Looking at CodeCov's documentation I couldn't find what I might be missing but my coverage reports are empty because lcov can't find some mysterious .gcda file (I guess). CodeCov's docs don't mention that anywhere so I guess I'm missing an important step in my configuration (or perhaps the file can't be found for some reason...?)

This is the output of TravisCI's after_success stage:

$ lcov --directory . --capture --output-file coverage.info
Capturing coverage data from .
Found gcov version: 4.8.4
Scanning . for .gcda files ...
geninfo: ERROR: no .gcda files found in .!

$ lcov --remove coverage.info '/usr/*' --output-file coverage.info
Reading tracefile coverage.info
lcov: ERROR: no valid records found in tracefile coverage.info

$ lcov --list coverage.info
Reading tracefile coverage.info
lcov: ERROR: no valid records found in tracefile coverage.info

$ bash <(curl -s https://codecov.io/bash) || \
  echo "Codecov did not collect coverage reports"
  _____          _
 / ____|        | |
| |     ___   __| | ___  ___ _____   __
| |    / _ \ / _` |/ _ \/ __/ _ \ \ / /
| |___| (_) | (_| |  __/ (_| (_) \ V /
 \_____\___/ \__,_|\___|\___\___/ \_/
                              Bash-8fda091
==> Travis CI detected.
    project root: .
--> token set from env
    ...
==> Running gcov in . (disable via -X gcov)
==> Python coveragepy not found
==> Searching for coverage reports in:
    + .
    -> Found 3 reports
==> Detecting git/mercurial file structure
==> Appending build variables
    + TRAVIS_OS_NAME
==> Reading reports
    - Skipping empty file ./coverage.info
    + ./doc/****.zip bytes=337165           -----> That's not a report.
    + ./doc/****.pdf bytes=353614           -----> That's not a report.
==> Appending adjustments
    http://docs.codecov.io/docs/fixing-reports
    + Found adjustments
==> Uploading reports
    url: https://codecov.io
    query: branch=codecov&commit=*****...
    -> Pinging Codecov
    -> Uploading to S3 https://codecov.s3.amazonaws.com
    -> View reports at https://codecov.io/github/********

The problem was with Cmake compiler and linker flags. In order for GCov (part of GCC, and used by lcov ) to provide profiling information and coverage tests some flags have to be set.

From Code Coverage for C Unit Tests :

Specifically, you need the compiler to add profiling information to the object code, which is done by adding the flags -fprofile-arcs and -ftest-coverage to your compile command.

The first flag adds logic to the object code to generate generic profiling information. This is information about how often each basic block is executed. When your program is run, all of this information will be saved to a new file with the extension .da, next to the .o file. The data in this file isn't coverage specific, but it will be used by gcov.

The second flag that you passed to GCC, -ftest-coverage , is also going to add logic to your object files. This time, the goal is to output the coverage-specific information. There are two files that will be generated, a .bb and a .bbg. The .bb file is a simple mapping file from basic blocks to line numbers. The .bbg file lists each of the arcs in the corresponding source file that were run when executing the application. This data is used by gcov to reconstruct the actual program flow graph, from which all basic block and arc execution counts can be computed.

Also, the sources need to be linked with -lgcov --coverage . In my case, since I'm using Cmake I needed to specify these with the set_target_properties function:

add_executable(dss-sim dss-sim.cpp)
target_link_libraries(dss-sim
    list
    of
    my
    static
    libs
)
# The libs above also need to be compiled with the same flags.
set_target_properties(dss-sim
    PROPERTIES
    COMPILE_FLAGS "-ftest-coverage -fprofile-arcs"
    LINK_FLAGS    "-lgcov --coverage"
)

Finally, since you normally don't want to include your unit tests in your coverage report, you will not define the compiler flags for them. Note, however, that if you link your unit tests with libraries that were compiled with gcov options, you'll still need to add the linker flags.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM