Makefile GNU使不删除中间文件

Makefile GNU使不删除中间文件,makefile,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 :

我的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
的不同版本,但
manmake
仍然将其显示为“gnumake实用程序”

为什么不
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

在开始构建项目之前,请确保文件不在那里。该文件明确指出:

因此,在
make
之前不存在的中间文件在
make
之后也不存在


如果这不是问题,您应该发布make的一些调试输出。

因此我将其复制到我的机器上,并设法重现您的问题和解决方案

请注意,在
.INTERMEDIATE
目标中,您使用
$(OBJECT\u FILES)
作为先决条件,但对于生成
.o
文件的规则,您使用模式规则。这混淆了make,并且不能识别两者指的是同一事物。此问题有两种解决方案:

  • .INTERMEDIATE
    的先决条件从
    $(对象\u文件)
    更改为
    %.o
    ,使其看起来像

    .INTERMEDIATE: %.o
    
  • 将生成.o文件的规则更改为

    $(OBJECT_FILES): $(SOURCE_FILES)
        $(COMPILER) $(COMPILER_OPTIONS) -c $< -o $@
    
    $(对象文件):$(源文件)
    $(编译器)$(编译器选项)-c$<-o$@
    
    或者类似的

  • 我推荐第一种解决方案,因为如果您有多个源文件,它就不太可能在编译中引起奇怪的问题


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

    每次进行更改时,是否确实要重新生成所有源?如果只是
    .o
    噪音困扰着你,那就把它们建在别的地方。并使用
    make-v
    获取版本。@如果有更好的方法不需要显式指定每个源文件,请告诉我。
    在运行它时使所有的
    输出什么?另外,不同的机器运行什么操作系统<我认为,代码>生成在Windows和Linux上有一些不同的行为。这可能是因为生成对象文件的规则没有先决条件吗?您可以尝试(a)将规则更改为读取
    %.o:%.c
    或(b)完全删除规则并更改变量名,以便make可以使用内置规则来构建对象(即,
    $(编译器)
    $(CXX)
    $(编译器选项)
    $(cxflags)
    )。请参阅GNU make手册中的隐式规则使用。如果这两种方法中的任何一种都有效,我会把它作为一个答案发布出来。在从头开始构建之后,这个问题仍然存在。我已经发布了来自
    make All
    的输出。谢谢@Maxpm,但是对于调试输出,请使用
    make-d All
    ,再次从干净状态发布输出