解决 Clangd 中 OpenCV 头文件报错
工欲善其事,必先利其器。
现象
当光标悬浮到 opencv2/opencv.hpp
上的时候,会得到如下报错:
xmmintrin.h In included file: definition of builtin function '_mm_getcsr'
虽然这个问题无关痛痒,因为 clangd 关于 cv 的提示仍然可以使用,但是使用 OpenCV 的文件就会被标红,对于我这样的强迫症来说,这是非常难以接受的。
解决过程
刚开始查网上资料,网友对此的解释是 gcc 的库 clang 识别不了,大家的解决方式是修改 clangd 配置的,尝试使用 Disagnostics 的 Suppress 功能抑制 builtin_definition 的报错提示,然后对于我的情况而言,这样是行不通的,于是这件事一直被耽搁了。
突然有一天,我发现当 clangd 读不到 compile_commands.json
的时候,根据我 Fallback Flags 的配置 1
2
3
4-I/opt/ros/noetic/include
-I/usr/include/eigen3
-I/usr/include/pcl-1.10
-I/usr/include/opencv4
结果可以发现,默认情况下 clangd 使用的编译器是 /usr/bin/clang,尽管我甚至没有装 clang,这个目录也是没有任何东西的,而从 compile_commands.json 中得到的编译器是 /usr/bin/c++。
再仔细研究一下我发现,在使用 /usr/bin/clang
这个虚空编译器的时候,xmmintrin.h
被导航到的目录不再是 gcc
下的 include 中,而是
/usr/lib/llvm-12/lib/clang/12.0.0/include/xmmintrin.h
,即
clangd 的库中。一看,发现这个 clang 和 gcc
下的这个文件有着不同的实现,那大抵能够解释了。
解决方案
直接在 clangd.arguments 中,设置 --query_driver=/usr/bin/clang 即可。
此外,为了能够进入 OpenCV 头文件后还能够正常导航,我们需要在 $HOME/.config/clangd/config.yaml 的 CompileFlag 中加入 -I/usr/include/opencv4。
思考
很多事情其实通过自己的思考是可以解决的,当某些东西在网上几乎查不到解决方案的时候,不妨试着自己去做做。
clangd 究竟是如何编译文件的呢?为何我使用的虚空编译器也能正常让其运作?