VSCode clangd 扩展找不到头文件

Phi*_*hil 7 clang clang++ visual-studio-code clangd

我目前的文件结构是:

??? common
?   ??? example.cc
??? compile_commands.json
??? include
    ??? common
        ??? example.hh
Run Code Online (Sandbox Code Playgroud)

example.hh: 留空

example.cc

??? common
?   ??? example.cc
??? compile_commands.json
??? include
    ??? common
        ??? example.hh
Run Code Online (Sandbox Code Playgroud)

compile_commands.json

#include "common/example.hh"

int main() {
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

打开example.cc它会产生错误:

'common/example.hh' file not found clang(pp_file_not_found)
Run Code Online (Sandbox Code Playgroud)

我直接运行命令,它工作正常:

[
    {
        "directory": "/home/user/project",
        "file": "/home/user/project/common/example.cc",
        "arguments": [
            "/usr/bin/clang++",
            "-I /home/user/project/include",
            "-o example",
            "/home/user/project/common/example.cc"
        ],
        "output": "example"
    }
]
Run Code Online (Sandbox Code Playgroud)

环境信息:

$ clang++ --version
clang version 10.0.0-4ubuntu1 
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/bin
Run Code Online (Sandbox Code Playgroud)

vscode:1.47.3

vscode-clangd:0.1.7

HC4*_*ica 2

问题在于,在"arguments"条目字段中compile_commands.json"-I /home/user/project/include"是单个参数。(虽然"-o example"在这种情况下这不会造成任何伤害。)

这意味着执行的命令就像您编写的那样:

$ /usr/bin/clang++ "-I /home/user/project/include" "-o example" /home/user/project/common/example.cc
Run Code Online (Sandbox Code Playgroud)

"-I /home/user/project/include"(注意和周围的引号"-o example")。

如果您运行该命令,则会出现相同的'common/example.hh' file not found clang(pp_file_not_found)错误。基本上,引号使 clang 认为参数以-I空格字符开头,然后该空格字符不会解析为路径。

解决方案是将命令行的每个标记放置在 的单独元素中"arguments"

[
    {
        "directory": "/home/user/project",
        "file": "/home/user/project/common/example.cc",
        "arguments": [
            "/usr/bin/clang++",
            "-I",
            "/home/user/project/include",
            "-o",
            "example",
            "/home/user/project/common/example.cc"
        ],
        "output": "example"
    }
]
Run Code Online (Sandbox Code Playgroud)

之所以"arguments"这么解释是因为格式规范描述如下:compile_commands.json"arguments"

参数:编译命令 argv 作为字符串列表。这应该运行翻译单元的编译步骤filearguments[0]应该是可执行文件的名称,例如clang++. 参数不应被转义,而应准备好传递给execvp()

基本上,"arguments"预期是命令行参数,因为 shell 会解析它们并将它们传递给argv程序。由于参数是用空格分隔的,因此单个参数可以包含内部空格的唯一方法是在命令行上引用该参数。


最后,我要指出的是,compile_commands.json文件通常不是手工编写的,而是由工具(通常是项目的构建系统或相关的东西)生成的。有关生成它们的常用工具的列表,请参阅https://clangd.llvm.org/installation#project-setup 。

如果您必须手写 a compile_commands.json,那么使用它可能"command"更容易"arguments"(请参阅规范的示例),从而避免出现此类问题。