【发布时间】:2012-08-31 05:33:10
【问题描述】:
在以下 Makefile 定义中:
- 倒数第二行中的
$$@代表什么? - 中间行的
|符号呢?
define KERNEL_RULE
$(DESTDIR)/$(1) : kernel_modules
$(DEST_DIR)/$(1) : $(DESTDIR)/$(1) | $(DEST_DIR)
cp $(DESTDIR)/$(1) $$@
endef
【问题讨论】:
标签: makefile
在以下 Makefile 定义中:
$$@ 代表什么?| 符号呢?define KERNEL_RULE
$(DESTDIR)/$(1) : kernel_modules
$(DEST_DIR)/$(1) : $(DESTDIR)/$(1) | $(DEST_DIR)
cp $(DESTDIR)/$(1) $$@
endef
【问题讨论】:
标签: makefile
(您有一个可悲的变量名选择;让我们将DESTDIR 更改为SOURCE_DIR 并保留DEST_DIR。)
假设您正在编写一个普通规则:
$(DEST_DIR)/foo : $(SOURCE_DIR)/foo
cp $(SOURCE_DIR)/foo $(DEST_DIR)/foo
这行得通,但冗余很麻烦。迟早你会在 preq 中更改 $(DEST_DIR)/foo 但忘记在规则中更改它。而且规则很难阅读。所以我们输入了automatic variable:
$(DEST_DIR)/foo : $(SOURCE_DIR)/foo
cp $(SOURCE_DIR)/foo $@
当此规则运行时,$@ 将扩展为目标名称$(DEST_DIR)/foo。 (我们还可以做得更好,但我们就到此为止吧。)
现在我们要确保 $(DEST_DIR) 在此规则运行之前存在,但我们不希望它完全是先决条件,因为缺少该目录应该不够使此规则运行。所以我们把它设为order-only prerequisite:
$(DEST_DIR)/foo : $(SOURCE_DIR)/foo | $(DEST_DIR)
cp $(SOURCE_DIR)/foo $@
现在我们需要很多这样的规则,针对不同的目标,而不是 the smart way,我们将使用 "canned recipe",一种用于动态创建规则的模板。
# 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 调用此定义时,$$@ 扩展为 $@,然后如果/当它运行规则时,$@ 将扩展为目标的名称。
【讨论】: