Consider the makefile code in Listing 1. The goal is to generate a dependency file $(DEPDIR)/%.d for each object file %.o generated when the C compiler is invoked on line 9. Specifically, the dependency files are generated as a side-effect of invoking the C compiler on line 9 to translate a %.c file into a %.o file--i.e., line 9 emits two files: $(DEPDIR)/%.d and %.o.
Listing 1.
1 DEPDIR := deps
2
3 SOURCES.c := $(wildcard *.c)
4 OBJS.c := $(SOURCES.c:.c=.o)
5
6 CPP_DEPFLAGS = -MT $@ -MMD -MF $(DEPDIR)/$*.d
#
# Other rules, variable definitions, etc. are here...
#
7 %.o : %.c
8 $(OBJS.c) : %.o : %.c $(DEPDIR)/%.d | $(DEPDIR)
9 $(COMPILE.c) $(CPP_DEPFLAGS) $(OUTPUT_OPTION) $<
10
11 $(DEPDIR) : ; mkdir -p $@
12
13 # Ensure make considers missing $(DEPDIR)/%.d files as "not updated"
14 $(DEPDIR)/%.d : ;
This makefile code works as desired, but I don't understand why (see below). Specifically, invoking make creates the DEPDIR folder if it does not exist, and the recipe on line 9 emits the $(DEPDIR)/%.d files as well as the %.o files.
Now assume the user deletes one or more of the %.d files, or the entire DEPDIR folder. Reinvoking make rebuilds the missing dependency files as desired, but again, I don't understand why.
$ rm -fr depdir *.o
$ make # Generates DEPDIR and the $(DEPDIR)/%.d files
$ rm -fr depdir
# NB: The %.o files still exist
$ make # Regenerates DEPDIR and the $(DEPDIR)/%.d files
Now replace the static pattern rule on line 8 with the implicit rule shown in Listing 2, and otherwise leave everything else as it was:
Listing 2.
8 %.o : %.c $(DEPDIR)/%.d | $(DEPDIR)
9 $(COMPILE.c) $(CPP_DEPFLAGS) $(OUTPUT_OPTION) $<
When an implicit rule is used, make does not regenerate deleted/missing dependency files--which is the outcome I expected:
$ rm -fr depdir *.o
$ make # Generates DEPDIR and the $(DEPDIR)/%.d files
$ rm -fr depdir
# NB: The %.o files still exist
$ make # Generates DEPDIR only; DOES NOT regenerate the $(DEPDIR)/%.d files
It's as though the static pattern rule version considers the prerequisite $(DEPDIR)/%.d (on line 8) to be updated (which I did NOT expect), thus making the %.o target out-of-date, and therefore the recipe on line 9 is invoked to rebuild the %.o file.
The implicit pattern rule, on the other hand, apparently considers the prerequisite $(DEPDIR)/%.d (on line 8) to be not updated (which is what I expected), and therefore make considers the %.o target up-to-date and the recipe on line 9 is not invoked.
So why does the static pattern rule version (Listing 1) regenerate the missing $(DEPDIR)/%.d files, while the implicit pattern rule version (Listing 2) does not? I don't find anything in the GNU Make documentation to explain this difference.
Aucun commentaire:
Enregistrer un commentaire