У меня есть следующий рекурсивный make-файл:
.PHONY: all clean
%.subdir:
$(MAKE) -C src $*
$(MAKE) -C dict $*
all: all.subdir
clean: clean.subdir
и это хорошо работает:
$ make all
make -C src all
make[1]: Entering directory `/or-1.3.6-fix/src'
make[1]: Nothing to be done for `all'.
make[1]: Leaving directory `/or-1.3.6-fix/src'
make -C dict all
make[1]: Entering directory `/or-1.3.6-fix/dict'
make[1]: Nothing to be done for `all'.
make[1]: Leaving directory `/or-1.3.6-fix/dict'
Но было бы более логично определить %.subdir
правила как фальшивые:
.PHONY: all clean all.subdir clean.subdir
и теперь сделайте остановки, работающие, как я хочу:
$ make all
make: Nothing to be done for `all'.
$ make -d all
...
Updating goal targets....
Considering target file `all'.
File `all' does not exist.
Considering target file `all.subdir'.
File `all.subdir' does not exist.
Finished prerequisites of target file `all.subdir'.
Must remake target `all.subdir'.
Successfully remade target file `all.subdir'.
Finished prerequisites of target file `all'.
Must remake target `all'.
Successfully remade target file `all'.
make: Nothing to be done for `all'.
Кто-то может объяснить меня почему (или еще лучше указывают на меня для создания документации)?
Вы правы, было бы разумнее определить правила подкаталога как PHONY. Но Make не учитывает неявные правила для целей PHONY, поэтому вам придется переписать это правило. Я предлагаю следующее:
SUBDIR_TARGETS = all.subdir clean.subdir
.PHONY: all clean $(SUBDIR_TARGETS)
$(SUBDIR_TARGETS): %.subdir:
$(MAKE) -C src $*
$(MAKE) -C dict $*
all: all.subdir
clean: clean.subdir
Из этот раздел руководства make:
Неявный поиск правил (см. Неявные правила) пропускается для целей .PHONY. Вот почему объявление цели как .PHONY полезно для производительности, даже если вас не беспокоит фактический существующий файл.
Следовательно, ваши неявные цели никогда не будут найдены, потому что они фальшивые.
Вы можете добиться того, что пытаетесь сделать, другим путем. Попробуйте это:
SUBDIRS := all clean
.PHONY: $(SUBDIRS)
$(SUBDIRS):
echo $(MAKE) -C src $@
echo $(MAKE) -C dict $@