我的Makefile
看起来像这样:
%.foo: %.bar
cp $< $@
test: *.foo
echo *.foo
我的目录中有 2 个文件:a.bar
和b.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.foo
和b.foo
.如何实现这一目标?
答案1
在这种情况下,您需要使用函数显式处理通配符wildcard
(至少在GNU 使):
%.foo: %.bar
cp $< $@
foos = $(patsubst %.bar,%.foo,$(wildcard *.bar))
test: $(foos)
echo $(foos)
$(wildcard *.bar)
扩展到所有以 结尾的文件.bar
,patsubst
调用替换.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