makefile "Removing intermediate files" only sometimes

make is deleting files that have been created with my own rule (not an implicit one).

I have a makefile which works as expected, which is the following:


OBJ     = assert.o

DEP     = $(OBJ:.o=.d)

################################################################################
# target: dependencies
#   action

PHONY := all
all: $(subst .a.o,.a.o ,$(join $(OBJ:.o=.a.o),$(OBJ:.o=.so.o)))
    @:


%.d: $(SRC_DIR)/base/assert/%.c
    $(Q)mkdir -p        $(@D)/
    @echo   "   CC -M   build/tmp/base/assert/$@"
    $(Q)$(CC) $(CFLAGS_A) -MG -MT"$@" -MT"$*.a.s" -MT"$*.so.s" -M $< -MF $@
%.a.s: $(SRC_DIR)/base/assert/%.c
    $(Q)mkdir -p        $(@D)/
    @echo   "   CC  build/tmp/base/assert/$@"
    $(Q)$(CC) $(CFLAGS_A) -S $< -o $@
%.so.s: $(SRC_DIR)/base/assert/%.c
    $(Q)mkdir -p        $(@D)/
    @echo   "   CC  build/tmp/base/assert/$@"
    $(Q)$(CC) $(CFLAGS_SO) -S $< -o $@
%.o: %.s
    @echo   "   AS  build/tmp/base/assert/$@"
    $(Q)$(AS) $< -o $@

include $(DEP)


PHONY += clean
clean:
    $(Q)rm -f *.o *.s

################################################################################
# Declare the contents of the .PHONY variable as phony.
.PHONY: $(PHONY)

This makefile creates the files assert.d assert.a.s assert.so.s assert.a.o and assert.so.o and deletes none of them:

    CC -M   build/tmp/base/assert/assert.d
    CC  build/tmp/base/assert/assert.a.s
    AS  build/tmp/base/assert/assert.a.o
    CC  build/tmp/base/assert/assert.so.s
    AS  build/tmp/base/assert/assert.so.o

Then I have another makefile where I have to work with subdirectories, and I had to workaround a problem: % doesn't handle that well. The makefile is the following:

OBJ     = $(CURDIR)/tcp/client.o

DEP     = $(OBJ:.o=.d)
BOTH_OBJ    = $(subst .a.o,.a.o ,$(join $(OBJ:.o=.a.o),$(OBJ:.o=.so.o)))
#BOTH_ASM   = $(BOTH_OBJ:.o=.s)

################################################################################
# target: dependencies
#   action

PHONY := all
all: $(BOTH_OBJ)
    @:


$(CURDIR)/%.d: $(SRC_DIR)/base/socket/%.c
    $(Q)mkdir -p        $(@D)/
    @echo   "   CC -M   build/tmp/base/socket/$*.d"
    $(Q)$(CC) $(CFLAGS_A) -MG -MT"$@" -MT"$*.a.s" -MT"$*.so.s" -M $< -MF $@
$(CURDIR)/%.a.s: $(SRC_DIR)/base/socket/%.c
    $(Q)mkdir -p        $(@D)/
    @echo   "   CC  build/tmp/base/socket/$*.a.s"
    $(Q)$(CC) $(CFLAGS_A) -S $< -o $@
$(CURDIR)/%.so.s: $(SRC_DIR)/base/socket/%.c
    $(Q)mkdir -p        $(@D)/
    @echo   "   CC  build/tmp/base/socket/$*.so.s"
    $(Q)$(CC) $(CFLAGS_SO) -S $< -o $@
$(CURDIR)/%.o: $(CURDIR)/%.s
    @echo   "   AS  build/tmp/base/socket/$*.o"
    $(Q)$(AS) $< -o $@

include $(DEP)


PHONY += clean
clean:
    $(Q)rm -rf *.o *.s

################################################################################
# Declare the contents of the PHONY variable as phony.
.PHONY: $(PHONY)


#.PRECIOUS: $(BOTH_ASM)

However, for some reason, make decides that the intermediate files are not important here and removes them:

    CC -M   build/tmp/base/socket/tcp/client.d
    CC  build/tmp/base/socket/tcp/client.a.s
    AS  build/tmp/base/socket/tcp/client.a.o
    CC  build/tmp/base/socket/tcp/client.so.s
    AS  build/tmp/base/socket/tcp/client.so.o
rm /media/user/DataNTFS/Alex-dev/git/libalx/build/tmp/base/socket/tcp/client.a.s /media/user/DataNTFS/Alex-dev/git/libalx/build/tmp/base/socket/tcp/client.so.s

I found this. But I can see no difference between the two makefiles. It should remove the files either in both of them or none of them as far as I can see. Why is it removing the files in the second makefile only?


Uncommenting .PRECIOUS seems to prevent removal, but I'm not sure if I'm hiding something bad with it.

Upvotes: 0

Views: 158

Answers (1)

I forgot to add $(CURDIR)/ in the target names of the dependencies files generated by gcc.

This line solved that:

    $(Q)$(CC) $(CFLAGS_A) -MG -MT"$@" -MT"$(CURDIR)/$*.a.s" -MT"$(CURDIR)/$*.so.s" -M $< -MF $@

So the full rule is as follows:

$(CURDIR)/%.d: $(SRC_DIR)/base/socket/%.c
    $(Q)mkdir -p        $(@D)/
    @echo   "   CC -M   build/tmp/base/socket/$*.d"
    $(Q)$(CC) $(CFLAGS_A) -MG -MT"$@" -MT"$(CURDIR)/$*.a.s" -MT"$(CURDIR)/$*.so.s" -M $< -MF $@

Upvotes: 1

Related Questions