尽管使用目标文件,GNU make 仍会重新编译
GNU make recompiles despite using object files
我最近从 Cmake 切换到 GNU make 只是为了学习一些新东西。在我的 Makefile 中,我设置了它,因此它将创建目标文件和 link 它们,但每次我调用 make 而不是重新编译已更改的文件时,它会重新编译每个文件。
我的生成文件
# Output directory of the *.o files
ODIR = obj
# Compiler flags
FLAGS = -std=c++17 -w -Wfatal-errors
LINKER_FLAGS = -lSDL2 -lSDL2_image -lSDL2_ttf -lSDL2_mixer
#dependencies for output:
output: animation.o Asset_Manager.o Collision.o Engine.o Entity_Manager.o Entity.o Map.o Texture_Manager.o main.o
g++ $(ODIR)/*.o -o game $(LINKER_FLAGS)
./game
#object files
animation.o: src/animation.hpp src/animation.cpp
g++ -c src/animation.cpp $(FLAGS) -o $(ODIR)/animation.o
Asset_Manager.o: src/Asset_Manager.hpp src/Asset_Manager.cpp
g++ -c src/Asset_Manager.cpp $(FLAGS) -o $(ODIR)/Asset_Manager.o
Collision.o: src/Collision.hpp src/Collision.cpp
g++ -c src/Collision.cpp $(FLAGS) -o $(ODIR)/Collision.o
Engine.o: src/Engine.hpp src/tank.hpp src/Engine.cpp
g++ -c src/Engine.cpp $(FLAGS) -o $(ODIR)/Engine.o
Entity_Manager.o: src/Entity_Manager.hpp src/Entity_Manager.cpp
g++ -c src/Entity_Manager.cpp $(FLAGS) -o $(ODIR)/Entity_Manager.o
Entity.o: src/Entity.hpp src/Component.hpp src/Entity.cpp
g++ -c src/Entity.cpp $(FLAGS) -o $(ODIR)/Entity.o
Map.o: src/Map.hpp src/Map.cpp
g++ -c src/Map.cpp $(FLAGS) -o $(ODIR)/Map.o
Texture_Manager.o: src/Texture_Manager.hpp src//Texture_Manager.cpp
g++ -c src/Texture_Manager.cpp $(FLAGS) -o $(ODIR)/Texture_Manager.o
main.o: src/main.cpp
g++ -c src/main.cpp $(FLAGS) -o $(ODIR)/main.o
# Release Build
release:
g++ -std=c++17 -O3 -s -DNDEBUG \
./src/*.cpp -o game_release \
$(LINKER_FLAGS)
./game_release
# Recipes for the a spicy meatballs
run:
./game
run_release:
./game_release
clean:
rm $(ODIR)/*.o game
为什么调用 make 时会重新编译所有内容?
你正在破坏 second rule of makefiles:
Map.o: src/Map.hpp src/Map.cpp
g++ -c src/Map.cpp $(FLAGS) -o $(ODIR)/Map.o
这条规则说“如果你想构建一个文件 Map.o
那么这里有一个方法可以做到这一点”。但是你在这里没有说实话,因为那个配方不会构建 Map.o
,它会构建 $(ODIR)/Map.o
。所以下次 make 运行s 它会看到,“哦,我需要目标 Map.o
但它不存在,这里有一个创建它的方法,我会 运行 它!”但食谱还是没有建立 Map.o
.
我最近从 Cmake 切换到 GNU make 只是为了学习一些新东西。在我的 Makefile 中,我设置了它,因此它将创建目标文件和 link 它们,但每次我调用 make 而不是重新编译已更改的文件时,它会重新编译每个文件。
我的生成文件
# Output directory of the *.o files
ODIR = obj
# Compiler flags
FLAGS = -std=c++17 -w -Wfatal-errors
LINKER_FLAGS = -lSDL2 -lSDL2_image -lSDL2_ttf -lSDL2_mixer
#dependencies for output:
output: animation.o Asset_Manager.o Collision.o Engine.o Entity_Manager.o Entity.o Map.o Texture_Manager.o main.o
g++ $(ODIR)/*.o -o game $(LINKER_FLAGS)
./game
#object files
animation.o: src/animation.hpp src/animation.cpp
g++ -c src/animation.cpp $(FLAGS) -o $(ODIR)/animation.o
Asset_Manager.o: src/Asset_Manager.hpp src/Asset_Manager.cpp
g++ -c src/Asset_Manager.cpp $(FLAGS) -o $(ODIR)/Asset_Manager.o
Collision.o: src/Collision.hpp src/Collision.cpp
g++ -c src/Collision.cpp $(FLAGS) -o $(ODIR)/Collision.o
Engine.o: src/Engine.hpp src/tank.hpp src/Engine.cpp
g++ -c src/Engine.cpp $(FLAGS) -o $(ODIR)/Engine.o
Entity_Manager.o: src/Entity_Manager.hpp src/Entity_Manager.cpp
g++ -c src/Entity_Manager.cpp $(FLAGS) -o $(ODIR)/Entity_Manager.o
Entity.o: src/Entity.hpp src/Component.hpp src/Entity.cpp
g++ -c src/Entity.cpp $(FLAGS) -o $(ODIR)/Entity.o
Map.o: src/Map.hpp src/Map.cpp
g++ -c src/Map.cpp $(FLAGS) -o $(ODIR)/Map.o
Texture_Manager.o: src/Texture_Manager.hpp src//Texture_Manager.cpp
g++ -c src/Texture_Manager.cpp $(FLAGS) -o $(ODIR)/Texture_Manager.o
main.o: src/main.cpp
g++ -c src/main.cpp $(FLAGS) -o $(ODIR)/main.o
# Release Build
release:
g++ -std=c++17 -O3 -s -DNDEBUG \
./src/*.cpp -o game_release \
$(LINKER_FLAGS)
./game_release
# Recipes for the a spicy meatballs
run:
./game
run_release:
./game_release
clean:
rm $(ODIR)/*.o game
为什么调用 make 时会重新编译所有内容?
你正在破坏 second rule of makefiles:
Map.o: src/Map.hpp src/Map.cpp
g++ -c src/Map.cpp $(FLAGS) -o $(ODIR)/Map.o
这条规则说“如果你想构建一个文件 Map.o
那么这里有一个方法可以做到这一点”。但是你在这里没有说实话,因为那个配方不会构建 Map.o
,它会构建 $(ODIR)/Map.o
。所以下次 make 运行s 它会看到,“哦,我需要目标 Map.o
但它不存在,这里有一个创建它的方法,我会 运行 它!”但食谱还是没有建立 Map.o
.