简体   繁体   English

VSCode clangd 扩展找不到头文件

[英]VSCode clangd extension can not find header file

My current file structure is:我当前的文件结构是:

├── common
│   └── example.cc
├── compile_commands.json
├── include
    └── common
        └── example.hh

example.hh : Leave it blank example.hh :留空

example.cc : example.cc

#include "common/example.hh"

int main() {
    return 0;
}

compile_commands.json : compile_commands.json

[
    {
        "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"
    }
]

When opening example.cc it produces error:打开example.cc时会产生错误:

'common/example.hh' file not found clang(pp_file_not_found)

I run the command directly and it works fine:我直接运行命令,它工作正常:

$ /usr/bin/clang++ -I /home/user/project/include -o example /home/user/project/common/example.cc

Environment info:环境信息:

$ clang++ --version
clang version 10.0.0-4ubuntu1 
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/bin

vscode: 1.47.3 VS代码:1.47.3

vscode-clangd: 0.1.7 vscode-clangd:0.1.7

The problem is that in the "arguments" field of the compile_commands.json entry, "-I /home/user/project/include" is a single argument.问题是在compile_commands.json条目的"arguments"字段中, "-I /home/user/project/include"是一个参数。 (So is "-o example" though that doesn't cause any harm in this case.) "-o example"也是如此,尽管在这种情况下不会造成任何伤害。)

That means the command that's executed will be as if you had written:这意味着执行的命令就像你写的一样:

$ /usr/bin/clang++ "-I /home/user/project/include" "-o example" /home/user/project/common/example.cc

(note the quotes around "-I /home/user/project/include" and "-o example" ). (注意"-I /home/user/project/include""-o example"周围的引号)。

If you run that command, that gives the same 'common/example.hh' file not found clang(pp_file_not_found) error.如果您运行该命令,则会给出相同'common/example.hh' file not found clang(pp_file_not_found)错误。 Basically, the quotes make clang think that the argument to -I starts with a space character, which then does not resolve as a path.基本上,引号使 clang 认为-I的参数以空格字符开头,然后不会解析为路径。

The solution is to place each token of the command line in a separate element of "arguments" :解决方案是将命令行的每个标记放在"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"
    }
]

The reason "arguments" is interpreted in this way is that the format specification for compile_commands.json describes "arguments" as follows:以这种方式解释"arguments"的原因是compile_commands.json格式规范描述"arguments"如下:

arguments: The compile command argv as list of strings. arguments:编译命令 argv 作为字符串列表。 This should run the compilation step for the translation unit file .这应该运行翻译单元file的编译步骤。 arguments[0] should be the executable name, such as clang++ . arguments[0]应该是可执行文件名,例如clang++ Arguments should not be escaped, but ready to pass to execvp() .参数不应该被转义,而是准备传递给execvp()

Basically, "arguments" are expected to be the command line arguments as a shell would parse them and pass them to the argv of a program.基本上, "arguments"应该是命令行参数,因为 shell 会解析它们并将它们传递给程序的argv Since arguments are space-separated, the only way a single argument can contain an internal space is if that argument was quoted on the command line.由于参数是空格分隔的,因此单个参数可以包含内部空格的唯一方法是该参数是否在命令行中被引用。


Finally, I'll note that compile_commands.json files are generally not meant to be written by hand, but instead generated by a tool (usually your project's build system or something related).最后,我要注意compile_commands.json文件通常不是手动编写的,而是由工具生成的(通常是您项目的构建系统或相关的东西)。 See https://clangd.llvm.org/installation#project-setup for a list of commonly used tools to generate them.有关生成它们的常用工具列表,请参阅https://clangd.llvm.org/installation#project-setup

If you must hand-write a compile_commands.json , it's probably easier to use "command" instead of "arguments" (refer to thespec for an example), precisely to avoid issues like this.如果您必须手动编写compile_commands.json ,使用"command"而不是"arguments"可能更容易(请参阅规范以获取示例),正是为了避免此类问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM