Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Avoid gnu make automatic file deletion

Tags:

makefile

GNU make is deleting my object files automatically. I don't understand why... My goal is small test programs generation, hence each source file is an independent program which uses no other module.

My makefile is:

# This makefile is written for Windows cmd shell
SHELL=C:\Windows\System32\cmd.exe

# FILES
SRCS=$(wildcard src/*.cpp)
BINS=$(patsubst %.cpp,bin/%.exe,$(notdir $(SRCS)))

all:compile

obj/%.o:src/%.cpp
    g++ -Wall -Wextra -std=gnu++11 -m64 -D_WIN32_WINNT=0x0400 -c -o $@ $<

bin/%.exe:obj/%.o
    g++ -Wall -Wextra -std=gnu++11 -m64 $^ -o $@

clean:
    if exist obj\*.o del /Q obj\*.o

mrproper:clean
    if exist bin\*.exe del /Q bin\*.exe

compile:$(BINS)

rebuild:clean all

.PHONY:all compile clean mrproper rebuild

Running GNU make with, for instance, a single source file does as follows:

g++ -Wall -Wextra -std=gnu++11 -m64 -D_WIN32_WINNT=0x0400 -c -o obj/Tester.o src/Tester.cpp
g++ -Wall -Wextra -std=gnu++11 -m64 obj/Tester.o -o bin/Tester.exe
rm obj/Tester.o

Why is my object file deleted? How to avoid it?

If I replace either obj/%.o:src/%.cpp by obj/Tester.o:src/Tester.cpp or bin/%.exe:obj/%.o by bin/Tester.exe:obj/Tester.o the file Tester.o is not deleted, but this is not what I need.

like image 844
jdarthenay Avatar asked Oct 20 '25 04:10

jdarthenay


2 Answers

Since you use implicit rule (such as ‘%.o’), object file will be delete after make.

Add special target .PRECIOUS to protect it.

.PRECIOUS: obj/%.o

Reference:

Special Built-in Target Names

Chains of Implicit Rules

like image 53
yihsiu Avatar answered Oct 22 '25 04:10

yihsiu


After reading the links yihsiui provides, I come with another answer to my own question. The object files are deleted because they don't exist and the rules I wrote made them intermediate. To avoid them to be flagged as intermediate, they must be an explicit target in some rule. I still need the pattern rule to generate the object file because I use the pattern substitution to compute the name of the object file. So, why not simply add an "empty" rule?

OBJS=$(patsubst %.cpp,obj/%.o,$(notdir $(SRCS)))

(...)

$(OBJS):
like image 37
jdarthenay Avatar answered Oct 22 '25 05:10

jdarthenay