makefile - instalar - make c
¿Por qué GNU hace eliminar un archivo (3)
Este es el comportamiento predeterminado de make. Cuando un comando devuelve un código de error (por ejemplo, un retorno distinto de cero), el objetivo de fabricación se elimina. Las directivas .PRECIOUS y .IGNORE de archivo MAKE pueden cambiar este comportamiento.
Tengo un archivo make ligeramente hackish para ejecutar pruebas:
### Run the tests
tests := tests/test1 tests/test2 ...
test: $(tests)
$(tests): %: %.c
gcc -o $@ $(testflags) $<
$@
Funciona, pero hace que Haz algo que nunca antes había visto. Mi prueba actualmente está rota y causa un error de bus. Make da el siguiente resultado:
gcc -o tests/test1 [flags blah blah] tests/test1.c
tests/test1
make: *** [tests/test1] Bus error
make: *** Deleting file `tests/test1''
Tengo curiosidad sobre la última línea. Nunca he visto Hacer eso antes. ¿Por qué Make elimina la prueba compilada?
Nota: edité este ejemplo bastante para simplificarlo. Podría haber introducido algunos errores.
Una forma de evitar este comportamiento es dividir la compilación y la ejecución de prueba en dos pasos:
tests := tests/test1 tests/test2 ...
test: $(tests) runtests
$(tests): %: %.c
gcc -o $@ $(testflags) $<
runtests: %.out: %
$< | tee $@
(Probablemente haya errores en mi sintaxis make, cualquiera puede corregirlo). La idea general es hacer que la ejecución de prueba genere un archivo de salida, lo que facilita la ejecución de cada prueba individualmente.
Porque el objetivo podría no haberse construido correctamente. La próxima vez que make
el proyecto, intentará reconstruir el objetivo. Si el archivo no se ha eliminado, make
no tendría manera de saber que algo salió mal. make
no puede saber que la falla provino de una prueba en lugar del proceso que genera el objetivo.
Si este comportamiento es o no deseable en su caso depende de la naturaleza de las pruebas. Si planeas arreglar la prueba para que no cause un Bus error
, eliminar el objetivo no es un gran problema. Si desea utilizar el destino para la depuración más adelante, deberá realizar un cambio en su proceso de creación.
Una forma de no borrar objetivos es usar el objetivo .PRECIOUS
.
Otro podría ser:
$(tests): %: %.c
gcc -o $@ $(testflags) $<
-$@
No probado, pero la documentación indica que el objetivo no se eliminará:
Cuando ocurre un error que a make no se le ha dicho que ignore, implica que el objetivo actual no puede rehacerse correctamente, y tampoco puede hacerlo cualquier otro que dependa de él directa o indirectamente. No se ejecutarán más comandos para estos objetivos, ya que sus condiciones previas no se han logrado.
y:
Por lo general, cuando falla un comando, si ha cambiado el archivo de destino, el archivo está dañado y no se puede usar, o al menos no se ha actualizado completamente. Sin embargo, la marca de tiempo del archivo dice que ahora está actualizado, por lo que la próxima vez que se ejecute, no intentará actualizar ese archivo. La situación es la misma que cuando una señal mata al comando; ver interrupciones. Por lo tanto, generalmente lo correcto es eliminar el archivo de destino si el comando falla después de comenzar a cambiar el archivo. make hará esto si .DELETE_ON_ERROR aparece como un objetivo. Esto es casi siempre lo que quieres hacer, pero no es una práctica histórica; por lo tanto, para compatibilidad, debe solicitarlo explícitamente.