如果 Make 规则失败,则删除目标文件的优雅方法
Elegant way to remove target file if a Make rule fails
我的 Makefile 中有一条规则,大致如下所示:
target_file: src_file
some_tool src_file > target_file
(当然,现实中我用的是$@
和$<
,不过这道题我更喜欢直白的风格。)
问题是 target_file
总是由带有新时间戳的 shell 创建,即使 some_tool
失败。在那种情况下,存在一个空的 target_file
,即使我修复了潜在的问题,它也不会重建,直到我手动删除 target_file
或触摸 src_file
.
此外,some_tool
仅写入标准输出,因此我无法通过 some_tool ... -o target_file
.
等更简洁的方法解决此问题
我目前的做法是删除
target_file: src_file
some_tool src_file > target_file || rm -f target_file
然而,这有一个缺点,如果 some_tool
失败,Make
不会注意到,因为在那种情况下 rm
接管并且 returns exitcode 0(成功).
另一种方法可能是:
target_file: src_file
some_tool src_file > target_file.tmp
mv target_file.tmp target_file
但是那种代码很乏味,失败时会留下一个烦人的文件 target_file.tmp
。
有没有更优雅的方法解决这个问题?
您可以使用 special target .DELETE_ON_ERROR
:
If .DELETE_ON_ERROR is mentioned as a target anywhere in the makefile, then make will delete the target of a rule if it has changed and its recipe exits with a nonzero exit status, just as it does when it receives a signal.
只需要一行:
.DELETE_ON_ERROR:
所有失败的规则都将删除其目标。
我的 Makefile 中有一条规则,大致如下所示:
target_file: src_file
some_tool src_file > target_file
(当然,现实中我用的是$@
和$<
,不过这道题我更喜欢直白的风格。)
问题是 target_file
总是由带有新时间戳的 shell 创建,即使 some_tool
失败。在那种情况下,存在一个空的 target_file
,即使我修复了潜在的问题,它也不会重建,直到我手动删除 target_file
或触摸 src_file
.
此外,some_tool
仅写入标准输出,因此我无法通过 some_tool ... -o target_file
.
我目前的做法是删除
target_file: src_file
some_tool src_file > target_file || rm -f target_file
然而,这有一个缺点,如果 some_tool
失败,Make
不会注意到,因为在那种情况下 rm
接管并且 returns exitcode 0(成功).
另一种方法可能是:
target_file: src_file
some_tool src_file > target_file.tmp
mv target_file.tmp target_file
但是那种代码很乏味,失败时会留下一个烦人的文件 target_file.tmp
。
有没有更优雅的方法解决这个问题?
您可以使用 special target .DELETE_ON_ERROR
:
If .DELETE_ON_ERROR is mentioned as a target anywhere in the makefile, then make will delete the target of a rule if it has changed and its recipe exits with a nonzero exit status, just as it does when it receives a signal.
只需要一行:
.DELETE_ON_ERROR:
所有失败的规则都将删除其目标。