Makefile 中的两个同名目标

Two targets with the same name in a Makefile

我想知道如果 Makefile 中有 2 个同名目标会发生什么:

根据 This question,有 2 个同名目标会引发警告。

但是,我不明白openwrt中的这个Makefile是如何工作的:

include/package.mk中:

define Build/DefaultTargets
$(if $(QUILT),$(Build/Quilt))
$(if $(USE_SOURCE_DIR)$(USE_GIT_TREE),,$(if $(strip $(PKG_SOURCE_URL)),$(call Download,default)))
$(call Build/Autoclean)

download:
    $(foreach hook,$(Hooks/Download),
    $(call $(hook))$(sep)
)

注意这里第 3 行对 Download 函数的调用和第 6 行 download 目标的定义。

通过查看 include/download.mk 中函数 Download 的定义:

define Download
  $(eval $(Download/Defaults))
  $(eval $(Download/$(1)))
  $(foreach FIELD,URL FILE $(Validate/$(call dl_method,$(URL),$(PROTO))),
  ifeq ($($(FIELD)),)
    $$(error Download/$(1) is missing the $(FIELD) field.)
  endif
)

$(foreach dep,$(DOWNLOAD_RDEP),
$(dep): $(DL_DIR)/$(FILE)
)
download: $(DL_DIR)/$(FILE)

我看到 download 目标被重新定义了。 我所知道的是,使用 call 将扩展功能,那么它是如何工作的?

如果在没有配方的情况下指定目标,它只是向目标添加依赖项。您可以随心所欲地使用这些。所以以下是有效的:

foo: dep1 dep2

foo: dep3
    recipe1

在这种情况下,如果重建 dep1、dep2 或 dep3,则 recipe1 为 运行。但这不是:

foo:
    recipe1

foo:
    recipe2

此时 make 不知道运行、and/or 的顺序,所以 Make 抱怨。 (请注意,pattern rules 可以有多个定义,在这种情况下,make 会选择第一个匹配的定义,但静态规则不允许这样做)