GNU Make 和通配符 - 缺少文件
Posted
技术标签:
【中文标题】GNU Make 和通配符 - 缺少文件【英文标题】:GNU Make and wildcards - missing files 【发布时间】:2010-12-01 05:30:30 【问题描述】:我有一个具有以下规则类型的 Makefile:
%.html:
./generate-images.py > $@
make $(patsubst %.png,%.gif,$(wildcard *.png))
generate-images
脚本不仅将 HTML 文件(至标准输出)写入当前目录,还将多个 .png 文件写入当前目录。这里的目标是将它们转换为 .gif。 (不是真的,但这是一个例子)
如果我直接调用它,这将有效。问题是:如果我从 foo.html
是依赖项的另一个规则调用它,则通配符语句无法找到任何文件。换句话说,它只是调用了make
,没有任何参数,这不是我想要的。
通配符有什么用?或者,有没有更好的方法来做到这一点?
【问题讨论】:
【参考方案1】:虽然您的问题可能有所不同,但我清楚地看到了一个。
同时处理规则中所有命令的整个文本,以便扩展make的函数和变量。假设您在目录中没有.png
文件,并且您调用make,因此它应该重新生成它们:a.png
和b.png
。然后,在您调用 make 之后,规则的文本实际上将如下所示:
file.html:
./generate-images.py > file.html
make
因为在读取 makefile 的那一刻没有.png
文件!第一行执行后,文件会出现,但下一行已经生成只是“make”。
只有当你第二次调用你的makefile时,它才会扩展为
file.html:
./generate-images.py > file.html
make a.gif b.gif
这不是你想要的。所以我建议以正确的方式来做。
# If you have batch conversion program, this may be helpful
images.stamp: *.png
convert_all_images $?
touch images.stamp
# OR, if you want convert one-by-one with means of make
images.stamp: $(wildcard *.png)
touch images.stamp
%.gif: %.png
convert_one --from=$^ --to=$@
# HTML would look like
%.html:
./generate-images.py > $@
make images.stamp
因此,当您调用make all
时,它会生成 html 并转换新生成的图像。请注意,它只会转换已更新的图像,这正是您想要的。
感谢 Beta 指出 gif/png 扩展的混乱。
【讨论】:
这就是我的帖子的目的。 +1 用于清楚地解释通配符问题,-1 用于过度复杂和错误的规则(即使在编辑之后),+1 用于令人惊讶的新见解:如果没有递归,你真的无法做到这一点! @Beta:我真的很想知道我的规则中有哪些错误!请给个提示——我会编辑我的答案并给你正确的归属。顺便说一句,实际上,您可以在没有递归的情况下做到这一点 :-) 这就是为什么我从我的帖子中删除了该声明 :-) 但这会使我的帖子更加复杂...... 您的 %.png:%.gif 规则应该是相反的,并且您的 images.stamp 规则将没有 preqs(并且不制作 gif),直到有人以另一种方式制作 gif。现在你怎么能在没有递归的情况下做到这一点(并且没有,例如,放入一个巨大的 Perl 脚本,它基本上是一个精简的 make 实现)?如果有办法,那你已经连续两次让我吃惊了! @Beta:我们可以使用重新加载 makefile 的能力来代替递归。如果我们写目标Makefile: htmls // touch Makefile
,处理htmls后make
会重新读取makefile,因为它已经更新了。然后它还会重新扩展我们的通配符。【参考方案2】:
这听起来像是在处理Makefile
时评估所有$()
表达式,而不是在执行每个规则时。您可以像这样向您的 makefile 添加规则:
images: $(patsubst %.png,%.gif,$(wildcard *.png))
.PHONY: images
然后将您的示例 sn-p 更改为
%.html:
./generate-images.py > $@
make images
以便 Make 在正确的时间评估 glob。这是值得查看手册的内容。
【讨论】:
以上是关于GNU Make 和通配符 - 缺少文件的主要内容,如果未能解决你的问题,请参考以下文章