15

ここからの質問の続きです。問題は、1 つの入力から複数の出力を生成するルールがあり、コマンドに時間がかかるため、再計算を避けたいということです。ここで、ファイルが中間ファイルとして削除されないようにしたいという追加のひねりがあり、ルールにはパラメーターを許可するワイルドカードが含まれます。


提案された解決策は、次のルールを設定することでした。

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
    @

次に、呼び出すと両方が作成され、 switchと並行しmake file-c.outて実行する際の問題が回避されます。これまでのところすべて順調です。make-j


問題は次のとおりです。上記のソリューションは DAG でチェーンをセットアップするため、別の方法でmake考慮します。これらのファイルは中間ファイルとして扱われ、デフォルトでは、準備が整うと不要になるとすぐに削除されfile-a.outます。file-b.outfile-c.out

これを回避する方法は、ここのどこかで言及されており、ターゲットの依存関係としてfile-a.outandを追加することで構成され、それらが削除されないようにします。残念ながら、私のルールではワイルドカード パターンが使用されているため、これで問題は解決しません。具体的には、私のルールは次のようになります。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残念ながら、ワイルドカードを使用してルールのサブセットを選択してこのように動作させることはできません。そのため、これはハックにすぎないと考えています (便利ではありますが)。

4

2 に答える 2

25

最も単純なこと

file-a-%.out file-b-%.out file-c-%.out: program file.in
    ./program $* file.in file-a-$*.out file-b-$*.out file-c-$*.out

あなたが望むことを正確に行います。

(複数のターゲットを持つパターン ルールは、ここで質問していた複数のターゲットを持つ通常のルールとは異なります。makeマニュアルの bison の例を参照してください。)

于 2010-06-24T20:14:06.767 に答える
2

単一のfile.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)
于 2010-06-15T15:55:22.947 に答える