Es difícil de creer, pero me parece que la expresión común de Makefile "> $ @" es incorrecta. En particular, un objetivo cuya regla tiene un comando que falla pero utiliza esta redirección fallará la primera vez, pero no las veces subsiguientes. Esto se debe a que, aunque el comando falla, la redirección "tiene éxito" en el sentido de crear un objetivo actualizado (aunque de longitud cero).
Me parece que lo correcto es redirigir a un temporal y, con éxito, renombrar este temporal al objetivo.
Aquí es ejemplo y Makefile:
bad-target:
command-that-will-fail > [email protected]
good-target:
command-that-will-fail > [email protected] || (rm [email protected]; false)
mv [email protected] [email protected]
clean:
rm -f bad-target good-target
Y aquí es una secuencia de comandos que ilustran el problema y su solución:
$ make clean
rm -f bad-target good-target
$ make bad-target
command-that-will-fail > bad-target
/bin/sh: command-that-will-fail: not found
make: *** [bad-target] Error 127
$ make bad-target
make: `bad-target' is up to date.
$ make good-target
command-that-will-fail > good-target.tmp || (rm good-target.tmp; false)
/bin/sh: command-that-will-fail: not found
make: *** [good-target] Error 1
$ make good-target
command-that-will-fail > good-target.tmp || (rm good-target.tmp; false)
/bin/sh: command-that-will-fail: not found
make: *** [good-target] Error 1
¡Bien, gracias! .DELETE_ON_ERROR es útil. –
¿Hay alguna manera de obtener el comportamiento DELETE_ON_ERROR solo para reglas específicas? – Will