web-dev-qa-db-ja.com

メイクファイル内の処理コンポーネントの順序

メイクファイルでは、依存関係の行は次の形式です-

abc: x y z

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

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

32

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

abc: x y z

順序はx y z

abc: x y z
y : z

順序はx z y

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

また、GNU Makeはいくつかのレシピを並行して実行できます。 Mat's answer を参照してください。

47

実際に実行される順序に依存するべきではありません。他のすべてが同じであれば、これらの前提条件の3つのレシピはすべて並行して実行できます。

唯一の厳しいルールは、ターゲットレシピを実行する前にすべての前提条件を満たしている必要があるということです。

xy、およびzの間に依存関係がなく、並列実行がない場合、GNU makeはそれらを順番に実行するように見えますそれらを指定しましたが、これはドキュメントで保証されていません。

36
Mat

make のPOSIX記述には、次のような根拠が含まれています。

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

_foo: y.tab.o Lex.o main.o
     $(CC) $(CFLAGS) -o $@ t.tab.o Lex.o main.o
_

この例では、makeが任意の順序を選択した場合、_Lex.o_は正しい_y.tab.h_で作成されない可能性があります。この関係を表現するより良い方法があるかもしれませんが、歴史的に広く使用されています。前提条件を並行して更新したい実装では、前述のように、makeまたはmakefile形式の明示的な拡張が必要です。

$(CC)行の_t.tab.o_は_y.tab.o_のタイプミスであると信じていますが、それは理論的には実際に言っていることです。

したがって、前提条件が左から右に処理されるという観察された動作はここで検証されますが、それは主な説明ではなく、根拠のセクションのみにあります。根拠は、並列makeなどの問題にも言及しています。

17