You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 02:50:24