Я не фанат шаблонных правил. Они слишком произвольны для моих вкусов. (То, что на самом деле происходит, зависит от того, какие файлы могут храниться на вашем жестком диске.)
Вы не можете просто добавить предварительное условие к данному набору целей, используя правило шаблона
Ну, вы можете, если вы используете stati c шаблон правил . Это гораздо приятнее идиома. Здесь мы добавляем префикс шаблона к фактическому списку источников, к которым вы хотите применить правило шаблона. Это хорошо, когда вы можете описать зависимости, используя make 's совпадение шаблонов.
Эскиз:
%.a: ; date >$@ # Pattern rule
tcp: ; mkdir -p $@ # Explicit rule
tcp/a.a: tcp/%.a: | tcp ; # Static pattern rule!
.PHONY: all
all: tcp/a.a
all: c.a
all: dir/b.a
all: ; : $@ Success
И у нас есть:
$ make all
mkdir -p tcp
date >tcp/a.a
date >c.a
date >dir/b.a
/bin/sh: dir/b.a: No such file or directory
make: *** [Makefile:3: dir/b.a] Error 1
Здесь мы сказали make , что перед сборкой (т. Е. "Запускает рецепт для") tcp/a.a
, он должен сначала собрать tcp
. Это работает. Мы не сказали make о каталоге для dir/b.a
, так что это не удалось. Обратите внимание, что рецепт файла .a
все еще находится в обычном шаблонном правиле. Это просто в виде экспозиции. Я определенно изменил бы это.
Да, в этом случае правило шаблона для tcp/
является чрезмерным. Однако учтите, что перед созданием tcp/a.a
может потребоваться сначала создать auto/a.src
(скажем).
tcp/a.a: tcp/%.a: auto/%.src | tcp ; # Static pattern rule!
Легко расширяемый.
targets := tcp/a.a tcp/b.a tcp/c.a
${targets}: tcp/%.a: auto/%.src | tcp ; # Static pattern rule!
[Кстати, в исходном make-файле ваш архив и общий объект должны зависеть от файлов .o
, а не от источника (???)]