我正在尝试构建预编译的标头和可执行文件,如下所示:
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 Precompiled Headers documentation,我认为我的编译行是正确的:
-I./build/
告诉它将build
目录添加到包含搜索路径。-include pch.hpp
在每个文件前附加一个#include <pch.hpp>
指令。.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
我不明白为什么添加另一个无关的include-path可以解决任何问题。很奇怪。
我当前的工作解决方案是完全删除-I
的include-path指令,并指定到build/pch.hpp
的更完整路径:
g++ -g -Wall -std=c++17 \
-c ./src/*.cpp \
-include ./build/pch.hpp
这一工作正常。不过,我不确定为什么有必要这样做,而且这很奇怪而且很不方便。
这是应该使用PCH的方式吗?为什么我的原始行不起作用,我打算做什么?
答案 0 :(得分:7)
当在编译中看到#include时,将搜索预编译的头文件。在搜索包含文件时(请参见C预处理器中的搜索路径),编译器将在每个目录中查找预编译头之前,先在该目录中查找包含文件。搜索的名称是#include中附加“ .gch”的名称。如果无法使用预编译的头文件,则将其忽略。
例如,如果您拥有
#include "all.h"
,并且all.h.gch与all.h位于同一目录中,那么将在可能的情况下使用预编译的头文件,否则将使用原始头。
这意味着编译器在构建cpp时必须能够同时找到h文件和gch文件。因此,它们都应该位于相同的目录或相同的包含搜索路径中。