如何让CMake在修改测试代码时清理对应被测文件的旧覆盖率数据
解决CMake代码覆盖率中特定gcda文件的清理问题
问题场景
修改测试源文件(如TEST_Outputs.c)时,对应的测试可执行文件会重建并生成新的测试文件gcda,但被测源文件(如Outputs.c)未重建,其gcda文件会累积新旧测试数据,需要清理该文件但保留其他无关文件的gcda。
方案1:将对应gcda文件关联到测试目标,随目标重建自动清理
通过CMake属性设置,把被测源文件对应的gcda标记为测试目标的关联文件,让CMake在重建测试目标时自动清理旧数据。
修改CMakeLists.txt中的测试循环逻辑,添加gcda清理关联:
FOREACH(i RANGE ${count}) LIST(GET tests_names ${i} test_name) LIST(GET tests_filename ${i} test_filename) LIST(GET tests_flags ${i} test_flags) LIST(GET tests_mocks ${i} test_mocks) LIST(GET tests_srcdir ${i} test_srcdir) # 提取被测源文件名,构造对应gcda文件路径 get_filename_component(src_basename ${test_srcdir} NAME) set(gcda_file "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${test_name}.dir/__/${test_srcdir}.gcda") ADD_EXECUTABLE(${test_name} ${test_filename} ${test_mocks} ${CMAKE_CURRENT_SOURCE_DIR}/${test_srcdir}) TARGET_LINK_LIBRARIES( ${test_name} PRIVATE cmocka ${CMAKE_PROJECT_NAME} gcov ) set_target_properties( ${test_name} PROPERTIES LINK_FLAGS ${test_flags} ) # 将gcda加入目标清理列表 set_property(TARGET ${test_name} APPEND PROPERTY ADDITIONAL_MAKE_CLEAN_FILES "${gcda_file}") # 构建前强制删除旧gcda add_custom_command(TARGET ${test_name} PRE_BUILD COMMAND ${CMAKE_COMMAND} -E remove -f "${gcda_file}" COMMENT "Cleaning old coverage data for ${src_basename}" ) ADD_CMOCKA_TEST(${test_name} ${test_srcdir}) ENDFOREACH()
PRE_BUILD命令会在测试目标构建前删除对应gcda,确保每次测试生成全新的覆盖率数据。
方案2:在AddCmocka.cmake的自定义命令中定位并删除gcda
修改AddCmocka.cmake中的add_cmocka_test宏,直接在测试执行前定位并删除对应被测文件的gcda:
MACRO(add_cmocka_test executable_name source) add_test(NAME RunCTest${executable_name} COMMAND ${executable_name} WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} ) # 构造目标gcda文件的完整路径 set(gcda_file "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${executable_name}.dir/__/${source}.gcda") add_custom_command(TARGET ${executable_name} # 先清理旧gcda COMMAND ${CMAKE_COMMAND} -E remove -f "${gcda_file}" # 再执行测试 COMMAND ${executable_name} COMMENT "Running ${executable_name} with clean coverage data" ) ENDMACRO()
这种方式直接在测试执行环节前置清理操作,精准删除目标gcda,不影响其他文件的覆盖率数据。
注意事项
- 确保
gcda_file的路径与你的实际构建目录结构完全匹配,你的目录中gcda位于CMakeFiles/<test_name>.dir/__/<src_path>.gcda,路径构造需准确。 - 使用
${CMAKE_COMMAND} -E remove -f替代平台原生命令,保证跨平台兼容性。
内容的提问来源于stack exchange,提问作者Samuel Comeau
相关产品推荐
相关产品推荐

