使用 makefile 构建时 GCC 不使用预编译头

dis*_*nes 3 c++ gcc makefile precompiled-headers

我正在尝试将预编译头与 GCC 一起使用来加快编译过程。如果我直接从命令行启动编译,则会使用预编译头,但如果我尝试使用 makefile 来组织编译,则不会使用预编译头。

更具体地说,我尝试使用 GCC 8.1.0 编译文件main.cpp,使用预编译标头lib.hpp.gch作为 main.cpp 中的第一个标记包含的文件lib.hpp

lib.hpp 预编译为

$ g++ -O2 -H -Wall -std=c++17 -c lib.hpp
Run Code Online (Sandbox Code Playgroud)

然后编译 main.cpp

$ g++ -O2 -H -Wall -std=c++17 -c main.cpp -o main.o
! lib.hpp.gch
...
Run Code Online (Sandbox Code Playgroud)

我可以从“!”中看到 实际使用的是预编译的 lib.hpp.gch。

如果我为此编写一个 makefile

CXX = g++
CXXFLAGS = -O2 -H -Wall -std=c++17

main.o: \
    main.cpp \
    main.hpp \
    lib.hpp
    $(CXX) $(CXXFLAGS) \
    -c main.cpp \
    -o main.o
Run Code Online (Sandbox Code Playgroud)

然后使用 make,我希望预编译头的用法相同

但它失败了,从“x”可以看出:

$ make
g++ -O2 -H -Wall -std=c++17 \
    -c main.cpp \
    -o main.o
x lib.hpp.gch
...
Run Code Online (Sandbox Code Playgroud)

这很奇怪,因为make发出的命令看起来和我之前手动使用的命令一模一样。

我还测量了时间,并且可以确认通过 make 进行的编译肯定比手动编译慢,从而确认未使用预编译头。

makefile 有什么问题?

Cin*_*its 7

您没有在 make 命令中的任何位置包含 PCH。尝试这个:

CXX = g++
CXXFLAGS = -O2 -H -Wall -std=c++17
OBJ = main.o #more objects here eventually I would think!

PCH_SRC = lib.hpp
PCH_HEADERS = headersthataregoinginyourpch.hpp andanother.hpp
PCH_OUT = lib.hpp.gch

main: $(OBJ) 
     $(CXX) $(CXXFLAGS) -o $@ $^

# Compiles your PCH
$(PCH_OUT): $(PCH_SRC) $(PCH_HEADERS)
     $(CXX) $(CXXFLAGS) -o $@ $<

# the -include flag instructs the compiler to act as if lib.hpp
# were the first header in every source file
%.o: %.cpp $(PCH_OUT)
    $(CXX) $(CXXFLAGS) -include $(PCH_SRC) -c -o $@ $<
Run Code Online (Sandbox Code Playgroud)

首先编译 PCH。然后所有 cpp 命令都会被编译,并-include lib.hpp保证在之前lib.hpp.gch总是先被搜索 lib.hpp

  • `-include` 标志使编译器在 `precompile.h` 之前搜索 *`precompile.h.gch`* 如您所见,使用 `gcc` 直接编译会产生相同的结果,因为它总是首先搜索 PCH像这样使用,当从 `make` 调用 `gcc` 时情况并非如此,在其他编译器如 `clang` 中也不是这样,除非指定 `-include`,否则不会搜索 PCH。 (2认同)