我正在尝试使用共享库从一个简单的测试项目中获取代码覆盖率,但由于某种原因,我的 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
非常感谢任何解决我面临的问题并且仍然能够使用共享库的想法!
感谢 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 文件中删除此行即可解决该问题。如果有人可以解释为什么会导致此问题,请告诉我,因为我不知道。