GNU makeはどの順序で前提条件を作成しますか?
-
22-07-2019 - |
質問
ルールがあると仮定します:
a: b c d e
およびb
、c
、d
およびe
は互いに独立しています。
<=>、<=>、<=>、<=>の作成順序は定義されていますか?一般に、それらは<=>、<=>、<=>、<=>の順序で作成されるように思われますが、順序が異なることもあります。
解決
もちろん、make -j a
を使用すると、それらはすべて同時にビルドされる可能性があります(b
、c
、d
、またはe
が他の/相互に依存する依存関係があるかどうかによって異なります)。
他のヒント
いいえ、順序は定義されていません。これが、宣言的依存関係指向プログラミングの使用における全体のポイントです。コンピューターが最適な評価順序を選択できるか、実際には、それらを同時にでも評価できるということです。
GNU makeはどのような順序で前提条件を作成しますか?
前提条件のタイプによって異なります。 tho GNU Make Manual 、セクション4.2:
実際に理解される前提条件には2種類あります GNU make:前述のような通常の前提条件 セクション、注文のみの前提条件。通常の前提条件は2つになります ステートメント:最初に、レシピの順序を課します 起動:ターゲットのすべての前提条件のレシピは ターゲットのレシピが実行される前に完了します。第二に、それは課す 依存関係:前提条件がよりも新しい場合 ターゲットの場合、ターゲットは古いと見なされ、再構築する必要があります。
通常、これはまさにあなたが望むものです。ターゲット<!>#8217; sの前提条件が 更新したら、ターゲットも更新する必要があります。
ただし、場合によっては、 強制されることなく 呼び出されるルールの特定の順序 これらのルールのいずれかが実行された場合に更新されるターゲット。その場合、 注文のみの前提条件を定義します。注文のみ 前提条件を指定するには、パイプ記号(|)を 前提条件リスト:パイプ記号の左側にある前提条件 正常です;右側の前提条件は注文のみです:
targets: normal-prerequisites | order-only-prerequisites
もちろん、通常の前提条件セクションは空かもしれません。また、あなたは 同じターゲットに対して複数行の前提条件を引き続き宣言します。 それらは適切に追加されます(通常の前提条件は 通常の前提条件のリスト。注文のみの前提条件は 注文のみの前提条件のリストに追加されます)。もしあなたが 同じファイルを通常と注文のみの両方として宣言する 前提条件、通常の前提条件が優先されます(なぜなら 注文のみの前提条件の動作の厳密なスーパーセットがあります)。
ターゲットを別の場所に配置する例を考えてください
make
を実行する前にそのディレクトリが存在しない可能性があります。に この状況では、ディレクトリを作成する前に ターゲットはそこに配置されますが、ディレクトリのタイムスタンプが ファイルが追加、削除、または名前変更されるたびに変更します。 don <!>#8217; tディレクトリ<!>#8217; sのたびにすべてのターゲットを再構築したくない タイムスタンプが変更されます。これを管理する1つの方法は、注文のみです 前提条件:ディレクトリをすべての注文専用の前提条件にする ターゲット:OBJDIR := objdir OBJS := $(addprefix $(OBJDIR)/,foo.o bar.o baz.o) $(OBJDIR)/%.o : %.c $(COMPILE.c) $(OUTPUT_OPTION) $< all: $(OBJS) $(OBJS): | $(OBJDIR) $(OBJDIR): mkdir $(OBJDIR)
ルールを作成して、<!>#8216; objdir <!>#8217;を作成します。必要に応じてディレクトリが実行されます <!>#8216; .o <!>#8217;の前ビルドされますが、<!>#8216; .o <!>#8217;ために構築されます <!>#8216; objdir <!>#8217;ディレクトリのタイムスタンプが変更されました。
指定したルールに基づいて、右の順序で。あなたの特定の例では、それはいくつかの異なる(4!= 24、メモリから)注文のうちのいずれかを意味する可能性があります。
すべてのmake
プログラムは、依存関係が守られている限り、好きな順序を自由に選択できます。例に他のルールがある場合、たとえばc: b
の場合、c
はb
の前に作成されます(ただし、指摘したようにそうではありません)。
特定の順序に依存する必要がある場合は、強制するためにさらにルールが必要になります。それ以外の場合は、<=>が必要な処理を実行できます。 GNU Makeのドキュメントには、ルールルール内の依存関係が処理される順序ではなく、処理されます。最も論理的な順序(とにかく私にとって)は、リストされている順序になりますが、それは保証されません。
順序が重要な場合は、再帰make 。たとえば、dとdの両方がeの前に作成されている限り、bとcの順序は関係ないとします。次に、ルールを次のように記述できます。
a: b c
$(MAKE) d
$(MAKE) e
# Additional steps to make a
dとeの複雑さによっては、このアプローチはビルド時間に悪い影響を与える可能性があることに注意してください:この方法で行うことに反対する議論については、再帰的に有害と見なされます(PDF)。