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

如何通过CMake为多模块项目生成单份cppcheck/clang-tidy报告?

多模块CMake项目集成静态分析工具生成合并报告的解决方法

针对Cppcheck的解决思路

问题根源在于你当前的配置让每个模块运行cppcheck时都输出到同一个xml文件,后续模块的检查结果会直接覆盖前面的。有两种可行方案:

方案1:分模块生成报告后合并

  1. 修改CMake配置,让每个模块生成独立的xml报告,用模块名区分文件:
find_program(CMAKE_CXX_CPPCHECK NAMES cppcheck)
if (CMAKE_CXX_CPPCHECK)
    list(APPEND CMAKE_CXX_CPPCHECK
        "--enable=warning"
        "--inconclusive"
        "--force"
        "--inline-suppr"
        "--suppressions-list=${CMAKE_SOURCE_DIR}/CppCheckSuppressions.txt"
        "--xml"
        "--output-file=${CMAKE_BINARY_DIR}/cppcheck-${PROJECT_NAME}.xml"
    )
endif()

这里用${PROJECT_NAME}(每个子模块的项目名)作为报告文件名的一部分,确保每个模块的报告不冲突。

  1. 添加CMake自定义目标,用cppcheck自带的cppcheck-merge工具合并所有模块的报告:
find_program(CPPCHECK_MERGE NAMES cppcheck-merge)
if (CPPCHECK_MERGE)
    # 收集所有模块生成的cppcheck xml文件
    file(GLOB_RECURSE CPPCHECK_XML_FILES "${CMAKE_BINARY_DIR}/cppcheck-*.xml")
    # 创建合并报告的目标
    add_custom_target(cppcheck-merge ALL
        COMMAND ${CPPCHECK_MERGE} ${CPPCHECK_XML_FILES} --output=${CMAKE_SOURCE_DIR}/cppcheck-results.xml
        DEPENDS ${CPPCHECK_XML_FILES}
        COMMENT "合并所有模块的cppcheck报告"
    )
endif()

构建项目时,cppcheck-merge目标会自动执行,把所有模块的报告合并成一份最终的cppcheck-results.xml。如果不想自动执行,去掉ALL关键字,手动运行make cppcheck-merge或ninja cppcheck-merge即可。

方案2:直接扫描整个源码树生成单份报告

跳过按模块逐个检查的方式,直接通过CMake自定义命令对整个项目的源码运行一次cppcheck:

find_program(CPPCHECK NAMES cppcheck)
if (CPPCHECK)
    add_custom_target(cppcheck-all
        COMMAND ${CPPCHECK}
            --enable=warning
            --inconclusive
            --force
            --inline-suppr
            --suppressions-list=${CMAKE_SOURCE_DIR}/CppCheckSuppressions.txt
            --xml
            --output-file=${CMAKE_SOURCE_DIR}/cppcheck-results.xml
            ${CMAKE_SOURCE_DIR}/src  # 替换成你的源码根目录,多个目录用空格分隔
        COMMENT "对所有源码文件执行cppcheck静态分析"
    )
endif()

运行make cppcheck-all就能直接生成覆盖所有模块的单份报告,无需合并步骤。

针对Clang-Tidy的解决思路

Clang-Tidy遇到的问题和cppcheck一致,同样可以用分模块生成再合并,或者直接全量扫描的方式解决:

方案1:分模块生成后合并

  1. 配置每个模块生成独立的fix文件:
find_program(CMAKE_CXX_CLANG_TIDY NAMES clang-tidy)
if (CMAKE_CXX_CLANG_TIDY)
    set(CMAKE_CXX_CLANG_TIDY
        ${CMAKE_CXX_CLANG_TIDY}
        --export-fixes=${CMAKE_BINARY_DIR}/clang-tidy-${PROJECT_NAME}.yaml
        --config-file=${CMAKE_SOURCE_DIR}/.clang-tidy  # 你的clang-tidy配置文件路径
    )
endif()
  1. 用脚本合并多个fix文件。由于Clang-Tidy没有官方合并工具,可以写一个简单的Python脚本(命名为merge-clang-tidy.py):
import yaml
import sys

merged = {"Diagnostics": []}
# 遍历所有输入的yaml文件
for file_path in sys.argv[1:-1]:
    try:
        with open(file_path, 'r') as f:
            data = yaml.safe_load(f)
            if data and "Diagnostics" in data:
                merged["Diagnostics"].extend(data["Diagnostics"])
    except Exception as e:
        print(f"读取文件 {file_path} 失败: {e}", file=sys.stderr)

# 写入合并后的结果
with open(sys.argv[-1], 'w') as f:
    yaml.dump(merged, f)
  1. 在CMake中添加自定义目标执行合并:
add_custom_target(clang-tidy-merge ALL
    COMMAND python3 ${CMAKE_SOURCE_DIR}/merge-clang-tidy.py ${CMAKE_BINARY_DIR}/clang-tidy-*.yaml ${CMAKE_SOURCE_DIR}/clang-tidy-results.yaml
    DEPENDS ${CMAKE_BINARY_DIR}/clang-tidy-*.yaml
    COMMENT "合并所有模块的clang-tidy报告"
)

方案2:全量扫描生成单份报告

直接对所有源码文件运行Clang-Tidy:

find_program(CLANG_TIDY NAMES clang-tidy)
if (CLANG_TIDY)
    # 收集所有C++源码文件
    file(GLOB_RECURSE CPP_SOURCES 
        "${CMAKE_SOURCE_DIR}/src/*.cpp" 
        "${CMAKE_SOURCE_DIR}/src/*.h"
        # 可以添加更多需要扫描的文件类型或目录
    )
    add_custom_target(clang-tidy-all
        COMMAND ${CLANG_TIDY}
            ${CPP_SOURCES}
            --config-file=${CMAKE_SOURCE_DIR}/.clang-tidy
            --export-fixes=${CMAKE_SOURCE_DIR}/clang-tidy-results.yaml
            --
            ${CMAKE_CXX_FLAGS}
            -I${CMAKE_SOURCE_DIR}/include  # 添加项目的头文件搜索路径
            # 其他编译选项按需添加
        COMMENT "对所有源码文件执行clang-tidy静态分析"
    )
endif()

内容的提问来源于stack exchange,提问作者emes9

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 03:07:57