Makefile中的多通配符目标

时间:2018-09-21 17:36:06

标签: makefile gnu-make

简单的Makefile:

a/% b/%:
    @echo $@

当我这样做

  

制作a / a b / b

可以按预期进行:

  

a / a

     

b / b

但是当我这样做

  

a / a b / a

看来:

  

a / a

     

make:'b / a'不需要做任何事情。

我如何获得期望的回报

  

a / a

     

b / a

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

2 个答案:

答案 0 :(得分:0)

给出您的makefile ...

a/% b/%:
        @echo $@

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

然后,Make考虑在命令行b/b中指定的下一个目标。尚未更新,因此make再次运行相同的规则,但使用茎b。因此,该规则运行两次-每个模式茎ab都运行一次。

现在考虑调用make a/a b/a时会发生什么。这次,两个目标都将匹配相同的规则,但具有相同的词干a。因此,make使用主干a运行规则后,认为a/ab/a均已更新,因此无需为第二个命令行目标{ {1}}。

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

b/a

上面给出了...

  

GM。> make -f multi-wildcard-target-in-makefile.mk a / a b / b
  a / a
  b / b

     

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

答案 1 :(得分:0)

如果您不想将可能的目标硬编码为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中进行了描述:

  

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