为什么g ++找不到-I include-path中的预编译头?

nih*_*hit 8 g++ precompiled-headers pch

我正在尝试构建一个预编译的标头和一个可执行文件,如下所示:

g++ -g -Wall -std=c++17 \
    -c ./src/pch.hpp -o ./build/pch.hpp.gch

g++ -g -Wall -std=c++17 \
        -c ./src/*.cpp  \
        -I./build/ -include pch.hpp
Run Code Online (Sandbox Code Playgroud)

pch.hpp.gch文件被正确地创建。但是对于每个.cpp文件,我都会收到以下错误:

1 error generated.
<built-in>:1:10: fatal error: 'pch.hpp' file not found
#include "pch.hpp"
Run Code Online (Sandbox Code Playgroud)

我认为根据gcc Precompiled Headers文档,我的编译行是正确的:

  • -I./build/告诉它将build目录添加到include搜索路径。
  • -include pch.hpp#include <pch.hpp>每个文件前添加指令。
  • 编译器.gch为其每个#include指令搜索带后缀的预编译头。

为什么我的编译行无法按预期运行?


我尝试过的某些方法确实可以给我带来更好的结果,但对我来说看起来并不正确。

如果我修改include来搜索.gch文件,则会找到该文件,与我期望的一致。即-include pch.hpp.gch,而不是-include pch.hpp
但是随后,PCH被解释为二进制文件,并且编译失败:

g++ -g -Wall -std=c++17 \
        -c ./src/*.cpp  \
        -I./build/ -include pch.hpp.gch
./build/pch.hpp.gch:2:22: error: source file is not valid UTF-8
Run Code Online (Sandbox Code Playgroud)

我不奇怪#include <pch.hpp.gch>它不会编译。但是我之所以提到这一点,是因为它似乎表明在我的原始命令build中搜索了该文件夹(正如我期望的那样),但是知道使用该.gch文件而不是常规标头的机制并未处于活动状态。奇怪的。

或者,如果我将src文件夹添加到标题搜索路径,则可以使用:

g++ -g -Wall -std=c++17 \
        -c ./src/*.cpp  \
        -I./src/ -I./build/ -include pch.hpp
Run Code Online (Sandbox Code Playgroud)

我不明白为什么添加另一个不相关的包含路径可以解决任何问题。奇怪的。


我当前的工作解决方案是完全删除-Iinclude-path指令,并指定以下更完整的路径build/pch.hpp

g++ -g -Wall -std=c++17 \
        -c ./src/*.cpp  \
        -include ./build/pch.hpp
Run Code Online (Sandbox Code Playgroud)

这一工作正常。不过,我不确定为什么有必要这样做,而且这很奇怪而且很不方便。

这是应该使用PCH的方式吗?为什么我的原始行不起作用,我打算做什么?

And*_*SFT 7

文档中

当在编译中看到#include时,将搜索预编译的头文件。在搜索包含文件时(请参见C预处理程序中的搜索路径),编译器会在每个目录中查找包含文件之前,先在每个目录中查找预编译的标头。搜索的名称是在#include中添加“ .gch”的名称。如果无法使用预编译的头文件,则将其忽略。

例如,如果您具有#include "all.h",并且all.h.gch与all.h在同一目录中,那么将在可能的情况下使用预编译的头文件,否则将使用原始头。

这意味着编译器在构建cpp时必须能够同时找到h文件和gch文件。因此,它们都应该在相同的目录或相同的包含搜索路径中。