我的Makefile看起来像这样:
%.foo: %.bar
cp $< $@
test: *.foo
echo *.foo
Run Code Online (Sandbox Code Playgroud)
我在目录中有 2 个文件:a.bar和b.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.foo和b.foo。如何做到这一点?
在这种情况下,您需要使用wildcard函数(至少在GNU Make 中)显式处理通配符:
%.foo: %.bar
cp $< $@
foos = $(patsubst %.bar,%.foo,$(wildcard *.bar))
test: $(foos)
echo $(foos)
Run Code Online (Sandbox Code Playgroud)
$(wildcard *.bar)扩展到所有以 结尾的文件.bar,patsubst调用替换.bar为.foo,然后按照您的预期处理所有目标。
没有 *.foo 文件开始。所以 make 所做的是寻找如何使*.foo字面意思,而第一条规则就是这样做的。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
Run Code Online (Sandbox Code Playgroud)