web-dev-qa-db-ja.com

Makefileのダブルコロンルールとは何ですか?

GNU Makeマニュアルのセクション4.13では、いわゆるダブルコロンルールについて説明しています。

ダブルコロンルールは、ターゲット名の後に「:」ではなく「::」で記述されたルールです。同じターゲットが複数のルールに表示される場合、通常のルールとは異なる方法で処理されます。

ターゲットが複数のルールに表示される場合、すべてのルールは同じタイプである必要があります。すべて通常、またはすべてダブルコロンです。それらが二重コロンである場合、それらのそれぞれは他から独立しています。ターゲットがそのルールの前提条件よりも古い場合、各ダブルコロンルールのコマンドが実行されます。そのルールの前提条件がない場合、そのコマンドは常に実行されます(ターゲットがすでに存在している場合でも)。これにより、ダブルコロンルールが実行されない、いずれか、またはすべて実行される可能性があります。

同じターゲットを持つダブルコロンルールは、実際には互いに完全に分離されています。異なるターゲットを持つルールが処理されるのと同じように、各ダブルコロンルールは個別に処理されます。

ターゲットのダブルコロンルールは、メイクファイルに表示される順序で実行されます。ただし、ダブルコロンルールが実際に意味をなす場合は、コマンドの実行順序が重要ではない場合です。

ダブルコロンルールはややあいまいで、あまり有用ではありません。これらは、ターゲットの更新に使用される方法が、更新の原因となった前提条件ファイルによって異なる場合のメカニズムを提供し、そのような場合はまれです。

各ダブルコロンルールはコマンドを指定する必要があります。そうでない場合は、適用される場合は暗黙のルールが使用されます。セクション「暗黙のルールの使用」を参照してください。

このセクションの各文の意味を個別に理解しましたが、ダブルコロン規則が何のためにあるのかはまだわかりません。まれなことですが、Makefileがnotで始まるオープンソースプロジェクトはまだ見たことがありません。

all::

したがって:Makefileのダブルコロンルールの意図された目的は何ですか?

33
lindelof

::各ルールは個別に処理されるため、より簡単になります。たとえば、単一のルール:

libxxx.a : sub1.o sub2.o
    ar rv libxxx.a sub1.o
    ar rv libxxx.a sub2.o

2つのより単純なルールに置き換えることができます。

libxxx.a :: sub1.o
    ar rv libxxx.a sub1.o

libxxx.a :: sub2.o
    ar rv libxxx.a sub2.o

AutoMakeのようなユーティリティは、いくつかの複雑なルールよりも多くの単純なルールを簡単に吐き出すことができます。

より多くの例を含む素晴らしい回答が投稿され、削除され、ここで見つかりました:

https://web.archive.org/web/20180122002430/http://owen.sj.ca.us/~rk/howto/slides/make/slides/makecolon.html

R.K.に感謝しますそれを書いたオーウェンと、それを再び見つけたエドワード・ミニックス!

15

二重コロンが役立つ状況は3つあります。

  1. どの前提条件がターゲットよりも新しいかに基づいて、コンパイルルールを交互に切り替えます。次の例は、 http://books.gigatux.nl/mirror/cinanutshell/0596006977/cinanut-CHP-19-SECTの「例19-3。ダブルコロンルール」に基づいています。 -3.html

サンプル.cファイル:

c@desk:~/test/circle$ cat circle.c 
#include <stdio.h>

int main (void)
{
  printf("Example.\n");
  return 0;
}

使用されるMakefile:

c@desk:~/test/circle$ cat Makefile 
# A makefile for "circle" to demonstrate double-colon rules.

CC = gcc
RM = rm -f
CFLAGS = -Wall -std=c99
DBGFLAGS = -ggdb -pg
DEBUGFILE = ./debug
SRC = circle.c

circle :: $(SRC)
        $(CC) $(CFLAGS) -o $@ -lm $^

circle :: $(DEBUGFILE)
        $(CC) $(CFLAGS) $(DBGFLAGS) -o $@ -lm $(SRC)

.PHONY : clean

clean  :
        $(RM) circle

結果:

