makefileのコンポーネントの処理順序

makefileでは、依存関係の行は次の形式です。

abc: x y z

3つのコンポーネント(x、y、z)はすべてそれ自身がmakefileのさらに下の依存関係行のターゲットです。

make abc が呼び出された場合、3つのターゲットx、y、zはどの順番で実行されますか?

22
追加された 著者 Mike,

4 答え

あなたは本当にそれらが実行される順序に依存すべきではありません。他のすべてが等しい場合、それらの前提条件の3つのレシピはすべて並行して実行できます。

ターゲットレシピが実行される前に、すべての前提条件が満たされていなければなりません。

x y z の間に依存関係がなく、パラレル実行がない場合、GNU makeはそれらを指定した順序で実行するように見えますこれはドキュメントで保証されていません。

31
追加された
'recipe'は、依存関係行の下にあるコマンドのリストを示すために使用される用語です。
追加された 著者 Shailesh Tainwala,
はい、それは(GNUのドキュメンテーションにはとにかく)という言葉です。
追加された 著者 Mat,
短く明確な答え。今は +1 できませんが、明日に戻って投票することを忘れないようにしていきます。
追加された 著者 Eldar Abusalimov,
これを置くもう1つの方法: の順序依存性があるときはいつでも、それをMakefileルールとして明示的にする。
追加された 著者 reinierpost,

デフォルトでは、これらの前提条件の間に依存関係が定義されていない限り、実行順序は前提条件リストで指定されたものと同じです。

abc: x y z

順序は xy です。

abc: x y z
y : z

順序は x です。

しかし、理想的には、前提条件が指定されている順序に依存しないように、Makefileを設計する必要があります。つまり、 y の後に y を実行する必要がある場合、 y:z 依存する必要があります。

GNU Makeはいくつかのレシピを並列に実行できることを覚えておいてください。 Matの答えを参照してください。

29
追加された
ありがとう、明確な答え。なぜ「UPD」があるのですか?そこで?
追加された 著者 Shailesh Tainwala,
@ EldarAbusalimov:その必要はありません - 改訂履歴があります。答えは単なる結論の産物にしてください。
追加された 著者 Lightness Races in Orbit,
@ Shailesh、あなたは大歓迎です。私はUPDを追加しました。主な回答を投稿した後のセクション。
追加された 著者 Eldar Abusalimov,

make のPOSIXの説明には根拠が含まれていますそれは言う:

ほとんどの歴史的な実装の make ユーティリティは、ターゲットの前提条件を左から右の順に処理します。メークファイル形式にはこれが必要です。 yacc プログラムを生成する多くのメイクファイルで使われている標準的なイディオムをサポートしています。たとえば:

  foo:y.tab.o lex.o main.o
     $(CC)$(CFLAGS)-o $ @ t.tab.o lex.o main.o
 
     

この例では、 make が任意の順序を選択した場合、正しい y.tab.h lex.o >。この関係を表現するより良い方法があるかもしれませんが、歴史的に広く使われています。前提条件を並行して更新したい場合は、前述のように make またはmakefileフォーマットを明示的に拡張する必要があります。

$(CC)行の t.tab.o y.tab.o のタイプミスであり、しかしそれは理論的根拠が実際に言うものです。

したがって、前提条件が左から右へと処理されるという観察された振る舞いはここで検証されますが、それは主な記述ではなく、根拠節のみにあります。理論的根拠には、 make と並行して問題が記述されています。

15
追加された
+ POSIXの説明と、 make と並行して重要な注意点があります。 IMOは、パラレルジョブに対する注文の強制を許さないという選択は間違っていました。 私の .o オブジェクトはどんな順序でもコンパイルできてうれしいですが、コンパイルとリンクの前後で何か他のことが起こる必要があります。それよりもはるかに難しい...
追加された 著者 underscore_d,

https://stackoverflow.com/a/22638294/636849 から、パイプシンボルを追加できます:

abc: | x y z

makeマニュアルから:   注文のみの前提条件は、前提条件リストにパイプ記号(|)を挿入することで指定できます。パイプ記号の左側の前提条件はすべて正常です。権利の前提条件はオーダーのみです:

     

ターゲット:通常の前提条件|注文のみの前提条件

1
追加された
いいえ、それは注文のみの前提条件とは異なります。 foo:| bar bar はパイプ文字なしで bar baz を強制しません。代わりに、パイプは大まかに「foo、barとbazを注文するとbarとbazは両方ともfooの前に来なければなりませんが、barとbazへの更新はfooを更新して実行する必要がある十分な理由ではありません。ドキュメントは gnu.org/software/make/manual/html_nodeにあります。 /Prerequisite-Types.ht‌ ml であり、最も明瞭ではありません。
追加された 著者 Phil P,