我的makefile如下:
# The names of targets that can be built. Used in the list of valid targets when no target is specified, and when building all targets.
TARGETS := libAurora.a libAurora.so
# The place to put the finished binaries.
TARGET_DIRECTORY := ./Binaries
# The compiler to use to compile the source code into object files.
COMPILER := g++
# Used when compiling source files into object files.
COMPILER_OPTIONS := -I. -Wall -Wextra -fPIC -g -O4
# The archiver to use to consolidate the object files into one library.
ARCHIVER := ar
# Options to be passed to the archiver.
ARCHIVER_OPTIONS := -r -c -s
SOURCE_FILES := $(shell find Source -type f -name *.cpp)
OBJECT_FILES := $(SOURCE_FILES:.cpp=.o)
.PHONY: Default # The default target, which gives instructions, can be called regardless of whether or not files need to be updated.
.INTERMEDIATE: $(OBJECT_FILES) # Specifying the object files as intermediates deletes them automatically after the build process.
Default:
@echo "Please specify a target, or use \"All\" to build all targets. Valid targets:"
@echo "$(TARGETS)"
All: $(TARGETS)
lib%.a: $(OBJECT_FILES)
$(ARCHIVER) $(ARCHIVER_OPTIONS) $(TARGET_DIRECTORY)/$@ $(OBJECT_FILES)
lib%.so: $(OBJECT_FILES)
$(ARCHIVER) $(ARCHIVER_OPTIONS) $(TARGET_DIRECTORY)/$@ $(OBJECT_FILES)
%.o:
$(COMPILER) $(COMPILER_OPTIONS) -c -o $@ $*.cpp
如您所见,.o
文件通过.INTERMEDIATE
目标指定为中间人。但是,在编译完成后,它们不会按预期删除。相反,它们仍然保留在创建它们的位置,使我的源目录变得混乱。
奇怪的是它在另一台机器上完美运行。这让我相信它是make
的不同版本,但man make
仍然将其显示为“GNU make utility”。
为什么make
不会删除中间文件?
编辑:make -v
报告版本3.81。
编辑:手动删除.o
文件(即干净的平板)后,make All
会产生以下输出:
g++ -I. -Wall -Wextra -fPIC -g -O4 -c -o Source/File/File.o Source/File/File.cpp
g++ -I. -Wall -Wextra -fPIC -g -O4 -c -o Source/Timer/Timer.o Source/Timer/Timer.cpp
ar -r -c -s ./Binaries/libAurora.a Source/File/File.o Source/Timer/Timer.o
ar -r -c -s ./Binaries/libAurora.so Source/File/File.o Source/Timer/Timer.o
答案 0 :(得分:4)
确保在开始构建项目之前文件不存在。医生说清楚:
因此,在 make
之后, <{strong> make
之前之前不存在的中间文件也不存在。
如果这不是问题,你应该从make发布一些调试输出。
答案 1 :(得分:3)
所以我把它复制到我的机器上并设法重现你的问题和解决方案。
请注意,在.INTERMEDIATE
目标中,您使用$(OBJECT_FILES)
作为先决条件,但对于生成.o
文件的规则,您使用模式规则。这会让make
感到困惑,并且它无法识别两者都指的是同一件事。这个问题有两种解决方案:
将.INTERMEDIATE
的先决条件从$(OBJECT_FILES)
更改为%.o
,因此看起来像
.INTERMEDIATE: %.o
将制作.o文件的规则更改为
$(OBJECT_FILES): $(SOURCE_FILES)
$(COMPILER) $(COMPILER_OPTIONS) -c $< -o $@
或类似的东西。
我推荐第一个解决方案,因为如果您有多个源文件,它不太可能导致编译出现奇怪的问题。
可以找到有关中间目标的更多信息here。