c@desk:~/test/circle$ make circle
gcc -Wall -std=c99 -o circle -lm circle.c
make: *** No rule to make target 'debug', needed by 'circle'.  Stop.
c@desk:~/test/circle$ make circle
gcc -Wall -std=c99 -o circle -lm circle.c
gcc -Wall -std=c99 -ggdb -pg -o circle -lm circle.c
c@desk:~/test/circle$ vim circle.c 
c@desk:~/test/circle$ make circle
gcc -Wall -std=c99 -o circle -lm circle.c
c@desk:~/test/circle$ vim debug 
c@desk:~/test/circle$ make circle
gcc -Wall -std=c99 -ggdb -pg -o circle -lm circle.c
  1. パターンルール端末を作成します。

次の例は、この状況を説明しています。a.configファイルはa.cfgから取得され、a.cfgはa.cfg1から取得されます(a.cfgは中間ファイルです)。

c@desk:~/test/circle1$ ls
a.cfg1  log.txt  Makefile
c@desk:~/test/circle1$ cat Makefile 
CP=/bin/cp

%.config:: %.cfg
        @echo "$@ from $<"
        @$(CP) $< $@

%.cfg: %.cfg1
        @echo "$@ from $<"
        @$(CP) $< $@

clean:
        -$(RM) *.config

結果(%.configルールはターミナルであるため、makeはa.cfg1からの中間a.cfgファイルの作成を禁止します):

c@desk:~/test/circle1$ make a.conf
make: *** No rule to make target 'a.conf'.  Stop.

%.configに二重コロンがない場合、結果は次のようになります。

c@desk:~/test/circle1$ make a.config
a.cfg from a.cfg1
a.config from a.cfg
rm a.cfg
  1. 常に実行されるルールを作成します(クリーンなルールに役立ちます)。ルールに前提条件があってはなりません!

c @ desktop:〜/ test/circle3 $ cat Makefile

CP=/bin/cp  
a.config::  
    @echo "Always" >> $@  

a.config::  
    @echo "Always!" >> $@  

clean:  
    -$(RM) *.config  

結果:

c@desk:~/test/circle3$ make a.config
c@desk:~/test/circle3$ cat a.config 
Always
Always!
c@desk:~/test/circle3$ make a.config
c@desk:~/test/circle3$ cat a.config
Always
Always!
Always
Always!
8
zcostin

ドキュメントに記載されているように、ダブルコロンルールが非常に役立つことはめったにありません。これらは、複合偽の​​ターゲットの個々のターゲットに名前を付けないための優れた小さな方法です(すべての::のように)が、この役割では実際には必要ありません。私はそれらが必要な場合に1つの不自然な例しか形成できません:

他のいくつかのログファイルL1、L2、...から連結されたログファイルLがあるとします。次のようないくつかのダブルコロンルールを作成します。

L :: L1
     cat $< >> $@ && rm $<

L :: L2
     cat $< >> $@ && rm $<

最近のGNU makeでは、もちろんこの種の魔法には$^を使用しますが、GNU make'sにインスピレーションを得た機能としてリストされています。機能タブ。

5
thiton

これらは、非再帰的なメイクファイルやcleanのようなターゲットに便利です。つまり、個々の.mkファイルは、他の場所ですでに定義されているcleanターゲットに独自のコマンドを追加できます。

ドキュメント 答えがあります:

ダブルコロンルールはややあいまいで、あまり有用ではありません。 ターゲットの更新に使用される方法が、更新の原因となった前提条件ファイルによって異なる場合のメカニズムを提供します。そのような場合はまれです。

5

使用法を明確にするために、簡単な例を提供します。

次のmakefileを試してください。

  a.faux:: dep1.fake
      $(info run a dep1.fake)
      touch a.faux

  a.faux:: dep2.fake
      $(info run a dep2.fake)
      touch a.faux

  dep1.fake:
      touch dep1.fake

  dep2.fake:
      touch dep2.fake

make a.fauxを実行すると、dep1.fakedep2.fakeが実行されます。 dep1.fakeを削除してmake a.fauxを再度実行すると、dep1.fakeのみが実行されます。

0
Zhengyang