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

C++ 使用makefile构建时,GCC不使用预编译头,c++,gcc,makefile,precompiled-headers,C++,Gcc,Makefile,Precompiled Headers,我正在尝试将预编译头与GCC一起使用,以加快编译过程。如果我直接从命令行启动编译,则会使用预编译头,但如果我尝试使用makefile组织编译,则不会使用预编译头 更具体地说,我尝试使用GCC 8.1.0编译一个文件main.cpp,使用一个预编译头lib.hpp.gch来编译文件lib.hpp,该文件包含在main.cpp中作为第一个标记 lib.hpp是用 $ g++ -O2 -H -Wall -std=c++17 -c lib.hpp $ g++ -O2 -H -Wall -std=c++

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

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

lib.hpp是用

$ g++ -O2 -H -Wall -std=c++17 -c lib.hpp
$ g++ -O2 -H -Wall -std=c++17 -c main.cpp -o main.o
! lib.hpp.gch
...
main.cpp然后使用

$ g++ -O2 -H -Wall -std=c++17 -c lib.hpp
$ g++ -O2 -H -Wall -std=c++17 -c main.cpp -o main.o
! lib.hpp.gch
...
我可以从“!”中看出,实际上使用了预编译的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
然后使用make,我希望预编译头的用法与make相同

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

这很奇怪,因为make发出的命令似乎与我以前手动使用的命令完全相同

我还对时间进行了测量,可以确认通过make进行的编译肯定比手动编译慢,确认没有使用预编译头


makefile中有什么问题?

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 $@ $<
CXX=g++
CXXFLAGS=-O2-H-Wall-std=c++17
OBJ=main.o#我想最终这里会有更多的对象!
PCH_SRC=lib.hpp
PCH_HEADERS=在您的PCH.hpp和另一个PCH.hpp中运行的HEADERS
PCH_OUT=lib.hpp.gch
main:$(OBJ)
$(CXX)$(CXXFLAGS)-o$@$^
#编译您的PCH
$(PCH\U OUT):$(PCH\U SRC)$(PCH\U标题)
$(CXX)$(CXXFLAGS)-o$@$<
#-include标志指示编译器像lib.hpp一样工作
#是每个源文件中的第一个头
%.o:%.cpp$(PCH_OUT)
$(CXX)$(CXXFLAGS)-包括$(PCH\U SRC)-c-o$@$<

首先编译PCH。然后使用
-include lib.hpp
编译所有cpp命令,这保证了
lib.hpp.gch
总是在
lib.hpp

之前先搜索
。试试这个:

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 $@ $<
CXX=g++
CXXFLAGS=-O2-H-Wall-std=c++17
OBJ=main.o#我想最终这里会有更多的对象!
PCH_SRC=lib.hpp
PCH_HEADERS=在您的PCH.hpp和另一个PCH.hpp中运行的HEADERS
PCH_OUT=lib.hpp.gch
main:$(OBJ)
$(CXX)$(CXXFLAGS)-o$@$^
#编译您的PCH
$(PCH\U OUT):$(PCH\U SRC)$(PCH\U标题)
$(CXX)$(CXXFLAGS)-o$@$<
#-include标志指示编译器像lib.hpp一样工作
#是每个源文件中的第一个头
%.o:%.cpp$(PCH_OUT)
$(CXX)$(CXXFLAGS)-包括$(PCH\U SRC)-c-o$@$<

首先编译PCH。然后使用
-include lib.hpp
编译所有cpp命令,这保证了
lib.hpp.gch
总是在
lib.hpp

之前先搜索
lib.hpp.gch?它的位置:
g++-O2-H-Wall-std=c++17-c lib.hpp
?实际上我并不是通过makefile来构建lib.hpp.gch,我是用开头显示的命令手动构建的,在make file中,您在哪里预编译头?它在哪里:
g++-O2-H-Wall-std=c++17-c lib.hpp
?实际上,我没有通过makefile构建lib.hpp.gch,我已经用开头显示的命令手动构建了它。我已经在makefile中添加了pch的编译,现在它可以工作了。但仍不清楚原因。make发出的命令不应该与直接从命令行发出的命令相同吗?编译makefile中的pch会有什么不同?我总是将lib.hpp作为.cpp文件中的第一个标记,因此这相当于使用-include标志。正如您所看到的那样,
-include
标志会使编译器在
预编译.h
之前搜索
预编译.h.gch
,使用
gcc
直接编译会产生相同的结果,因为这样使用时,它总是首先搜索PCH,当从
make
调用
gcc
时,情况并非如此,在其他编译器(如
clang
中,除非指定了
-include
),否则不会搜索PCH。根据gcc文档,“…在搜索包含的文件时(请参阅C预处理器中的搜索路径)编译器在每个目录中查找预编译头文件,然后再查找该目录中的include文件。搜索的名称是附加了“.gch”的#include中指定的名称。如果无法使用预编译头文件,则忽略它。”因此,如果预编译头文件存在于搜索路径中,默认情况下,应该始终优先于相应的头文件。证据是,在我修改的makefile中,我刚刚添加了预编译头文件的编译。我没有使用-include标志,它工作得非常好。所以迷雾仍然存在。我在makefile中添加了pch的编译,现在它可以工作了。但仍不清楚原因。make发出的命令不应该与直接从命令行发出的命令相同吗?编译makefile中的pch会有什么不同?我总是将lib.hpp作为.cpp文件中的第一个标记,因此这相当于使用-include标志。正如您所看到的那样,
-include
标志会使编译器在
预编译.h
之前搜索
预编译.h.gch
,使用
gcc
直接编译会产生相同的结果,因为这样使用时,它总是首先搜索PCH,当从
make
调用
gcc
时,情况并非如此,在其他编译器(如
clang
中,除非指定了
-include
),否则不会搜索PCH。根据gcc文档,“…在搜索包含的文件时(请参阅C预处理器中的搜索路径)编译器在之前的每个目录中查找预编译头