让 Clangd 支持 GCC 的 C++23 Std Module
本文主要记录在 Arch Linux 上使用 GCC 15.2.1 编译器编译包含 import std; 的 C++23 标准模块(std module)代码时,如何让 Clangd 正常工作——即 import std; 不再被标记为红色波浪线提示“Module 'std' not found”,并且能够正常提供其中符号的悬停(Hover)提示。
使用的工具版本如下:
- GCC: 15.2.1
- Clangd: 22.0.0git def8ecbda9f146d5ba5bbc8c92f7d5ccd242ad2b
- VS Code: 1.106.1
- VS Code 中的 Clangd 插件: 0.2.0
- Bear: 3.1.6
如你所见,Clangd 官方目前最新的稳定版本是 21.1.6,但本次实验需自行从 Git 仓库编译开发中的 22.0.0 版本。实测表明,21.x 版本容易出现部分源代码文件中的符号无法正常解析的问题。
VS Code 的 C++ 插件使用的是 Clangd(LLVM)。Microsoft 官方的 C/C++ 插件表现如何,可自行尝试。
首先,我们创建一个最小可行项目。运行以下命令:
将系统中 GCC 提供的两个用于 C++23 标准模块的关键文件复制到当前目录。
接着新建一个 main.cpp 文件,内容如下:
并编写对应的 Makefile:
CXX := /usr/bin/g++
CXXFLAGS := -std=c++26 -fmodules
STDCC := std.cc
STDCOMPATCC := std.compat.cc
main: gcm.cache/std.gcm gcm.cache/std.compat.gcm main.cpp
$(CXX) $(CXXFLAGS) -o main main.cpp
gcm.cache/std.gcm: $(STDCC)
$(CXX) $(CXXFLAGS) -c -o std.o $(STDCC)
gcm.cache/std.compat.gcm: $(STDCOMPATCC)
$(CXX) $(CXXFLAGS) -c -o std.compat.o $(STDCOMPATCC)
.PHONY: clean
clean:
rm -rf .cache gcm.cache main *.o compile_commands.json
下一步,使用 Bear 生成 compile_commands.json,同时尝试编译,运行:
这会在当前目录下生成 compile_commands.json 文件,该文件将被 Clangd 识别并使用。同时会编译源文件。正常情况下应无报错,当前目录下会生成 std.o、std.compat.o、main 和 gcm.cache/ 目录。Make 实际执行了以下命令:
/usr/bin/g++ -std=c++26 -fmodules -c -o std.o std.cc
/usr/bin/g++ -std=c++26 -fmodules -c -o std.compat.o std.compat.cc
/usr/bin/g++ -std=c++26 -fmodules -o main main.cpp
接着,新建 .clangd 配置文件,内容如下:
If:
PathMatch: [.*\.h, .*\.cpp]
CompileFlags:
Add: [-std=c++26, -fmodules, -Xclang, -fbuiltin-headers-in-system-modules]
Compiler: g++
在 VS Code 中按 Ctrl+, 打开设置,搜索 “clangd”,找到 “Clangd: Arguments” 选项,添加以下两条参数:
如果你确实自行编译了 Clangd 22.0.0,可能还需要修改 “Clangd: Path” 设置,将其指向你编译出的 Clangd 可执行文件路径。
此时,用 VS Code 打开 main.cpp,应该会看到 import std; 下的红色波浪线已经消失,将光标悬停在 cout 上时,也能正常显示悬停提示框。
以下是一些可能出现的常见问题:
- 请确保
compile_commands.json中包含正确的内容,而不是只有[]。这可以通过执行make clean; make来解决。 - 请确保确实将系统目录中的
std.cc和std.compat.cc这两个文件复制到了当前目录中,而不是在 Makefile 中直接引用系统路径下的文件,否则可能导致 Clangd 解析失败。 - 请确保 Clangd 能读取到的
.clangd配置文件中,CompileFlags已正确添加了-fmodules、-Xclang和-fbuiltin-headers-in-system-modules这几个选项,特别是最后一个。否则可能在 Clangd 日志中看到与inttypes.h相关的报错。 - 请确保在 VS Code 的 Clangd 插件设置中已添加
--experimental-modules-support参数,否则 Clangd 可能在多次重启失败后自动停止运行。
希望这篇文章对你有所帮助!如果你仍有疑问,欢迎通过电子邮件等方式与我分享你的实验经历。