Это - вид продолжения вопроса отсюда. Проблема состоит в том, что существует правило, генерирующее несколько выводов от единственного входа, и команда является трудоемкой, таким образом, мы предпочли бы избегать перерасчета. Теперь существует дополнительное скручивание, что мы хотим помешать файлам удаляться как промежуточные файлы, и правила включают подстановочные знаки для обеспечения параметров.
Предложенное решение состояло в том, что мы устанавливаем следующее правило:
file-a.out: program file.in
./program file.in file-a.out file-b.out file-c.out
file-b.out: file-a.out
@
file-c.out: file-b.out
@
Затем вызов make file-c.out
создает обоих, и мы избегаем проблем с выполнением make
параллельно с -j
переключатель. Весь штраф до сих пор.
Проблема следующая. Поскольку вышеупомянутое решение настраивает цепочку в DAG, make
рассматривает это по-другому; файлы file-a.out
и file-b.out
рассматриваются как промежуточные файлы, и они по умолчанию удалены как ненужные как только file-c.out
готово.
Способ избежать этого был упомянут где-нибудь здесь и состоит из добавления file-a.out
и file-b.out
как зависимости цели .SECONDARY
, который мешает им удаляться. К сожалению, это не решает мой случай, потому что мои правила используют подстановочные скороговорки; а именно, мои правила больше походят на это:
file-a-%.out: program file.in
./program $* file.in file-a-$*.out file-b-$*.out file-c-$*.out
file-b-%.out: file-a-%.out
@
file-c-%.out: file-b-%.out
@
так, чтобы можно было передать параметр, который включен в имя файла, например, путем выполнения
make file-c-12.out
Решение это make
документация предлагает, должны добавить они как неявные правила к списку зависимостей .PRECIOUS
, таким образом мешая этим файлам быть удаленным.
Решение с .PRECIOUS
работы, но это также препятствует тому, чтобы эти файлы были удалены, когда правило перестало работать, и файлы являются неполными. Там какой-либо другой путь состоит в том, чтобы сделать эту работу?
Взлом для решения этого должен определить цель .SECONDARY
без предпосылок, т.е.
.SECONDARY:
который сообщает make
это все файлы нужно рассматривать как вторичное и таким образом не удаленное, если когда make
прерван или правило перестало работать. К сожалению, это не позволяет, чтобы выбор подмножества правил с подстановочными знаками проложил себе путь, таким образом, я считаю это только взломом (даже при том, что это полезно).
Если вместо одного файла.in, ваши результаты были сгенерированы из файла предпосылок, включающего ствол, т.е.
file-a.out: program file-%.in
./program file-$*.in file-a-$*.out file-b-$*.out file-c-$*.out
тогда вы можете построить список всех возможных совпадений цели:
inputs = $(wildcard file-*.in)
secondaries = $(patsubst file-%.in,file-a-%.out,$(inputs)) \
$(patsubst file-%.in,file-b-%.out,$(inputs))
Аналогично, если ствол происходит из конечного множества:
batchnos = 17 18 19 20
batchnos = $(shell seq 17 20)
secondaries = $(patsubst %,file-a-%.out,$(batchnos)) $(patsubst %,file-b-%.out,$(batchnos))
Тогда просто добавьте их как предпосылки к цели .SECONDARY
.SECONDARY: $(secondaries)
Самая простая вещь
file-a-%.out file-b-%.out file-c-%.out: program file.in
./program $* file.in file-a-$*.out file-b-$*.out file-c-$*.out
сделает именно то, что вы хотите.
(Шаблонные правила с несколькими целями отличаются от обычного правила с несколькими целями, о котором вы спрашивали здесь . См. Пример bison в руководстве по make .)