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?
If I'm understanding you correctly, this is what
.SECONDARYis 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 thealltarget). That recipe is only run if all other recipes succeeded, and if you declare them.SECONDARYthey won't be rebuilt if not needed. I'm not sure this will work as I haven't tried it.