Это происходит потому, что на самом деле это пустой рецепт, поэтому бежать нечего. Функция
$(shell)
оценивается при разборе рецепта Makefile, а ее вывод рассматривается как содержимое рецепта. Бывает, что этот оператор генерирует выходной файл как побочный продукт, но вывод оператора пустой, поэтому make
не имеет ничего общего и делает вывод, что цель актуальна. На самом деле, всегда будет так, если рецепт окажется пустым:
$ ls
Makefile foo.bar
$ cat Makefile
test.txt: foo.bar
$(info Making $@ from $<)
$ make
Making test.txt from foo.bar
make: 'test.txt' is up to date.
$ ls
Makefile foo.bar
Обратите внимание, что в приведенном выше примере не было создано test.txt
, make
только что пришел к выводу, что он выполнил (пустой) рецепт для обновите его, так что теперь он актуален.
Для правильной работы, вы должны вообще отказаться от функции $(shell)
. make
рецепты уже вызываются в оболочке:
$ cat Makefile
test.txt: foo.bar
grep ^hello $< >$@
$ make
grep ^hello foo.bar >test.txt
$ make
make: 'test.txt' is up to date.
$ make -B
grep ^hello foo.bar >test.txt
$ ls
Makefile foo.bar test.txt