Pergunta

Eu estou querendo saber se há uma maneira de implementar trap em GNU make, semelhante ao construído em BASH?

Se o usuário pressiona CTRL-C, ou se a própria make falhar (não zero saída), eu gostaria de chamar um alvo particular ou macro.

Foi útil?

Solução

No. sinal do GNU make já manipulação deixa muito a desejar. De dentro de seu manipulador de sinal, ele chama funções como printf que não são seguros para ser chamado de dentro de um manipulador de sinal. Eu vi esta causa problemas, por exemplo regras .DELETE_ON_ERROR nem sempre correr se stderr é redirecionado para stdout.

Por exemplo, em um CentOS 7.4 caixa:

  1. Crie a seguinte Makefile:

    .DELETE_ON_ERROR:
    
    foo:
            touch $@
            sleep 10
    
  2. abri-lo no vim e correr :make,

  3. Embora seja dormindo, bateu Ctrl - C

Vim / fazer impressões

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

Interrupt: Press ENTER or type command to continue

Faça foi enviado um sinal de interrupção, mas foo ainda existe.

Outras dicas

Neste ponto no tempo, GNU make não tem suporte nativo.

Existe uma solução confiável no entanto:

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

Isso chama interrupções, terminações e quaisquer códigos de saída diferente de zero.

Observe o $(MAKE) assim substituições cmdline e opções de make são passadas para submake.

Na armadilha:

  • manipulador de interceptação clara (com -)
  • fazer a limpeza
  • exit com status de saída diferente de zero, então ferramentas de automação de construção relatar a compilação falhou.

DELETE_ON_ERROR não funciona para diretórios, então esta é a chave para a limpeza após mktemp -d, por exemplo

Substituir <DO CLEANUP HERE> com CMD válido.

Uma versão simplificada da resposta de @ kevinf que parece bom o suficiente para casos básicos:

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

(Este exemplo é por uma razão: docker-compose up diz

Quando as saídas de comando, todos os contêineres estão parados.

mas não rm os recipientes parado como docker run --rm seria, assim você ainda pode vê-los com docker ps -a.)

Faça não apoiá-lo, mas usando truques festança você pode realizar 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

O "dissociar" será executado depois da conclusão do "make". Esta é geralmente uma solução satisfatória, se você está tentando operações de limpeza que podem ocorrer durante a compilação, mas não são limpos-se normalmente ao sair "make".

No. Tanto quanto eu sei não existe tal funcionalidade.

Faça produz códigos de retorno. Tanto quanto me lembro agora, ele retorna 0 para o sucesso, 2 para o fracasso (por favor, verifique a documentação). Portanto, seria o suficiente para você para embrulhar make dentro de um shell script, por exemplo?

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top