如何通过CMake实现跨编译器禁用测试可执行文件的覆盖率标志?
跨编译器禁用测试可执行文件覆盖率标志的方案
方案1:移除测试目标的覆盖率编译/链接标志
CodeCoverage.cmake通常会给所有目标全局添加--coverage(GCC/Clang)或/Profile(MSVC)这类覆盖率标志,我们可以单独针对tests目标移除这些标志:
if(ENABLE_COVERAGE) # 先引入CodeCoverage模块并完成基础配置 include(CodeCoverage.cmake) setup_target_for_coverage_lcov( NAME coverage_report EXECUTABLE tests # 其他参数根据你的项目调整 ) # 识别当前编译器对应的覆盖率标志 if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang") set(COVERAGE_FLAG "--coverage") elseif(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") set(COVERAGE_FLAG "/Profile") endif() # 移除测试目标的编译标志 get_target_property(tests_compile_flags tests COMPILE_FLAGS) string(REPLACE "${COVERAGE_FLAG}" "" tests_compile_flags "${tests_compile_flags}") set_target_properties(tests PROPERTIES COMPILE_FLAGS "${tests_compile_flags}") # 移除测试目标的链接标志 get_target_property(tests_link_flags tests LINK_FLAGS) string(REPLACE "${COVERAGE_FLAG}" "" tests_link_flags "${tests_link_flags}") set_target_properties(tests PROPERTIES LINK_FLAGS "${tests_link_flags}") endif()
注意:要确保这段代码放在引入CodeCoverage.cmake之后,避免被模块的全局设置覆盖。
方案2:仅给业务代码目标添加覆盖率标志(更推荐)
其实测试代码本身不需要统计覆盖率,我们可以修改配置逻辑,只给你的业务库/代码目标添加覆盖率标志,而tests目标完全不接触这些标志:
if(ENABLE_COVERAGE) include(CodeCoverage.cmake) # 识别编译器对应的覆盖率标志 if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang") set(COVERAGE_FLAG "--coverage") elseif(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") set(COVERAGE_FLAG "/Profile") endif() # 仅给业务代码目标添加覆盖率标志(替换成你的实际库目标名) target_compile_options(your_business_library PRIVATE ${COVERAGE_FLAG}) target_link_options(your_business_library PRIVATE ${COVERAGE_FLAG}) # 配置覆盖率报告,排除测试代码目录 setup_target_for_coverage_lcov( NAME coverage_report EXECUTABLE tests DEPENDENCIES tests your_business_library EXCLUDE "${PROJECT_SOURCE_DIR}/tests/*" "${PROJECT_BINARY_DIR}/*" ) endif()
这个方案更合理,因为覆盖率报告本来就应该聚焦业务代码,测试代码的覆盖情况没有统计价值,同时从根源避免了给tests目标添加不必要的标志。
方案3:利用CMake目标属性控制标志继承
如果你的项目是业务代码作为库,tests通过target_link_libraries链接这个库,那么可以将覆盖率标志设为库的PRIVATE属性,这样tests目标不会继承这些标志:
if(ENABLE_COVERAGE) include(CodeCoverage.cmake) if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang") set(COVERAGE_FLAG "--coverage") elseif(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") set(COVERAGE_FLAG "/Profile") endif() # PRIVATE属性确保标志只作用于库自身,不传递给链接它的tests目标 target_compile_options(your_business_library PRIVATE ${COVERAGE_FLAG}) target_link_options(your_business_library PRIVATE ${COVERAGE_FLAG}) # 照常配置覆盖率报告 setup_target_for_coverage_lcov( NAME coverage_report EXECUTABLE tests ) endif()
内容的提问来源于stack exchange,提问作者Arnav Borborah
相关产品推荐
相关产品推荐

