为什么从 Makefile 调用时 diff 会失败?

为什么从 Makefile 调用时 diff 会失败?

我正在尝试解决的补丁问题的缩小范围:只有两个文件,每个文件的大小为 1 个字节:

  • 文件a(包含'a'
  • 文件b(包含'b')和

'b'目标是制作并应用一个补丁来更改to的值'a'。 Makefile 的内容是:

patch:
        diff -u b a > b2a.patch
        patch -o b.corrected b < b2a.patch
        diff a b.corrected

clean:
        rm -f b2a.patch b.corrected

鉴于上述情况,make失败并显示以下输出:

$ make
diff -u b a > b2a.patch
make: *** [patch] Error 1

但是,如果我在 bash shell 上逐个执行 Makefile 中的命令,则完全没有问题。

答案1

Make 假定退出代码 0 表示成功,其他值表示失败。这是几乎所有命令行工具使用的标准约定。

不幸的是,diff不是其中之一。检查 GNU diff 信息页面,以及单个 Unix 规范“diff”条目,0表示没有发现差异,1表示发现差异,≥2表示有错误。

您可以通过在命令前加上连字符来告诉 Make 完全忽略退出状态,就像您在评论中所做的那样,但这将忽略实际错误 - 可能不是您想要的。相反,您可以:

patch:
        diff -u b a > b2a.patch; [ $$? -eq 1 ]
        patch -o b.corrected b < b2a.patch
        diff a b.corrected; [ $$? -eq 1 ]

请注意; [ $$? -eq 1 ]我添加到两条差异行末尾的位。; test $$? -eq 1当然,您也可以使用。 shell$?变量是$$?由于正常的 Makefile 转义约定造成的。请注意,这也会拒绝退出状态 0(没有差异),这可能就是您想要的。

顺便说一句:看来这确实应该是:

patch: b.corrected
        diff …
b.corrected: b2a.patch
        patch …
b2a.patch: a b
        diff …

以便对 a 和 b 进行修改,并正确重新生成文件。

相关内容