Aquí podría ser tu PUBLICIDAD


Cómo hacer para eliminar archivos adicionales en caso de error

votos
7

Estamos discutiendo últimamente sobre la forma en que manejamos los archivos .d para las dependencias en nuestro proceso de compilación basado en make. Se ha planteado el problema de que a veces los archivos .d se pueden dañar cuando se interrumpen las compilaciones.

Estamos utilizando el destino .DELETE_ON_ERROR para garantizar que si una compilación se interrumpe o falla, se eliminan los archivos de objeto que estaba en proceso de generar. Sin embargo, también estamos usando GCC para generar archivos .d en tiempo de compilación, que también deberían eliminarse. No parece haber una forma directa de decir sobre esto.

Entonces, la pregunta es, ¿hay alguna manera de convencernos para eliminar nuestro objeto y nuestros archivos de dependencia en el caso de un error? ¿Hay alguna forma en que podamos configurar las reglas para que sepa que los archivos .d y .o se generan al mismo tiempo y deben eliminarse si hay un error?

Alternativamente, ¿hay algo más que podamos hacer para solucionar el problema de los archivos .d corruptos? Una sugerencia en este sentido es generar los archivos .d con un nombre temporal y tener un paso de compilación posterior por cada archivo que lo copie al nombre correcto.

Publicado el 12/03/2009 a las 20:11
fuente por usuario Dan Olson
En otros idiomas...        العربية       

2 respuestas

votos
6

En términos generales, GNU make no admite objetivos con múltiples salidas. Sin embargo, hay una excepción a esa regla: reglas de patrones. Si puede estructurar su archivo MAKE de modo que use reglas de patrones para generar los archivos objeto, puede lograr sus objetivos. Por ejemplo:

.DELETE_ON_ERROR:

all: foo.o

%.o %.d: %.c
    @touch $*.d
    @touch $*.o
    @exit 1

Verá que con este archivo MAKE cuando se detecta el "error" en la regla, se eliminan tanto el archivo .d como el archivo .o. La ventaja de este enfoque es que expresa con mayor precisión el gráfico de dependencia al describir cómo se generará el archivo .d y qué regla lo generará.

Alternativamente, un paradigma común en este caso es tal como lo sugirió: haga que GCC genere el archivo .d en un nombre de archivo temporal y muévalo solo en su lugar después de que el comando GCC se haya completado con éxito. Usualmente esto se logra con un truco del caparazón:

all: foo.o

%.o: %.c
    gcc -o $@ -MMD -MF $(basename $@).d.tmp -c $< \
        && mv $(basename $@).d.tmp $(basename $@).d

Aquí el truco "mágico" es el uso de los indicadores de GCC -MMD, que genera el archivo de dependencia como un efecto secundario de la compilación, y -MFque le permite especificar el nombre de salida para el archivo de dependencia; y el uso de la cmd1 && cmd2sintaxis del intérprete de comandos, que hace que el intérprete de comandos solo se ejecute cmd2si cmd1sale exitosamente.

Respondida el 12/03/2009 a las 09:22
fuente por usuario Eric Melski


Aquí podría ser tu PUBLICIDAD


votos
-1

Tengo ninguno de los ejemplos de Eric funcione correctamente. GCC (versión 4.4) no compila nada cuando se pasa en el interruptor-MM por lo que no se ve como se puede compilar y escribir el .d de una sola vez. Esto es lo que hice:

%.o: %.c
    @rm -f $@ $(patsubst %.o,%.d,$@)
    gcc -c $< -o $@
    @$(CXX) -MM -MG > $(patsubst %.o,%.d,$@)

Comienza por la eliminación de un archivo .d existente, la tercera línea que genera el nuevo sólo se ejecuta si el segundo comando, el paso de compilación real, tiene éxito (&& truco de Eric no es necesario, hacer que lo hace automáticamente). Por alguna razón que no entiendo, un archivo .o existente no se elimina automáticamente si la compilación falla, pero que se resolvió fácilmente mediante la adición $@a la primera rm.

Respondida el 19/04/2011 a las 08:53
fuente por usuario Wim