GCOVR如何覆盖共享库,不生成GCNO文件

问题描述 投票:0回答:1

我正在尝试使用共享库从一个简单的测试项目中获取代码覆盖率,但由于某种原因,我的 XML 文件为空,并且没有为共享库生成 .gcno 文件。我唯一的 .gcno 文件来自单元测试可执行文件。此外,根本不会生成 .gcda 文件。我有以下文件夹结构:

ProjectRoot/
|- src/
|  |- calculator/
|  |  |- CMakeLists.txt
|  |  |- Calculator.cpp
|  |  |- Calculator.h
|  |- CMakeLists.txt
|  |- sources.cpp
|  |- sources.h
|- tests/
|  |- CMakelists.txt
|  |- unit-test1.cpp
|- CMakeLists.txt

根 CMakeLists.txt 文件:

cmake_minimum_required (VERSION 3.14)
enable_testing()
project("testProject")

add_subdirectory("src")

if (CMAKE_BUILD_TYPE MATCHES Debug)
    add_subdirectory("tests")
endif()

src CMakeLists.txt 文件:

project ("main")
add_subdirectory("calculator")

add_executable(${PROJECT_NAME} "sources.cpp" "sources.h")
target_link_libraries(${PROJECT_NAME} "calculator")

if (CMAKE_VERSION VERSION_GREATER 3.12)
    set_property(TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD 20)
endif()

计算器CMakeLists.txt文件:

project("calculator")

add_library(${PROJECT_NAME} SHARED "Calculator.h" "Calculator.cpp")

if (CMAKE_VERSION VERSION_GREATER 3.12)
    set_property(TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD 20)
endif()

(单元)测试CMakeLists.txt文件

set(UNIT-TESTS "unit-tests")
include(CTest)

include(FetchContent)
FetchContent_Declare(
    googletest
    GIT_REPOSITORY https://github.com/google/googletest.git
    GIT_TAG v1.14.0)

set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
FetchContent_MakeAvailable(googletest)

# This will generate an empty code coverage result and only a unit-test1.cpp.gcno file
add_executable(${UNIT-TESTS} unit-test1.cpp)
target_link_libraries(${UNIT-TESTS} GTest::gtest_main calculator)

# if I change the executable to this I will have the correct code coverage result 
# and 2 .gcno files: unit-test1.cpp.gcno and Calculator.cpp.gcno
# But no .gcda file is generated (unsure if that is significant).
# add_executable(${UNIT-TESTS} unit-test1.cpp "../src/calculator/Calculator.h" "../src/calculator/Calculator.cpp")
# target_link_libraries(${UNIT-TESTS} GTest::gtest_main)

include(GoogleTest)
gtest_discover_tests(${UNIT-TESTS})

set(CMAKE_MODULE_PATH /usr/src/CMake)
include(CodeCoverage)
append_coverage_compiler_flags(${UNIT-TESTS})

set(CMAKE_CXX_FLAGS  "${CMAKE_CXX_FLAGS} -O0")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O0")

set(GCOVR_PATH "/usr/bin/gcovr")
setup_target_for_coverage_gcovr_xml(
        NAME CoverageXml
        EXECUTABLE ${UNIT-TESTS}
        DEPENDENCIES ${UNIT-TESTS}
        EXECUTABLE_ARGS "--gtest_output=xml:report/"
        EXCLUDE "out/" "tests/")

有关函数append_coverage_compiler_flags()和setup_target_for_coverage_gcovr_xml(),请查看此处https://github.com/bilke/cmake-modules/blob/master/CodeCoverage.cmake。该模块已加载到我正在使用的 docker 映像中。要编译并运行coverageXml和单元测试目标,我使用以下命令:

cmake -S ./ -B ./out/build/ -DCMAKE_BUILD_TYPE=Debug -DCMAKE_C_COMPILER=clang-16 -DCMAKE_CXX_COMPILER=clang++-16
cmake --build ./out/build/ --parallel 2 --target CoverageXml unit-tests

非常感谢任何解决我面临的问题并且仍然能够使用共享库的想法!

cmake gcov gcovr
1个回答
0
投票

感谢 Tsyvarev 将我推向正确的道路。使用当前的 cmake 文件和 cmake 命令。标志 -g 和 --coverage 不会提供给计算器库。我发现了 2 个可能的修复方法,或者将其添加到库中:

set(CMAKE_MODULE_PATH /usr/src/CMake)
include(CodeCoverage)
append_coverage_compiler_flags(${PROJECT_NAME})

这绝对适用于这个项目,但我还有另一个更大的项目。我使用的修复方法是将 -g 和 --coverage 标志添加到命令中,如下所示:

-DCMAKE_CXX_FLAGS="-g --coverage"

在遇到相同问题的其他项目上测试此解决方案(第二个选项)时,我注意到在单元测试文件夹中的 CMakeLists.txt 文件中使用 project() 函数会导致另一个问题。

将生成 .gcno 文件(针对可执行文件和库),但 XML 文件将仅包含其自身的单元测试文件,而不包含库的可执行文件。只需从 CMakeLists.txt 文件中删除此行即可解决该问题。如果有人可以解释为什么会导致此问题,请告诉我,因为我不知道。

© www.soinside.com 2019 - 2024. All rights reserved.