GNU make 不删除中间文件

Max*_*xpm 5 makefile

我的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
Run Code Online (Sandbox Code Playgroud)

如您所见,.o文件通过目标指定为中间体.INTERMEDIATE。但是,编译完成后它们不会按预期删除。相反,它们保留在创建的位置,使我的源目录变得混乱。

奇怪的是,它在另一台机器上运行得很好。这让我相信它是 的不同版本make,但man make仍然将其显示为“GNU make 实用程序”。

为什么不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
Run Code Online (Sandbox Code Playgroud)

Dan*_*Dan 4

所以我将其复制到我的机器上并设法重现您的问题和解决方案。

请注意,在您的.INTERMEDIATE目标中,您使用$(OBJECT_FILES)作为先决条件,但对于创建文件的规则,.o您使用模式规则。这令人困惑make,并且它没有意识到两者指的是同一件事。这个问题有两种解决方案:

  1. .INTERMEDIATE将from$(OBJECT_FILES)的先决条件更改为%.o,所以看起来像

    .INTERMEDIATE: %.o
    
    Run Code Online (Sandbox Code Playgroud)
  2. 将制作 .o 文件的规则更改为

    $(OBJECT_FILES): $(SOURCE_FILES)
        $(COMPILER) $(COMPILER_OPTIONS) -c $< -o $@
    
    Run Code Online (Sandbox Code Playgroud)

    或类似的东西。

我推荐第一个解决方案,因为如果您有多个源文件,它不太可能导致编译时出现奇怪的问题。

有关中间目标的更多信息可以在此处找到。