如何在 Travis CI 中为 C++ with/CMake 项目正确配置 CodeCov?

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

我正在尝试使用 TravisCI 在我的 GitHub 存储库上配置 CodeCov。由于我的回购是在 C++ 中并且我已经使用了 CMake,所以我基本上将 this exampleafter_success 标签复制粘贴到我的 .travis.yml 文件中:

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"

我推送了一个自定义 .codecov.yml 文件来提供我的令牌和通知设置,但是 after_success 只是示例中建议的那个。我真的不熟悉 lcov,所以我不知道是否缺少其他内容或这些调用是为了什么。

查看 CodeCov 的文档,我找不到我可能遗漏的内容,但我的覆盖率报告是空的,因为 lcov 找不到一些神秘的 .gcda 文件(我猜)。 CodeCov 的文档在任何地方都没有提到这一点,所以我想我在配置中遗漏了一个重要步骤(或者可能由于某种原因找不到文件......?)

这是 TravisCI after_success 阶段的输出:

$ 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/********

问题出在 Cmake 编译器和 linker 标志上。为了让 GCov(GCC 的一部分,lcov 使用)提供分析信息和覆盖率测试,必须设置一些标志。

来自 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.

另外,来源需要 link 与 -lgcov --coverage 编辑。就我而言,因为我使用的是 Cmake,所以我需要使用 set_target_properties 函数指定这些:

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"
)

最后,由于您通常不希望在覆盖率报告中包含单元测试,因此您将为它们定义编译器标志。但是请注意,如果您 link 使用使用 gcov 选项编译的库进行单元测试,您仍然需要添加 linker 标志。