使用 CMake 将 *.gcno 和 *.gcda 文件添加到 make clean 规则中

Glu*_*ton 5 makefile cmake lcov test-coverage

我的项目结构类似:

\n\n
\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 CMakeLists.txt\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 src\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 logic.cpp\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 logic.h\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 test\n    \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 CMakeLists.txt\n    \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 logic_test.cpp\n
Run Code Online (Sandbox Code Playgroud)\n\n

主要CMakeLists.txt文件是:

\n\n
cmake_minimum_required (VERSION 2.8)\nproject (Logic)\nset (Logic_SOURCES ${PROJECT_SOURCE_DIR}/src/logic.cpp)\ninclude_directories (${PROJECT_SOURCE_DIR}/src)\nadd_library (logic SHARED ${Logic_SOURCES})\nadd_subdirectory (test)\n
Run Code Online (Sandbox Code Playgroud)\n\n

对于CMakeLists.txt测试来说是:

\n\n
find_package (GTest)\nset (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O0 -g -march=native -mtune=native -fprofile-arcs -ftest-coverage")\nset (CMAKE_EXE_LINKER_FLAGS "-fprofile-arcs -ftest-coverage")\nset (Test_SOURCES ${Logic_SOURCES} ${PROJECT_SOURCE_DIR}/test/logic_test.cpp)\nadd_executable (logic_test ${Test_SOURCES})\ntarget_link_libraries (${TestName} gtest gtest_main gcov pthread)\n
Run Code Online (Sandbox Code Playgroud)\n\n

为了处理测试覆盖率报告,我已将自定义目标添加到test/CMakeLists.txt

\n\n
set (Coverage_REPORT ${PROJECT_BINARY_DIR}/coverage.info)\nset (Coverage_DIR    ${PROJECT_BINARY_DIR}/coverage)\nadd_custom_command (\n    OUTPUT  ${Coverage_REPORT}\n    COMMAND lcov -q -c -f -b . -d ${PROJECT_BINARY_DIR}/test -o ${Coverage_REPORT}\n    COMMAND lcov -e ${Coverage_REPORT} \'${PROJECT_SOURCE_DIR}/src/*\' -o ${Coverage_REPORT}\n    COMMAND genhtml ${Coverage_REPORT} --legend --demangle-cpp -f -q -o ${Coverage_DIR}\n    DEPENDS logic_test\n)\nadd_custom_target (coverage DEPENDS ${Coverage_REPORT})\n
Run Code Online (Sandbox Code Playgroud)\n\n

所有这些代码都正确且符合预期。工作流程如下所示:

\n\n
mkdir build\ncd build\ncmake ..\nmake\n./test/logictest\nmake coverage\n
Run Code Online (Sandbox Code Playgroud)\n\n

但现在我想将测试覆盖工件添加到make clean规则中。我尝试将此代码添加到test/CMakeLists.txt

\n\n
file (GLOB_RECURSE Test_GCNOS ${PROJECT_BINARY_DIR}/*.gcno)\nfile (GLOB_RECURSE Test_GCDAS ${PROJECT_BINARY_DIR}/*.gcda)\nlist (APPEND Test_COVERAGE_DATA "${Coverage_REPORT}")\nlist (APPEND Test_COVERAGE_DATA "${Coverage_DIR}")\nlist (APPEND Test_COVERAGE_DATA "${Coverage_GCNO}")\nlist (APPEND Test_COVERAGE_DATA "${Coverage_GCDA}")\nset_directory_properties (PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "${Test_COVERAGE_DATA}")\n
Run Code Online (Sandbox Code Playgroud)\n\n

但这种方法并没有按预期工作(对我来说)。当调用cmake ..artifatc 时尚不存在,因此变量为空,这需要在运行测试后Coverage_DATA调用。cmake ..这看起来很丑(对我来说)。

\n\n

所以我的问题是:如何将测试覆盖工件添加到make clean规则中?

\n

Glu*_*ton 1

它不能被称为优雅的解决方案,但在我看来,它比cmake回忆更好。\n我尝试创建宏,它通过源文件列表确定覆盖工件(*.gcno和文件)的名称:*.gcda

\n\n
macro (determine_coverage_data Sources TestName Artifacts Suffix)\nset (CoverageDirectory "${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/${TestName}.dir")\nforeach (File ${Sources})\n    string (REGEX MATCH "^${CMAKE_CURRENT_SOURCE_DIR}*" Directory "${File}")\n    if    (Directory STREQUAL CMAKE_CURRENT_SOURCE_DIR)\n        string (REGEX REPLACE "^${CMAKE_CURRENT_SOURCE_DIR}*" "${CoverageDirectory}" File "${File}")\n    else  (Directory STREQUAL CMAKE_CURRENT_SOURCE_DIR)\n        string (REGEX REPLACE "/" ";" A "${CMAKE_CURRENT_SOURCE_DIR}")\n        string (REGEX REPLACE "/" ";" B "${File}")\n        list (LENGTH A DeepDirectory)\n        list (LENGTH B DeepFile)\n        set (File "${CoverageDirectory}")\n        set (I 1)\n        while    (I LESS DeepDirectory)\n            list (GET A ${I} AI)\n            list (GET B ${I} BI)\n            if    (AI STREQUAL BI)\n                math (EXPR I "${I} + 1")\n            else  (AI STREQUAL BI)\n                math (EXPR DeepDiff "${DeepFile} - ${I} - 1")\n                while    (DeepDiff GREATER 0)\n                    set (File "${File}/__")\n                    math (EXPR DeepDiff "${DeepDiff} - 1")\n                endwhile (DeepDiff GREATER 0)\n                while    (I LESS DeepFile)\n                    list (GET B ${I} BI)\n                    set (File "${File}/${BI}")\n                    math (EXPR I "${I} + 1")\n                endwhile (I LESS DeepFile)\n            endif (AI STREQUAL BI)\n        endwhile (I LESS DeepDirectory)\n    endif (Directory STREQUAL CMAKE_CURRENT_SOURCE_DIR)\n    set (${Artifacts} ${${Artifacts}} "${File}${Suffix}")\nendforeach (File)\nendmacro (determine_coverage_data)\n
Run Code Online (Sandbox Code Playgroud)\n\n

完整的解决方案如下所示:

\n\n
\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 cmake\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 UseGCov.cmake\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 CMakeLists.txt\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 src\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 logic.cpp\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 logic.h\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 test\n    \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 CMakeLists.txt\n    \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 logic_test.cpp\n
Run Code Online (Sandbox Code Playgroud)\n\n

主要CMakeLists.txt文件是:

\n\n
cmake_minimum_required (VERSION 2.8)\nproject (Logic)\nset (Logic_SOURCES ${PROJECT_SOURCE_DIR}/src/logic.cpp)\n# Include macro.\ninclude ("${PROJECT_SOURCE_DIR}/cmake/UseGCov.cmake")\ninclude_directories (${PROJECT_SOURCE_DIR}/src)\nadd_library (logic SHARED ${Logic_SOURCES})\nadd_subdirectory (test)\n
Run Code Online (Sandbox Code Playgroud)\n\n

对于CMakeLists.txt测试来说是:

\n\n
find_package (GTest)\n\nset (Test_SOURCES ${Logic_SOURCES} ${PROJECT_SOURCE_DIR}/test/logic_test.cpp)\nset (TestName logic_test)\n\nset (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O0 -g -march=native -mtune=native -fprofile-arcs -ftest-coverage")\nset (CMAKE_EXE_LINKER_FLAGS "-fprofile-arcs -ftest-coverage")\n\n# Call macro.\ndetermine_coverage_data ("${Test_SOURCES}" "${TestName}" Test_GCNOS ".gcno")\ndetermine_coverage_data ("${Test_SOURCES}" "${TestName}" Test_GCDAS ".gcda")\n\nset (Coverage_REPORT ${PROJECT_BINARY_DIR}/coverage.info)\nset (Coverage_DIR    ${PROJECT_BINARY_DIR}/coverage)\nadd_custom_command (\n    OUTPUT  ${Coverage_REPORT}\n    COMMAND lcov -q -c -f -b . -d ${PROJECT_BINARY_DIR}/test -o ${Coverage_REPORT}\n    COMMAND lcov -e ${Coverage_REPORT} \'${PROJECT_SOURCE_DIR}/src/*\' -o ${Coverage_REPORT}\n    COMMAND genhtml ${Coverage_REPORT} --legend --demangle-cpp -f -q -o ${Coverage_DIR}\n    DEPENDS logic_test\n)\nadd_custom_target (coverage DEPENDS ${Coverage_REPORT})\n\nset (Test_COVERAGE_DATA ${Coverage_REPORT} ${Coverage_DIR} ${Test_GCNOS} ${Test_GCDAS})\nset_directory_properties (PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "${Test_COVERAGE_DATA}")\nadd_executable (${TestName} ${Test_SOURCES})\ntarget_link_libraries (${TestName} gtest gtest_main gcov pthread)\n
Run Code Online (Sandbox Code Playgroud)\n