调用 make 目标时指定通配符模式

Specifying wild card patterns when invoking make targets

假设我定义:

# makefile
.FORCE:

foo-bar: .FORCE
  @echo "$@"

foo-biz: .FORCE
  @echo "$@"

.PHONY: foo-bar foo-biz

然后我在命令行写:

$: make foo-bar foo-biz

那我有没有什么办法可以这样写:

$: make foo-*

例如?

这是一个主意。由于通配发生在 shell 甚至在 make 程序启动之前,您可以将存储库中的文件命名为您想要通配的规则:

touch foo-bar foo-biz
make foo-*
# executes 'make foo-bar foo-biz'

这也适用于真实文件(不仅仅是 .FORCE 或 PHONY),但前提是文件已经存在。

这有效,但它只支持原生 make 模式匹配的一个 % 通配符。而且我没有分析它对模式规则等的影响

PATTERN_GOALS := $(foreach g,$(MAKECMDGOALS),$(if $(findstring %,$(g)),$(g)))
force-on-pattern = $$(if $$(filter $(PATTERN_GOALS),$$@),$$(eval FORCE+=$$@))

# make FORCE a simple expanded variable
FORCE := 


.SECONDEXPANSION:

foo: $(force-on-pattern)
    echo $@

fooa: $(force-on-pattern)
    echo $@

fooab: $(force-on-pattern)
    echo $@

foob: $(force-on-pattern)
    echo $@

$(PATTERN_GOALS): $$(FORCE) ;

测试:

$ make foo%
fooab
fooa
foob
foo

$ make fooa%
fooab
fooa

$ make fooab%
fooab

$ make fooab
echo fooab
fooab

$ make foo%b
fooab
foob

您可以查看 GNUmake table toolkit,特别是 make-native glob 匹配器的 glob-match 函数,但正如@Beta 所注意到的,这是 'fearsome beast' make 编程.