【问题标题】:multi wildcard target in MakefileMakefile 中的多通配符目标
【发布时间】:2018-09-21 17:36:06
【问题描述】:

只是简单的 Makefile:

a/% b/%:
    @echo $@

当我这样做时

制作 a/a b/b

正如预期的那样:

一个/一个

b/b

但是当我这样做时

使a/a b/a

看来:

一个/一个

make: `b/a' 无事可做。

如何获得预期回报

一个/一个

b/a

在 Linux 和 macOS 上使用 v3.81 和 v3.82 版本进行测试

【问题讨论】:

  • .PHONY 无关。这是对实际 Makefile 的测试。即使简单的Makefile中有.PHONY: a/% b/%,也不生效。

标签: makefile gnu-make


【解决方案1】:

鉴于您的makefile...

a/% b/%:
        @echo $@

考虑调用make a/a b/b 时会发生什么。 make 注意到规则 a/% b/%: 与词干 a 匹配(即内置变量 $* 将是 a)并运行命令。因为您的规则有多个目标 make 现在认为 a/ab/a 都已更新。

Make 然后考虑在命令行b/b 上指定的下一个目标。这还没有更新,所以make 再次运行相同的规则,但使用了b 的词干。因此该规则运行了两次——每个模式词干ab 运行一次。

现在考虑调用make a/a b/a 时会发生什么。这一次,两个目标将匹配相同的规则,但具有相同的词干a。因此make,在运行带有a 的规则后,认为a/ab/a 都已更新,并且认为不需要为第二个命令行目标b/a 重新运行规则。

尚不完全清楚您需要什么行为,但如果您希望为不同的目标多次调用相同的规则,即使模式词干是相同的,那么您可能需要类似...

# Possible targets (for illustration purposes).
#
TARGETS := a/a a/b b/a b/b

$(TARGETS): %:
        @echo $@

以上给出...

G.M.> make -f multi-wildcard-target-in-makefile.mk a/a b/b
一个/一个
b/b

G.M.> make -f multi-wildcard-target-in-makefile.mk a/a b/a
一个/一个
b/a

【讨论】:

  • 谢谢,我明白了。有没有办法让make 使用通配符目标多次运行?或者这是不可能的?像这样的实际规则
  • $(MAKE) -C $(@D) $(@F),所以我无法在 Makefile 中编写实际目标。 (茎未知)。
  • 抱歉,我不确定我是否了解您的 cmets。如果你能提供一个更具体的例子来说明你实际需要什么,我很乐意更新我的答案。
  • 我的意思是目标a/% b/%:的配方是$(MAKE) -C $(@D) $(@F)。所以词干%实际上是a/Makefileb/Makefile中的目标,这是出乎意料的。
【解决方案2】:

如果您不想将可能的目标硬编码为 G.M.建议,你可以创造一些魔法:

$ cat Makefile
define recipe
$(1):
    @echo $$@
endef

PATTERNS=a/% b/%
$(foreach pattern,$(PATTERNS),$(eval $(call recipe,$(pattern))))

测试:

$ make a/a b/a
a/a
b/a
$ make a/a b/b
a/a
b/b

GNU make docs 中描述了您观察到的行为:

模式规则可能有多个目标。与普通规则不同,这不会像许多具有相同先决条件和配方的不同规则一样起作用。如果模式规则有多个目标,make 知道规则的配方负责生成所有目标。该配方仅执行一次以生成所有目标。

【讨论】:

  • 谢谢,我明白了。这可以解决问题。但是如果make docs配方只执行一次就可以生成所有的目标。,为什么我描述中的make a/a b/b可以执行两次呢?
  • 对于给定的% 一次。首先,% 被评估为a,并且 make 将像 a/a b/a 一样执行规则。然后,make 需要构建b/b(按照你的要求),所以% 变成b 并且make 会像a/b b/b 一样执行规则。这就是 G.M.在他的回答中解释。
猜你喜欢
  • 2010-12-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-16
  • 1970-01-01
  • 2012-02-12
相关资源
最近更新 更多