Pregunta

Me pregunto si hay una manera de poner en práctica trap en make GNU, similar a la incorporada en BASH?

Si el usuario pulsa CTRL-C, o si make misma falla (no nula salida), me gustaría llamar a un objetivo o macro en particular.

¿Fue útil?

Solución

No. el manejo de señales de GNU make ya deja mucho que desear. Desde el interior de su manejador de señales, que llama a funciones como printf que no son seguros para ser llamado desde un controlador de señales. He visto a este causa problemas, por ejemplo, reglas .DELETE_ON_ERROR no siempre se ejecutan si stderr se redirige a stdout.

Por ejemplo, en una caja de CentOS 7.4:

  1. Cree el siguiente Makefile:

    .DELETE_ON_ERROR:
    
    foo:
            touch $@
            sleep 10
    
  2. Abre en vim y correr :make,

  3. Si bien está durmiendo, golpeó Ctrl - C

Vim / hacer impresiones

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

Interrupt: Press ENTER or type command to continue

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

Otros consejos

En este punto en el tiempo, GNU make 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 el $(MAKE) por lo que anula la línea de órdenes y hacer que las opciones se pasan a submake.

En la trampa:

  • manejador trampa clara (con -)
  • hacer la limpieza
  • salida con el código de salida distinto de cero, por lo que la construcción de herramientas de automatización informan 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.

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, todos los contenedores son detenidos.

pero no rm los contenedores dejado como docker run --rm haría, por lo que aún se pueden ver a docker ps -a.)

Hacer no lo soporta, pero utilizando trucos BASH se 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 el "hacer" completa. Esto suele ser una solución satisfactoria si está intentando a las operaciones de limpieza que pueden ocurrir durante la construcción, pero no se limpian normalmente al salir "hacer".

No. Por lo que yo sé que no hay tal funcionalidad.

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

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top