我只需要解决为什么 VSCode 扩展 clangd 在连接到远程工作区时无法正确找到嵌入式项目中的所有标头和链接的问题,所以我想其他人可能会发现这对于它的工作原理非常有用。我不是在问问题,而是给你答案,以防其他人遇到这个问题。 stackoverflow 上的其他一些线程帮助我解决了这个问题,但我想将所有内容作为一个大食谱放在一个地方很有用。
我正在使用 aarch64-linux-gnu-g++ 编译器开发一个 cmakelists.txt 项目。 为了让 clangd 扩展找到项目标头,需要让 clangd 知道 compilation_database.json,因此在 cmakelists.txt 中插入此代码以生成 compilation_database.json:
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
if(CMAKE_EXPORT_COMPILE_COMMANDS)
set(CMAKE_CXX_STANDARD_INCLUDE_DIRECTORIES ${CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES})
endif()
这将生成 compilation_database.json 并将隐式包含目录包含到 compilation_database.json 中。 由于 compilation_database.json 具有指向编译器的链接,在我的情况下,它位于 /compiler/elbe_sdk_x.x.x/sysroots/host/usr/bin/aarch64-linux-gnu-g++ 的某个固定位置,其中我对文件夹 /compiler 没有任何权限来添加最新版本的 elbe_sdk_x.x.x,我必须为本地版本的编译器调整 compilation_database.json /home/user/elbe_sdk/ sysroots/host/usr/bin/aarch64-linux-gnu-g++ 因此我将 compilation_database.json 复制到 /home/user/project/compilation_database.json 并替换了数据库内所有出现的固定编译器路径从 /compiler/elbe_sdk_x.x.x/sysroots/host/usr/bin/aarch64-linux-gnu-g++ 到我的本地编译器路径 /home/user/elbe_sdk/sysroots/host/usr/bin/aarch64-linux- gnu-g++ ( - 这里注意:每次 compiler_database.json 由于项目更改而发生更改时,都必须执行此操作,然后删除 /home/user/.config/clangd 文件夹并重新启动 VSCode,以便 clangd重新索引所有链接和标题)
现在继续 clangd 配置:将 VSCode clangd 扩展 settings.json 更改为
\"clangd.arguments\": [\"-log=verbose\",
\"-pretty\",
\"--background-index\",
\"--query-driver=/home/user/elbe_sdk/sysroots/host/usr/bin/aarch64-linux-gnu-g++\",
\"--compile-commands-dir=/home/user/project/\",
\"--all-scopes-completion\"]
因为我使用的编译器在 elf 中有固定的 rpath 和 interpreterpath
readelf -a /home/user/elbe_sdk/sysroots/host/usr/bin/aarch64-linux-gnu-g++
>>>
[...]
Requesting program interpreter: /compiler/elbe_sdk_x.x.x/sysroots/host/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
[...]
Library runpath: [/compiler/elbe_sdk_x.x.x/sysroots/host/usr/lib/x86_64-linux-gnu:/compiler/elbe_sdk_x.x.x/sysroots/host/lib/x86_64-linux-gnu/:/compiler/elbe_sdk_x.x.x/sysroots/host/usr/lib:/compiler/elbe_sdk_x.x.x/sysroots/host/lib]
[...]
因此无法由 clangd 的查询驱动程序函数调用,我使用
patchelf --set-rpath /home/user/elbe_sdk/sysroots/host/usr/lib/x86_64-linux-gnu:/home/user/elbe_sdk/sysroots/host/lib/x86_64-linux-gnu/:/home/user/elbe_sdk/sysroots/host/usr/lib:/home/user/elbe_sdk/sysroots/host/lib aarch64-linux-gnu-g++
patchelf --set-interpreter /home/user/elbe_sdk/sysroots/host/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2 aarch64-linux-gnu-g++
更改 rpath 和解释器路径以与我的本地编译器版本相对应。
现在 clangd 已经找到了一些包含、标头和引用,但由于 “fatal_too_many_errors” 而无法正确索引,可以通过添加 进行更改
CompileFlags:
Add: -ferror-limit=0
到 /home/user/.config/clangd/config.yaml (如果文件夹 /home/user/.config/clangd 不存在,请创建它并在其中创建 config.yaml,使用设置 ferror-limit 值,其中 0 表示 “无限制”)
最后但并非最不重要的一点是重新启动 VSCode 并让它重新索引所有文件(如果已经索引,请在重新启动之前删除上面提到的文件夹/home/user/.config/clangd)。您的包含和引用现在应该都已正确解析:)
clangd 的配置文件覆盖编译器,则可能可以省略查找/替换步骤,如下所示:
CompileFlags:
Compiler: /home/user/elbe_sdk/sysroots/host/usr/bin/aarch64-linux-gnu-g++