如果文件不存在,我该如何避免Makefile失败?

3

我有几个文件之间存在依赖关系,其中一个文件是由另一个文件生成的。例如,需要用bar.txt生成foo-temp.xml,然后再生成最终的foo.xml文件。在我的Makefile中,表达如下:

foo-temp.xml: bar.txt
    do-magic -o foo-temp.xml bar.txt

foo.xml: foo-temp.xml
    do-more-magic -o foo.xml foo-temp.xml

只要所有文件都存在,一切都会顺利进行。但有时我会手动提供foo-temp.xml而不是从bar.txt生成它; 事实上,在这种情况下,bar.txt甚至不存在。
如何在我的Makefile中表达这种“不存在”,而不让它因为bar.txt不存在而失败?

这里或者在你的原始代码中,do-more-magic -o foo-temp.xml foo.xml 是一个错别字吗?难道不应该是 do-more-magic -o foo.xml foo-temp.xml 吗?虽然这并不影响这个问题。 - Etan Reisner
@EtanReisner:哎呀,你说得对,已经修复了。 - Jens
1个回答

0

我不确定这是最好的方法,但它应该可以工作(假设 bar.txt 本身不需要通过其他目标创建)。

foo-temp.xml: $(wildcard bar.txt)

wildcard函数返回与模式匹配的文件列表,并删除不匹配的文件。这也适用于没有通配符/模式匹配字符的文件名。

或者(更详细地说)

foo-temp.xml: $(and $(realpath bar.txt),bar.txt)

相同的基本思路,但是realpath返回一个“规范绝对名称”,因此您不能直接使用其结果(除非您想在那里使用绝对路径),因此我们使用and函数短路以仅在realpath返回非空值时生成输出。

如果需要生成bar.txt本身,那么这两种解决方案都不起作用,因为它将阻止bar.txt成为先决条件,除非它已经存在(但一旦存在,正常的make进程就会工作)。

如果是这种情况,那么您可以尝试使用make -o foo-temp.xml foo.xml告诉make foo-temp.xml是无限旧的,这应该短路使其不再尝试重新创建它(并处理它的先决条件),并应该让foo.xml: foo-temp.xml规则生效(假设foo.xml不存在或比您手动创建的foo-temp.xml旧)。


一个组合的方式起作用了。我实际上使用了 $(and ..) 函数,因为它允许我在全局变量上添加依赖项:$(and $(ROOTFILE), bla.txt),当主要的 $ROOTFILEbla.txt 存在时生成一个依赖关系。 - Jens
@Jens 是的,and 对于这样的条件非常有用。不过我有一个建议。在 make 上下文中避免使用多余的空格。它们并不总是在你期望的地方被剥离/忽略。因此,我建议使用 $(and $(ROOTFILE),bla.txt) 而不是 $(and $(ROOTFILE), bla.txt),即使我认为在这种情况下并没有什么影响。 - Etan Reisner
啊,我不知道!谢谢 :) - Jens

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接