Make-файл GNU: несколько выводов от единственного правила + препятствующий тому, чтобы были удалены промежуточные файлы

Это - вид продолжения вопроса отсюда. Проблема состоит в том, что существует правило, генерирующее несколько выводов от единственного входа, и команда является трудоемкой, таким образом, мы предпочли бы избегать перерасчета. Теперь существует дополнительное скручивание, что мы хотим помешать файлам удаляться как промежуточные файлы, и правила включают подстановочные знаки для обеспечения параметров.


Предложенное решение состояло в том, что мы устанавливаем следующее правило:

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 прерван или правило перестало работать. К сожалению, это не позволяет, чтобы выбор подмножества правил с подстановочными знаками проложил себе путь, таким образом, я считаю это только взломом (даже при том, что это полезно).

14
задан Community 23 May 2017 в 12:13
поделиться

2 ответа

Если вместо одного файла.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)
2
ответ дан 1 December 2019 в 11:59
поделиться

Самая простая вещь

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 .)

23
ответ дан 1 December 2019 в 11:59
поделиться
Другие вопросы по тегам:

Похожие вопросы: