GNU make: Don't delete intermediate files on error that happened elsewhere

34 Views Asked by At

Say that I have a makefile:

.RECIPEPREFIX = +
.ONESHELL:

all: one

vars := one.a two.a three.a
.INTERMEDIATE: $(vars)

one: $(vars)
+ touch $@

%.a: %.b
+ touch $@

%.b:
+ if [ "$@" = "three.b" ];
+ then
+   exit 1;
+ fi
+ touch $@

and all the targets take a long time to finish. If everything goes well, none of the intermediates (defined explicitly or implicitly) will be preserved. And that's good.

But, say that one target signals an error. Makefile stops and removes all intermediate targets even though there was no error signalled for them.

Variations of this problem are even more annoying when make is run in parallel.

How to prevent removing intermediate targets that were created successfully?

1

There are 1 best solutions below

4
MadScientist On

If I'm understanding you correctly, this is what .SECONDARY is for.

You can read more info here: https://www.gnu.org/software/make/manual/html_node/Special-Targets.html and also here: https://www.gnu.org/software/make/manual/html_node/Chained-Rules.html

John points out I didn't notice your desire to keep the intermediate files being removed on if the build doesn't fail. I don't think there's any way to prevent make from deleting an intermediate file on failure, while still having it be deleted on success.

The only thing I can think of is to declare them .SECONDARY, then delete them yourself as part of your final recipe (for example, a recipe for the all target). That recipe is only run if all other recipes succeeded, and if you declare them .SECONDARY they won't be rebuilt if not needed. I'm not sure this will work as I haven't tried it.