Clang-Tidy在CI中默认退出码恒为0,即使报告error,需显式加--warnings-as-errors="*"或脚本grep "error:"后exit 1来强制失败,否则构建“假装健康”。

Clang-Tidy 在 CI 中不报错 ≠ 没问题,而是默认把所有诊断当警告处理,退出码恒为 0 —— 这会让构建流程“假装健康”,完全失去拦截能力。
CI 中 clang-tidy 退出码始终是 0?必须显式触发失败
Clang-Tidy 默认行为是报告诊断(warning/error),但不改变进程退出码。CI 脚本看到 exit code 0 就认为成功,哪怕输出里全是 error: 行。
- 强制升为错误:加
--warnings-as-errors="*",所有匹配规则的诊断都导致非零退出码 - 更稳妥组合:
--warnings-as-errors="*"+--fix-errors+--format-style=none,避免格式化失败干扰判断 - 脚本兜底检查(推荐):用
grep -q "error:"判断输出,命中则exit 1,不依赖工具自身退出逻辑
找不到 compile_commands.json?-p 参数路径必须精确匹配
clang-tidy -p build/ src/*.cpp 报 “No compilation database found” 不是因为文件不存在,而是 -p 后指定的目录下没有 compile_commands.json,或该 JSON 里记录的源文件路径与你传入的 src/*.cpp 不一致(比如路径是 ../src/main.cpp)。
- CMake 项目务必在构建目录执行生成命令:
cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON .. && ninja,确保compile_commands.json在build/下 - CI 中
-p必须指向含该文件的**绝对路径**,相对路径易受工作目录影响;GitLab CI 可写-p "$CI_PROJECT_DIR/build/" - 验证是否生效:运行
clang-tidy -p build/ --list-files,应列出所有被识别的源文件
cppcoreguidelines-* 规则不生效?clang-tidy 不内置 CppCoreCheck
你在 .clang-tidy 里写了 cppcoreguidelines-* 却没任何输出?这不是配置错了,而是 clang-tidy 社区版对 C++ Core Guidelines 的支持是模拟实现,不是微软原生 CppCoreCheck,且默认禁用。
- 确认是否加载:
clang-tidy -list-checks | grep cppcoreguidelines,无输出说明模块未启用 - 启用方式只有两种:
-checks="cppcoreguidelines-*"命令行显式指定,或在.clang-tidy中写Checks: "-*,cppcoreguidelines-*" - 部分规则(如
cppcoreguidelines-pro-bounds-array-to-pointer-decay)依赖-extra-arg=-std=c++17等参数,否则 AST 解析不全,直接跳过检查
CI 构建卡住或超时?检查项太多 + 头文件爆炸是主因
启用 readability-* 或全量 * 后,clang-tidy 在 CI 中跑 20 分钟还不出结果,大概率是它在反复解析第三方头文件(如 Boost、Eigen),而非你的代码。
- 用
HeaderFilterRegex限制作用域:HeaderFilterRegex: '^(include|src)/',只检查项目自有头文件 - CI 中禁用耗时检查:移除
readability-identifier-naming(需遍历全部符号表)、cppcoreguidelines-pro-type-vararg(模板实例化爆炸) - 大型项目优先启用
bugprone-*和performance-*,它们直指空指针解引用、忽略返回值、不必要的拷贝等真实风险点
最常被忽略的一点:CI 中 clang-tidy 的工作目录、-p 路径、源文件 glob 模式三者必须严格对齐,差一个 ../ 或大小写,就静默跳过所有检查——它不会报错,只会安静地什么也不做。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











