如何将 SYSTEM headers 与 CMake 和 clang-tidy 一起使用?

How to use SYSTEM headers with CMake and clang-tidy?

我正在尝试在我的 CMake (3.17.1) 项目中使用 clang-tidy,但是它在 Catch2 测试库 header 上崩溃了。将 Catch2 设置为系统 header 似乎没有帮助。为 clang-tidy 调用的命令包含 Catch2 的路径作为系统包含目录,但仍会为其打印诊断信息。在尝试隔离它时,我发现这实际上不适用于 clang-tidy:

clang-tidy src.cpp -- -Isystem/Path/to/header

它导致 header 根本找不到。我在某处学到的(现在找不到)是让它实际上是 clang-tidy 的两个 --extra-arg 参数:

clang-tidy --extra-arg=-Isystem --extra-arg=/Path/to/header src.cpp

但这并不适用于任何地方。在 Windows 上我能够使它工作,但在 Linux 上它从未以任何形式工作(一起,分开,在 -- 之后)。如何将 -isystem header 与 Linux 上的 clang-tidy 一起使用?这是非常混乱和不一致的。此外,如何用 CMake 做到这一点?

我有这个:

cmake_minimum_required(VERSION 3.10)
set(CMAKE_CXX_CLANG_TIDY clang-tidy)

add_library(Catch2 STATIC Catch2/Catch2.cpp Catch2/include/Catch2/catch.hpp)
target_include_directories(Catch2 SYSTEM PUBLIC Catch2/include)

add_executable(SomeTest SomeTest/test.cpp)
target_link_libraries(Catch2)

生成的命令行相当复杂(为了可读性我自己包装了):

cmake 
-E __run_co_compile 
--tidy="clang-tidy-10;--extra-arg-before=--driver-mode=g++"
--source=../Sometest/test.cpp
-- 
/usr/bin/clang++-10
-isystem ../Catch2/include 
-g
-std=gnu++17
-MD
-MT CMakeFiles/SomeTest.dir/projects/SomeTest/test.cpp.o 
-MF CMakeFiles/SomeTest.dir/projects/SomeTest/FileTest.cpp.o.d 
-o CMakeFiles/SomeTest.dir/projects/SomeTest/test.cpp.o 
-c 
../projects/SomeTest/test.cpp

在输出中有来自 Catch2 的警告,因此包含中的 system 似乎被忽略了。我试图通过 CMAKE_CXX_CLANG_TIDY 属性:

强制 --extra-arg

set(CMAKE_CXX_CLANG_TIDY clang-tidy --extra-arg=-isystem --extra-arg=../Catch2/include)

但这似乎也无济于事。

我关注 your repro 发布在 LLVM bugtracker 上。

您做的一切都正确:即,将 Catch2 标记为 SYSTEM 的系统包含。 clang-tidy 的行为也正确:它只检查你的源文件 test.cpp 而没有完全检查 catch.hpp,只检查宏扩展。

问题是 Catch2 的版本过时了。 hicpp-vararg 警告已 silenced as of Catch2 2.12.2, so you need to update to at least that version. Moreover, apparently the core issue that hicpp-vararg reported upon has been fixed,此更改预计将出现在 clang-tidy 11 版本中。