GNU does not delete intermediate files

My makefile looks like this:

# 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 

As you can see, .o files are specified as intermediate elements through the .INTERMEDIATE target. However, after compilation is complete, they are not deleted as expected. Instead, they remain where they were created, cluttering up my source directory.

It is strange that it works fine on another machine. This leads me to believe that this is a different version of make , but man make still shows it as a "GNU make utility."

Why doesn't make delete intermediate files?

EDIT: make -v reports version 3.81.

EDIT: after deleting the .o files (i.e. a blank sheet) make All produces the following output:

 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 
+4
source share
2 answers

So, I copied this to my machine and was able to reproduce both your problem and the solution.

Note that in your target .INTERMEDIATE you use $(OBJECT_FILES) as a prerequisite, but for a rule that uses .o files, a template rule is used. This confuses make , and it does not recognize that both refer to the same thing. There are two solutions to this problem:

  • Change the .INTERMEDIATE from $(OBJECT_FILES) to %.o , so it looks like

     .INTERMEDIATE: %.o 
  • Change the rule for creating .o files in

     $(OBJECT_FILES): $(SOURCE_FILES) $(COMPILER) $(COMPILER_OPTIONS) -c $< -o $@ 

    or something like that.

I recommend the first solution, as it is less likely to cause strange compilation problems if you have multiple source files.

More information on the intermediate goal can be found here .

+3
source

Make sure there are no files before you start building the project. Doc clearly says:

Consequently, an intermediate file that did not exist before make also does not exist after make .

If this is not a problem, you should post some debug output from make.

+4
source

All Articles