Domanda

Mi chiedo se c'è un modo per implementare trap in GNU make, simile a quello integrato in BASH?

Se l'utente preme CTRL-C, o se make stessa fallisce (non zero uscita), mi vuoi chiamare un particolare bersaglio o macro.

È stato utile?

Soluzione

No. gestione del segnale di GNU make lascia già molto a desiderare. Da dentro il suo gestore di segnale, che chiama le funzioni come printf che non sono sicuri di essere chiamato dall'interno di un gestore di segnale. Ho visto questo causa problemi, per le regole .DELETE_ON_ERROR esempio non sempre correre se stderr viene reindirizzato a stdout.

Per esempio, su una scatola di CentOS 7.4:

  1. Creare la seguente Makefile:

    .DELETE_ON_ERROR:
    
    foo:
            touch $@
            sleep 10
    
  2. Aprire in vim ed eseguire :make,

  3. Anche se sta dormendo, ha colpito Ctrl - C

Vim / make stampe

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

Interrupt: Press ENTER or type command to continue

make è stato inviato un segnale di interrupt, ma foo esiste ancora.

Altri suggerimenti

A questo punto nel tempo, GNU make non ha il supporto nativo.

C'è una soluzione affidabile per quanto:

.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"

Questa cattura interruzioni, cessazioni e gli eventuali codici di uscita diverso da zero.

Si noti la $(MAKE) così le sostituzioni cmdline e rendere le opzioni vengono passati al submake.

In trappola:

  • gestore di trap chiaro (con -)
  • fare la pulizia
  • uscita con diverso da zero stato di uscita, in modo da costruire strumenti di automazione riportano la generazione non riuscita.

DELETE_ON_ERROR non funziona per le directory, quindi questa è la chiave per la pulizia dopo mktemp -d, ad esempio

Sostituire <DO CLEANUP HERE> con valida CMD.

Una versione semplificata di @ di kevinf risposta che sembra abbastanza buono per i casi di base:

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

(Questo esempio è per un motivo: docker-compose up fa dire

  

Quando   il comando termina, tutti i contenitori vengono arrestati.

ma non rm i contenitori smesso come docker run --rm sarebbe, in modo da poter ancora li vedi con docker ps -a.)

make non lo supporta, ma che utilizzano trucchi BASH si può realizzare qualcosa di simile.

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

Il "smontare" verrà eseguito dopo il "fare" completa. Questo è di solito una soluzione soddisfacente, se si sta tentando di operazioni di pulizia che si possono verificare durante la compilazione, ma non vengono pulite normalmente in uscita "fare".

No. Per quanto ne so non c'è tale funzionalità.

marca produce codici di ritorno. Per quanto posso ricordare in questo momento, restituisce 0 per il successo, 2 per il fallimento (si prega di verificare la documentazione). Pertanto, sarebbe sufficiente per avvolgere fare all'interno di uno script di shell per esempio?

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top