次の Makefile 定義では、次のようになります。
- 最後から2行目のは何
$$@
を表していますか? |
真ん中の線の記号はどうですか?
define KERNEL_RULE
$(DESTDIR)/$(1) : kernel_modules
$(DEST_DIR)/$(1) : $(DESTDIR)/$(1) | $(DEST_DIR)
cp $(DESTDIR)/$(1) $$@
endef
次の Makefile 定義では、次のようになります。
$$@
を表していますか?|
真ん中の線の記号はどうですか?define KERNEL_RULE
$(DESTDIR)/$(1) : kernel_modules
$(DEST_DIR)/$(1) : $(DESTDIR)/$(1) | $(DEST_DIR)
cp $(DESTDIR)/$(1) $$@
endef
DESTDIR
(変数名の選択は嘆かわしいものです。変更してSOURCE_DIR
そのままにしておきましょうDEST_DIR
。)
通常のルールを書いているとします。
$(DEST_DIR)/foo : $(SOURCE_DIR)/foo
cp $(SOURCE_DIR)/foo $(DEST_DIR)/foo
それは機能しますが、冗長性は面倒です。遅かれ早かれ$(DEST_DIR)/foo
preq を変更しますが、ルールを変更するのを忘れます。そしてルールが読みにくい。そこで、自動変数を入れます:
$(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 がこの定義を呼び出すと、に$$@
展開され$@
、ルールが実行$@
されると、ターゲットの名前に展開されます。