Makefile静态模式规则匹配问题
Makefile static pattern rule matching issue
我认为我缺少一些关于 gnu make 的基本知识(如果重要的话,我正在使用 3.81)静态模式规则匹配(显然其他人也在我工作的地方做了,因为这是我发现的正在尝试修复已被注释掉的规则)。我试图将我的例子简化到它的症结所在(希望我没有错过真实例子中的任何重要内容)。
这似乎符合我的预期
JUNK:=foo bar
BINS:=$(patsubst %,bin/%,$(JUNK))
all : $(BINS)
.PHONY : all
# This works
$(BINS) : bin/% : %
mkdir -p bin && cp $< $@
但是这个(更接近我在真正的 Makefile 中找到的)
JUNK:=foo bar
BINS:=$(patsubst %,bin/%,$(JUNK))
all : $(BINS)
.PHONY : all
# This doesn't work
$(JUNK) : bin/% : %
mkdir -p bin && cp $< $@
# This doesn't work either
#bin/$(JUNK) : bin/% : %
# mkdir -p bin && cp $< $@
根据我对这两种情况下应该发生的情况的理解,我预计两个 Makefile 的行为将完全相同;然而,只有第一个的行为符合我的预期(即,将文件正确复制到 bin),第二个给出以下输出
Makefile:12: target `foo' doesn't match the target pattern
Makefile:12: target `bar' doesn't match the target pattern
make: *** No rule to make target `bin/foo', needed by `all'. Stop.
更令人困惑的是,我正在检查的 make 文件中有几乎相同的其他静态模式规则在起作用。
所以我显然知道如何 "work around" 这个问题,但我想了解为什么第二个(以及第二个代码块中注释掉的部分)不做我想做的事期待他们。
提前感谢任何help/insight。
第一个不起作用,因为在扩展 JUNK
变量后,make 会看到:
foo bar : bin/% : %
静态模式规则的工作方式是第一个模式(目标模式)必须匹配目标列表中的每个单词。这告诉 make 目标名称的哪一部分是词干(与 %
匹配的部分)。如果目标模式不匹配,make 不知道词干是什么。模式 bin/%
与文本 foo
不匹配(文本 foo
中没有 bin/
)所以您会看到错误。
第二个不起作用,因为在此示例 (bin/$(JUNK) : bin/% : %
) 中扩展 JUNK
变量的结果如下所示:
bin/foo bar : bin/% : %
此处,bin/foo
匹配模式,但 bar
不匹配,因此您会得到与上一个相同的错误。
要使其正常工作,您必须将 bin/
添加到 每个 目标,而不仅仅是第一个目标,因此使用 patsubst
(或者, addprefix
也可以。
我认为我缺少一些关于 gnu make 的基本知识(如果重要的话,我正在使用 3.81)静态模式规则匹配(显然其他人也在我工作的地方做了,因为这是我发现的正在尝试修复已被注释掉的规则)。我试图将我的例子简化到它的症结所在(希望我没有错过真实例子中的任何重要内容)。
这似乎符合我的预期
JUNK:=foo bar
BINS:=$(patsubst %,bin/%,$(JUNK))
all : $(BINS)
.PHONY : all
# This works
$(BINS) : bin/% : %
mkdir -p bin && cp $< $@
但是这个(更接近我在真正的 Makefile 中找到的)
JUNK:=foo bar
BINS:=$(patsubst %,bin/%,$(JUNK))
all : $(BINS)
.PHONY : all
# This doesn't work
$(JUNK) : bin/% : %
mkdir -p bin && cp $< $@
# This doesn't work either
#bin/$(JUNK) : bin/% : %
# mkdir -p bin && cp $< $@
根据我对这两种情况下应该发生的情况的理解,我预计两个 Makefile 的行为将完全相同;然而,只有第一个的行为符合我的预期(即,将文件正确复制到 bin),第二个给出以下输出
Makefile:12: target `foo' doesn't match the target pattern
Makefile:12: target `bar' doesn't match the target pattern
make: *** No rule to make target `bin/foo', needed by `all'. Stop.
更令人困惑的是,我正在检查的 make 文件中有几乎相同的其他静态模式规则在起作用。
所以我显然知道如何 "work around" 这个问题,但我想了解为什么第二个(以及第二个代码块中注释掉的部分)不做我想做的事期待他们。
提前感谢任何help/insight。
第一个不起作用,因为在扩展 JUNK
变量后,make 会看到:
foo bar : bin/% : %
静态模式规则的工作方式是第一个模式(目标模式)必须匹配目标列表中的每个单词。这告诉 make 目标名称的哪一部分是词干(与 %
匹配的部分)。如果目标模式不匹配,make 不知道词干是什么。模式 bin/%
与文本 foo
不匹配(文本 foo
中没有 bin/
)所以您会看到错误。
第二个不起作用,因为在此示例 (bin/$(JUNK) : bin/% : %
) 中扩展 JUNK
变量的结果如下所示:
bin/foo bar : bin/% : %
此处,bin/foo
匹配模式,但 bar
不匹配,因此您会得到与上一个相同的错误。
要使其正常工作,您必须将 bin/
添加到 每个 目标,而不仅仅是第一个目标,因此使用 patsubst
(或者, addprefix
也可以。