2016-06-17 3 views
1

私は、複数の出力ファイルを生成するツールを持っています。これは、makeでモデリングするのが難しいことで有名です。私はGNU Makefile rule generating a few targets from a single source fileでレシピを使用していますが、これは簡単で信頼できるようです。そしてそれはほぼの作品です。信頼できない並列は、.INTERMEDIATEを使用してmakefileにビルドされますか?

残念ながら、並列ビルドに関するいくつかの非常に奇妙な動作が見られます。並列ビルドに関しては、依存関係が時々破棄されるようです。なぜ私は理解できません。私は一度それを構築する場合

out3: out1 out2 
    touch out3 

.INTERMEDIATE: out.intermediate 
out1 out2: out.intermediate 
out.intermediate: in 
    touch out1 out2 

、それは動作します:

は、ここに私のテストケースだ

$ touch in 
$ make -f test.mk out3 -j4 
touch out1 out2 
touch out3 

out1out2が一緒に構築されて、一度、良いです。その結果からout3が構築されます。

は今、私はインクリメンタルビルドをシミュレートし、入力ファイルに触れ、再度実行してください:

$ touch in 
$ make -f test.mk out3 -j4 
touch out1 out2 

正しく、out1out2を再構築だ...しかし、それはそれは持っている必要がありout3を再構築していないこと。それでは別のビルドをすれば:

$ make -f test.mk out3 -j4 
touch out3 

...そしてそれがキャッチアップします。

は、並列ビルドに適用されます。 -j1は正常に動作します。

これは悪いです---私は正しいビルドに頼ることができる必要があります。誰が何が起こっているかについて何か考えがありますか?

これはGNU Make 4.1です。

+0

あなたが参照しているレシピはGNU以外のフォールバック提案 です。あなたが* GNU Makeを使用しているときには、GNU Makeソリューションを同じ答えで使うことができます。GNU Makeソリューションを最も上に挙げた答えで使うことができます。テストケースでそれを試してみました。 –

+0

GNUはどのソリューションを作っていますか?あなたはパターンを意味しますか?私のファイル名は関連していないので、これは適切ではありません。 –

+0

必要な関連性は、ターゲットファイル名(前提条件ファイル名ではない)が少なくとも1つの文字( '。それじゃない? –

答えて

2

リンク先のSOの応答にエラーがあります。非常に多くの人々が成功したと思われることは明らかです。

GNU makeのディレクトリキャッシュの結果はどうなりますか(詳しくは、-rRdオプションをmake呼び出しに追加できます)。 GNU makeは、ファイルシステムの状態があなたのmakefileが記述するもの以外の何らかの形で変わることを期待していないので、ディレクトリの内容をキャッシュして(大規模なmakefile /ディレクトリに対して)大幅な性能向上を提供します。 makeはルールを実行するとき

基本的には、:out.intermediate

out.intermediate: in 
     touch out1 out2 

それは、このレシピは、ルールに記載されているもの以外のすべてのターゲットを更新することを期待していません。他のファイルout1out2が既にディレクトリキャッシュに内部化されている場合(それらは存在しており、すでにそれをout3の前提条件としてチェックしています)、makeはファイルシステムに戻って、更新されたかどうか:メイクファイルによれば、それが実行されたルールが変更されていない可能性があるため、変更できなかったことを知らせます。

これをすべて行うには、単純な1文字の修正があります。これに

out1 out2: out.intermediate 

:この行を変更し

out1 out2: out.intermediate ; 

あなたがより明確になりたい場合は、この使用することができます

out1 out2: out.intermediate 
     @: 

かさえ、この、デバッグのため:

out1 out2: out.intermediate 
     @echo Do nothing 

これらに共通するものターゲットと前提条件の間の依存関係だけでなく、レシピを与えて、そのルールを呼び出さなければならないということです。レシピが空であっても(最初の例のように)、makeは実際にコマンドを実行しないので、makeはout1および/またはout2のタイムスタンプが変更された可能性があると推測し、キャッシュされた変更を無効にしますファイルシステムからそれらを再取得することができます。

+0

ありがとうございます---それは完璧に動作します。 (また、私がmakeを使うたびに、私はもう少しそれを嫌ってしまいます。) –

関連する問題