Makefile 奇怪的变量替换

Mar*_*ila 6 make

我的Makefile看起来像这样:

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

test: *.foo
    echo *.foo
Run Code Online (Sandbox Code Playgroud)

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

cp b.bar *.foo
echo *.foo
*.foo
Run Code Online (Sandbox Code Playgroud)

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

我实际上期待看到这个:

cp a.bar a.foo
cp b.bar b.foo
echo *.foo
a.foo b.foo
Run Code Online (Sandbox Code Playgroud)

并且还创建a.foob.foo。如何做到这一点?

Ste*_*itt 8

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

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

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

test: $(foos)
    echo $(foos)
Run Code Online (Sandbox Code Playgroud)

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


Sat*_*hra 6

没有 *.foo 文件开始。所以 make 所做的是寻找如何使*.foo字面意思,而第一条规则就是这样做的。Make 扩展$<到第一个先决条件(*.barb.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
Run Code Online (Sandbox Code Playgroud)