vog vog - 1 year ago 53
Bash Question

Elegant way to remove target file if a Make rule fails

I have a rule in my Makefile that roughly looks like this:

target_file: src_file
some_tool src_file > target_file

(Of course, in reality I'm using
, but for this question I prefer a more explicit style.)

The problem is that
is always created by the shell with a fresh timestamp, even if
fails. In that case, an empty
exists, and even if I fix the underlying issue, it won't be rebuilt until I manually remove
or touch

only writes to standard output, so I can't work around this through a cleaner approach such as
some_tool ... -o target_file

My current approach is to remove

target_file: src_file
some_tool src_file > target_file || rm -f target_file

However, this has the disadvantage that
won't notice if
fails, because in that case
takes over and returns exitcode 0 (succeess).

Another approach may be:

target_file: src_file
some_tool src_file > target_file.tmp
mv target_file.tmp target_file

But that kind of code is tedious and on failure leaves an annoying file

Is there a more elegant way to solve this problem?

Answer Source

You could use the 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.

All it takes is one line:


And all rules that fail will have their target removed.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download