Makefile 奇怪的变量替换

Makefile 奇怪的变量替换

我的Makefile看起来像这样:

%.foo: %.bar
    cp $< $@

test: *.foo
    echo *.foo

我的目录中有 2 个文件:a.barb.bar.当我运行make test它时输出:

cp b.bar *.foo
echo *.foo
*.foo

*.foo它还会在当前目录中创建一个文件。

我其实很期待看到这个:

cp a.bar a.foo
cp b.bar b.foo
echo *.foo
a.foo b.foo

并且还创建a.foob.foo.如何实现这一目标?

答案1

在这种情况下,您需要使用函数显式处理通配符wildcard(至少在GNU 使):

%.foo: %.bar
    cp $< $@

foos = $(patsubst %.bar,%.foo,$(wildcard *.bar))

test: $(foos)
    echo $(foos)

$(wildcard *.bar)扩展到所有以 结尾的文件.barpatsubst调用替换.bar.foo,然后所有目标都按照您的预期进行处理。

答案2

开始时没有 *.foo 文件。所以 make 所做的就是寻找如何*.foo从字面上进行 make,而第一条规则就是这样做的。 Make 扩展$<到第一个先决条件( ,在本例中*.bar恰好是)。b.bar然后 Make 运行 shell 命令cp b.bar *.foo。由于没有 *.foo,shell 将其扩展为cp b.bar *.foo字面意思。这就是您获取*.foo文件的方式。

您可以通过运行来验证这一点make -d test

您可以通过根据先决条件列表生成目标列表来获得您想要的效果。

TARGETS = $(patsubst %.bar,%.foo,$(wildcard *.bar))
%.foo: %.bar
    @cp $< $@
test: $(TARGETS)
    @echo $(TARGETS)
    echo *.foo

相关内容