问题
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:
profiling: /xxxx/xxxxxj/projects/build-xxxxx-CLang-Debug/tests/CMakeFiles/xxxxxxxxxxxxxt_ut.dir/tests/gui/ship_design/ut_ship_stats_header.cpp.gcda: cannot merge previous GCDA file: mismatched number of counters (14)
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)
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)
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.
- I may miss some valuable configuration of code coverage data (ie. call lcov --zerocounters
FIND_PROGRAM( LCOV_PATH lcov )
COMMAND ${LCOV_PATH} -z --directory ${PROJECT_BINARY_DIR}}
- I need to add custom target removing all gcda files before test run is committed.
How should I approach this problem?
回答1:
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.
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)
Then create a custom target.
## 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
)
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 ... ]
$
The make coverage
target we defined in our CMakeLists.txt will:
- 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.
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.)
来源:https://stackoverflow.com/questions/41936659/code-coverage-warrnings-spam-output