为什么g++找不到在-I包含路径中的预编译头文件?

11

我正在尝试构建预编译头文件和可执行文件,方法如下:

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

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

1 error generated.
<built-in>:1:10: fatal error: 'pch.hpp' file not found
#include "pch.hpp"

根据gcc预编译头文件文档,我认为我的编译行正确:

  • -I./build/告诉GCC将build目录添加到包含搜索路径中。
  • -include pch.hpp在每个文件开头添加一个#include <pch.hpp>预处理指令。
  • 编译器为每个#include指令搜索带有.gch后缀的预编译头文件。

为什么我的编译行没有按预期工作呢?


我尝试了一些东西,可以让我得到更好的结果,但它们看起来不正确。

如果将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

我不感到惊讶#include <pch.hpp.gch>无法编译。但我提到这一点是因为它似乎表明在我的原始命令中,build文件夹被搜索(正如我所预期的那样),但知道使用.gch文件而不是常规头文件的机制不起作用。奇怪。

另外,如果我将src文件夹添加到头文件搜索路径中,则可以正常工作:

g++ -g -Wall -std=c++17 \
        -c ./src/*.cpp  \
        -I./src/ -I./build/ -include pch.hpp

我不理解为什么添加一个与主题无关的另一个包含路径会解决任何问题。奇怪。


我的当前解决方案是完全删除-I包含路径指令,并且指定一个更完整的路径到build/pch.hpp:

g++ -g -Wall -std=c++17 \
        -c ./src/*.cpp  \
        -include ./build/pch.hpp

这个功能正常运作。虽然我不确定为什么需要它,而且它很奇怪和不方便。

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

1个回答

10
根据文档,当编译器遇到#include指令时,它会搜索预编译头文件。在查找包含文件(见C预处理器中的搜索路径)时,编译器会在每个目录中查找预编译头文件,这发生在它在该目录中查找包含文件之前。所查找的名称是在#include中指定的名称,并附加“.gch”。如果不能使用预编译头文件,则忽略它。
例如,如果您有#include "all.h",并且您在与all.h相同的目录中有all.h.gch,则尽可能使用预编译头文件,否则使用原始头文件。
这意味着编译器在构建cpp时必须能够同时找到h文件和gch文件。因此,它们应该在同一目录或相同的包含搜索路径中。

1
那么为什么当我使用 -include ./build/pch.hpp 没有额外的搜索路径时,编译器找不到原始头文件,但它仍然可以工作呢? - nihohit
1
你的第二个选项是完全跳过预编译头文件。编译器将pch.hpp作为典型的头文件包含进来。 - Andrey Chistyakov

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接