Рассмотрим код make-файла в листинге 1. Цель - создать файл зависимостей $ (DEPDIR) /%. D для каждого объектного файла% .o, сгенерированного при запуске компилятора C в строке 9. В частности, файлы зависимостейгенерируются как побочный эффект вызова компилятора C в строке 9 для преобразования файла% .c в файл% .o - т. е. в строке 9 выделяются два файла: $ (DEPDIR) /%. d и% .o.
Листинг 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 : ;
15
16 # [EDIT]
17 .PRECIOUS: $(DEPDIR)/%.d
Этот код make-файла работает как надо , но я не понимаю, почему (см. Ниже) . В частности, при вызове make создается папка DEPDIR, если она не существует, а рецепт в строке 9 генерирует файлы $ (DEPDIR) /%. D, а также файлы% .o.
Теперь предположим, что пользовательудаляет один или несколько файлов% .d или всю папку DEPDIR. Повторный вызов make перестраивает отсутствующие файлы зависимостей по желанию , но, опять же, я не понимаю, почему .
$ 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
Теперь замените правило статического шаблона в строке 8 неявным правилом, показанным вЛистинг 2, а в остальном оставьте все остальное как было:
Листинг 2.
7 %.o : %.c
8 %.o : %.c $(DEPDIR)/%.d | $(DEPDIR)
9 $(COMPILE.c) $(CPP_DEPFLAGS) $(OUTPUT_OPTION) $<
Когда используется неявное правило, make не восстанавливает удаленный / отсутствующийфайлы зависимостей - это НЕ ожидаемый результат:
$ 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
Версия правила статического шаблона учитывает удаленное / отсутствующее предварительное условие $ (DEPDIR) /%. d (в строке 8). ) будет обновлено (что я НЕ ожидал) по правилу в строке 14, что сделает цель% .o устаревшей, и, следовательно, рецепт в строке 9вызывается для восстановления файла% .o.
С другой стороны, неявное шаблонное правило, по-видимому, считает удаленное / отсутствующее условие $ (DEPDIR) /%. D (в строке 8) равным не обновлено актуальный (что на НЕ то, что я ожидал), и поэтому make считает, что цель% .o обновлена, и рецепт в строке 9 не вызывается.
Так почему же неявное правило шаблона (листинг 2) не вызывает строку рецепта в строке 9? В документации GNU Make я не нахожу ничего, что объясняет эту разницу между правилом статического шаблона и неявным правилом.