【问题标题】:What does $$@ and the pipe symbol in Makefile stand for?Makefile 中的 $$@ 和管道符号代表什么?
【发布时间】:2012-08-31 05:33:10
【问题描述】:

在以下 Makefile 定义中:

  1. 倒数第二行中的$$@ 代表什么?
  2. 中间行的| 符号呢?
define KERNEL_RULE
$(DESTDIR)/$(1) : kernel_modules
$(DEST_DIR)/$(1) : $(DESTDIR)/$(1) | $(DEST_DIR)
    cp $(DESTDIR)/$(1) $$@
endef

【问题讨论】:

    标签: makefile


    【解决方案1】:

    (您有一个可悲的变量名选择;让我们将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 调用此定义时,$$@ 扩展为 $@,然后如果/当它运行规则时,$@ 将扩展为目标的名称。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-03-08
      • 1970-01-01
      • 2013-03-10
      • 2011-01-31
      • 1970-01-01
      相关资源
      最近更新 更多