如何配置Clang执行代码诊断时忽略第三方库、自动生成代码等指定目录
问题背景
使用catkin-tools搭配Clang构建C++项目时,配置的-Werror -Wall -Wextra -Wfloat-equal等编译诊断参数会同时扫描三类代码:自有业务代码、第三方依赖代码、构建自动生成代码。需求是仅对自有代码执行强诊断规则,触发规则直接终止构建,跳过以下三个路径的诊断检查:
/usr/include/eigen3/opt/ros/melodic~/ws/src/devel/
此前尝试通过-isystem=/usr/include/eigen3/标记系统头文件路径未生效,且-Wfloat-equal属于Clang原生编译诊断规则,不属于clang-tidy的检查项范围,无法通过.clang-tidy文件的HeaderFilterRegex配置过滤。
具体配置步骤
1. 修正-isystem参数写法
此前配置失效的核心原因是参数写法错误:Clang的-isystem参数与路径之间不能加等号,必须用空格分隔。将所有第三方系统依赖路径都通过-isystem标记后,Clang会默认跳过这些路径下所有普通编译警告,不会触发-Werror中断构建。
2. 配置catkin的cmake参数
修改catkin配置文件中的cmake_args段,完整配置如下:
cmake_args: # 基础诊断规则,仅对非系统头文件路径生效 - -DCMAKE_CXX_FLAGS=-Werror -Wall -Wextra -Wfloat-equal -Wno-system-headers # 标记需要跳过诊断的系统级依赖路径 - -DCMAKE_CXX_FLAGS=-isystem /usr/include/eigen3 - -DCMAKE_CXX_FLAGS=-isystem /opt/ros/melodic # 标记构建自动生成的devel目录为系统路径,跳过诊断 - -DCMAKE_CXX_FLAGS=-isystem ${CMAKE_BINARY_DIR}/../devel
注:
${CMAKE_BINARY_DIR}是CMake内置变量,指向当前工作空间的build目录,通过相对路径定位devel目录可以适配不同的工作空间路径,不需要写死用户目录。如果配置后路径识别异常,可以替换为devel目录的绝对路径。
3. 特殊场景兜底方案
如果自动生成的代码文件即使放在-isystem标记的路径下仍然触发警告,可以在代码生成模板的头部添加如下宏指令:
#pragma clang system_header
添加该宏的文件会被Clang识别为系统头文件,自动跳过所有普通编译警告检查,不需要每次生成代码后手动修改。
原理说明
clang-tidy的HeaderFilterRegex仅对clang-tidy执行的静态检查规则生效,-Wfloat-equal这类参数是Clang编译阶段直接触发的原生诊断,不经过clang-tidy的检查流程,因此必须通过Clang编译参数层面的系统头文件标记规则实现目录过滤。
内容的提问来源于stack exchange,提问作者Westranger

