40

次の Makefile 定義では、次のようになります。

  1. 最後から2行目のは何$$@を表していますか?
  2. |真ん中の線の記号はどうですか?
define KERNEL_RULE
$(DESTDIR)/$(1) : kernel_modules
$(DEST_DIR)/$(1) : $(DESTDIR)/$(1) | $(DEST_DIR)
    cp $(DESTDIR)/$(1) $$@
endef
4

1 に答える 1

92

DESTDIR(変数名の選択は嘆かわしいものです。変更してSOURCE_DIRそのままにしておきましょうDEST_DIR。)

通常のルールを書いているとします。

$(DEST_DIR)/foo : $(SOURCE_DIR)/foo
    cp $(SOURCE_DIR)/foo $(DEST_DIR)/foo

それは機能しますが、冗長性は面倒です。遅かれ早かれ$(DEST_DIR)/foopreq を変更しますが、ルールを変更するのを忘れます。そしてルールが読みにくい。そこで、自動変数を入れます:

$(DEST_DIR)/foo : $(SOURCE_DIR)/foo
    cp $(SOURCE_DIR)/foo $@

このルールが実行$@されると、 はターゲットの名前に展開され$(DEST_DIR)/fooます。(それ以上のこともできますが、ここでやめましょう。)

ここで$(DEST_DIR)、このルールが実行される前に が存在することを確認したいのですが、それを正確に前提条件にしたくはありません。なぜなら、そのディレクトリが存在しないことは、このルールを実行するのに十分ではないからです。したがって、注文のみの前提条件にします。

$(DEST_DIR)/foo : $(SOURCE_DIR)/foo | $(DEST_DIR)
    cp $(SOURCE_DIR)/foo $@

ここで、さまざまなターゲットに対して、このような多くのルールが必要です。それをスマートな方法で行う代わりに、その場でルールを作成するための一種のテンプレートである「缶詰のレシピ」を使用します。

# This won't work
define KERNEL_RULE
$(SOURCE_DIR)/$(1) : kernel_modules
$(DEST_DIR)/$(1) : $(SOURCE_DIR)/$(1) | $(DEST_DIR)
    cp $(SOURCE_DIR)/$(1) $@
endef

問題は、この定義を評価$@すると が展開され、まだルールではないため、何も展開されないことです。したがって、次のように変更し$$@ます。

# This will work
define KERNEL_RULE
$(SOURCE_DIR)/$(1) : kernel_modules
$(DEST_DIR)/$(1) : $(SOURCE_DIR)/$(1) | $(DEST_DIR)
    cp $(SOURCE_DIR)/$(1) $$@
endef

Make がこの定義を呼び出すと、に$$@展開され$@、ルールが実行$@されると、ターゲットの名前に展開されます。

于 2012-09-06T13:05:41.817 に答える