问题描述
在CMake测试配置中,我添加了标记以生成代码覆盖率
In CMake tests configuration I added flags to generate codecoverage
IF( "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" OR
"${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -O0 -fprofile-arcs -ftest-coverage")
SET(CMAKE_C_FLAGS "-g -O0 -fprofile-arcs -ftest-coverage ")
endif()
每次运行测试时-我的输出都被这些消息淹没:
Each time I run tests - my output is spammed with those messages:
分析:
/xxxx/xxxxxx/projects/build-xxxxxxxxxxxxxxx-CLang-Debug/tests/CMakeFiles/xxxxxxxxxxxxxxx_ut.dir/tests/gui/ship_design/ut_ship_stats_header.cpp.gcda:
无法合并先前的GCDA文件:弧形标记(0x2b8e100f)
profiling: /xxxx/xxxxxx/projects/build-xxxxxxxxxxxxxxx-CLang-Debug/tests/CMakeFiles/xxxxxxxxxxxxxxx_ut.dir/tests/gui/ship_design/ut_ship_stats_header.cpp.gcda: cannot merge previous GCDA file: corrupt arc tag (0x2b8e100f)
分析:
/xxxx/xxxxxx/projects/build-xxxxxxxxxxxxxxx-CLang-Debug/tests/CMakeFiles/xxxxxxxxxxxxxxx_ut.dir/tests/ut_generate_hex_path.cpp.gcda:
无法合并以前的GCDA文件:损坏的弧标记(0x65646f6e)
profiling: /xxxx/xxxxxx/projects/build-xxxxxxxxxxxxxxx-CLang-Debug/tests/CMakeFiles/xxxxxxxxxxxxxxx_ut.dir/tests/ut_generate_hex_path.cpp.gcda: cannot merge previous GCDA file: corrupt arc tag (0x65646f6e)
我不必说这至少会使读取测试运行结果困难。当我删除以前生成的所有gcda文件时,上述问题消失了。因此,有两种可能的解决方案。
I don't have to say that this make reading test run results at least difficult. Above problem vanished when I remove all gcda files generated previously. So there are two possible solutions.
- 我可能会错过一些有价值的代码覆盖率数据配置(即,调用lcov --zerocounters
命令$ {LCOV_PATH} -z-目录$ {PROJECT_BINARY_DIR}}
COMMAND ${LCOV_PATH} -z --directory ${PROJECT_BINARY_DIR}}
- 我需要添加自定义目标是在提交测试运行之前删除所有gcda文件。
我应该如何解决此问题?
How should I approach this problem?
推荐答案
我认为您可能在工作流程中做了一些不寻常的事情,因为您看到的问题并不一定总是发生。
I think you might be doing something unusual in your workflow, as the problem you're seeing shouldn't happen all of the time. But, what I've added here should help you figure that out, or work around it completely.
首先,您应该利用CMake的,并创建自己的 coverage
Firstly, you should take advantage of CMake's build-types and create your own "coverage type".
## coverage flags
set(CMAKE_CXX_FLAGS_COVERAGE "-g -O0 -fprofile-arcs -ftest-coverage" CACHE STRING "Flags used by the C++ compiler during coverage builds.")
set(CMAKE_C_FLAGS_COVERAGE "-g -O0 -fprofile-arcs -ftest-coverage" CACHE STRING "Flags used by the C compiler during coverage builds.")
set(CMAKE_EXE_LINKER_FLAGS_COVERAGE "-g -O0 -fprofile-arcs -ftest-coverage" CACHE STRING "Flags used for linking binaries during coverage builds.")
set(CMAKE_SHARED_LINKER_FLAGS_COVERAGE "-g -O0 -fprofile-arcs -ftest-coverage" CACHE STRING "Flags used by the shared libraries linker during coverage builds.")
mark_as_advanced(
CMAKE_CXX_FLAGS_COVERAGE
CMAKE_C_FLAGS_COVERAGE
CMAKE_EXE_LINKER_FLAGS_COVERAGE
CMAKE_SHARED_LINKER_FLAGS_COVERAGE)
## Update the documentation string of CMAKE_BUILD_TYPE for GUIs
set(CMAKE_BUILD_TYPE "${CMAKE_BUILD_TYPE}" CACHE STRING "Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel RelWithAssert Coverage." FORCE)
然后创建。
## create our "make coverage" target
add_custom_target(coverage
COMMAND if test ! -d ../output \; then mkdir ../output\; fi
COMMAND find ${CMAKE_BINARY_DIR} -name \*.gcda -delete
COMMAND lcov -b CMakeFiles/ -d . -z
COMMAND lcov -b -d . -c -i -o test_base.info
COMMAND ./env-shell.sh ctest -j2 || true
COMMAND lcov -b CMakeFiles/ -d . -c -o test_run.info
COMMAND lcov -b CMakeFiles/ -d . -a test_base.info -a test_run.info -o test_total.info
COMMAND lcov -o reports.info -r test_total.info '/usr/include/*' '/usr/local/*' '/cvmfs/*' '*/numpy' '/usr/lib/gcc/*' ${p} '${CMAKE_BINARY_DIR}/CMakeFiles/' '${CMAKE_BINARY_DIR}/steamshovel/*'
COMMAND genhtml --ignore-errors source --legend -o ../output/`date +%Y-%m-%d` reports.info
)
现在,利用源代码外的构建,在与源代码平行的 coverage目录中运行 cmake
。
Now, taking advantage of out-of-source builds, run cmake
in a "coverage" directory parallel to your source.
$ pwd
/home/user/my_project/src
$ mkdir ../coverage
$ cd ../coverage
$ cmake -DCMAKE_BUILD_TYPE=Coverage ../src
[ ... cmake's output here ...]
-- Configuring done
-- Generating done
-- Build files have been written to: /home/user/my_project/coverage
$
现在,构建项目和测试,并运行覆盖目标。
Now, build your project, and your tests, and run your "coverage" target.
$ make
$ make test-bins
$ make coverage
[ ... make's output here ... ]
$
我们在CMakeLists.txt中定义的覆盖范围
目标将是:
The make coverage
target we defined in our CMakeLists.txt will:
- 如果不存在,则创建一个与我们的源代码平行的输出目录并构建目录
- 查找并删除所有
*。当前构建目录中的gcda
文件 - 零并初始化
lcov
计数器和输出文件 - 通过
ctest
运行测试。 - 编译
lcov
输出并生成我们的HTML覆盖率报告
- if it doesn't exist, create an "output" directory parallel to our source and build directories
- find and delete all
*.gcda
files in our current build directory - zero and initialize our
lcov
counters and output file - run our tests via
ctest
- "compile" the
lcov
output and generate our HTML coverage report
请注意,您可能需要针对特定项目进行调整。
Note that you may need to adjust things for your particular project.
在这一点上,我强烈建议将所有这些自动化。将它添加到您的持续集成中(如果有的话),甚至设置一个 cron
作业,这样它可以在一夜之间运行,并且您可以从一份全新的覆盖报告中开始新的一天。 (这些示例来自一个正在执行的项目,该项目执行由处理的夜间覆盖率报告。)
At this point I highly recommend automating all of this. Add it to your continuous integration, if you have some, or even set up a cron
job so that this runs overnight and you have a fresh new coverage report to start your day. (These examples are from a working project that does a nightly coverage report handled by buildbot.)
这篇关于代码覆盖警告垃圾邮件输出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!