2009-06-10 6 views

Respuesta

2

No. El manejo de señal de GNU make ya deja mucho que desear. Desde dentro de su manejador de señal, llama a funciones como printf que no son seguras para llamar desde un manejador de señal. He visto esto causar problemas, por ejemplo .DELETE_ON_ERROR reglas no siempre se ejecutan si stderr se redirige a stdout.

Por ejemplo, en un CentOS 7.4 cuadro:

  1. Cree el siguiente Makefile:

    .DELETE_ON_ERROR: 
    
    foo: 
         touch [email protected] 
         sleep 10 
    
  2. abrirlo en vim y ejecutar :make,

  3. Si bien está durmiendo, pulse Ctrl - C

Vim/obtener impresiones de

Press ENTER or type command to continue 
touch foo 
sleep 10 
^C 
shell returned 130 

Interrupt: Press ENTER or type command to continue 

estructural se envió una señal de interrupción, pero foo todavía existe.

+0

¿Tiene algunos ejemplos en los que el '.DELETE_ON_ERROR' no funciona? ¿Es eso un error en la implementación de make? –

+0

@HakanBaba Detalles agregados. – andrewdotn

1

No. Por lo que yo sé, no existe tal funcionalidad.

1

produce produce códigos de retorno. Por lo que puedo recordar en este momento, devuelve 0 para el éxito, 2 para el fracaso (consulte la documentación). Por lo tanto, ¿sería suficiente para usted envolver hacer dentro de un script de shell por ejemplo?

+1

Puedo hacerlo, pero, si es posible, lo intento evitar, es autónomo y estoy * intentando * mantenerlo así. – Cyrus

2

Make no lo admite, pero al usar los trucos de BASH puede lograr algo similar.

default: complete 

complete: do_mount 
     echo "Do something here..." 

do_mount: 
     mkdir -p "$(MOUNTPOINT)" 
     (while ps -p $$PPID >/dev/null ; do \ 
       sleep 1 ; \ 
     done ; \ 
     unmount "$(MOUNTPOINT)" \ 
     ) & 
     mount "$(MOUNTSOURCE)" "$(MOUNTPOINT)" -o bind 

El "desmontar" se ejecutará después de que se complete la "marca". Esta suele ser una solución satisfactoria si está intentando realizar operaciones de limpieza que pueden ocurrir durante la construcción pero que no se limpian normalmente al salir de "make".

5

En este momento, la fabricación de GNU no tiene soporte nativo.

Hay una solución fiable sin embargo:

.PHONY: internal-target external-target 

external-target: 
    bash -c "trap 'trap - SIGINT SIGTERM ERR; <DO CLEANUP HERE>; exit 1' SIGINT SIGTERM ERR; $(MAKE) internal-target" 

internal-target: 
    echo "doing stuff here" 

Esto llama interrupciones, terminaciones y cualquier código de salida distinto de cero.

Tenga en cuenta $(MAKE), por lo que las anulaciones de línea de comando y las opciones de fabricación se pasan al submake.

En trampa:

  • manejador trampa clara (con -)
  • hacer la limpieza
  • de salida con el código de salida distinto de cero, por lo que construir herramientas de automatización de reportar la acumulación fallado.

DELETE_ON_ERROR no funciona para directorios, así que esto es clave para la limpieza después de mktemp -d, por ejemplo

Reemplazar <DO CLEANUP HERE> con CMD válida.

+0

Además de la cita anidada en su eco, que por supuesto son ilegales, esto no parece funcionar, al menos por lo que quiero lograr. ¿Cómo se supone que uno debe usarlo? Supongamos que mi archivo MAKE tiene solo un objetivo con un sueño y un toque, como el ejemplo de @andrewdotn (ignore .DELETE_ON_ERROR), ¿cómo lo modificaría para usar esta solución alternativa? – Davide

+0

Consulte ediciones. echo "haciendo cosas aquí" sería el sueño/toque. HAGA LIMPIEZA AQUÍ sería algo así como, echo que presionó ctrl-c – kevinf

3

Una versión simplificada de respuesta de @ kevinf que parece lo suficientemente bueno para casos básicos:

run: 
    bash -c "trap 'docker-compose down' EXIT; docker-compose up --build" 

(Este ejemplo es para una razón: docker-compose up Qué dice

Cuando las salidas de comando, todas los contenedores están detenidos.

pero no lo hace rm the stopped contai ners como docker run --rm, por lo que todavía puede verlos con docker ps -a.)

+0

Todavía veo 'receta para el objetivo 'ejecutar' falló ... hacer: *** [ejecutar] Interrumpir' cuando intento esto, y el objetivo de hacer no ejecuta el comando 'docker-compose down'. (Tengo el caso de uso exacto descrito en esta respuesta). – ely

Cuestiones relacionadas