Como faz a compilação continuar?

Como faz a compilação continuar?

Eu sei que posso interromper um makeprocesso a qualquer momento sem precisar recompilar toda a árvore de origem novamente. Como eu sei, makesó compila um alvo se ele ainda não estiver compilado ou se o código-fonte for modificado após a última compilação.
Mas se eu interromper make, certamente haverá um ou mais (dependendo do nível de simultaneidade) binários meio prontos. O que isso faz com eles na próxima vez que eu corro make? Ou termina o alvo atual quando pressiono Ctrl+ Cpara evitar binários parcialmente compilados?

Responder1

Em termos simples, você pode imaginar makeum número (possivelmente grande) de etapas, onde cada etapa recebe vários arquivos como entrada e cria um arquivo como saída.

Uma etapa pode ser "compilar file.cpara file.o" ou "usar ldpara vincular main.oe file.oentrar program". Se você interromper makecom CtrlC, a etapa atualmente em execução será encerrada, o que removerá (ou deverá) o arquivo de saída no qual estava trabalhando. Geralmente não há nenhum "binário meio pronto" deixado para trás.

Ao reiniciar make, ele examinará os carimbos de data e hora de todos os arquivos de entrada e saída e executará novamente as etapas em que:

  • um arquivo de entrada tem um carimbo de data/hora mais recente que o arquivo de saída
  • o arquivo de saída não existe

Isso geralmente significa que se uma etapa demorar muito para ser executada (é raro em computadores modernos, mas a ldetapa para programas grandes pode facilmente levar muitos minutos quando makefoi projetada), parar e reiniciar makeiniciará essa etapa desde o início.

A realidade da sua média Makefileé consideravelmente mais complicada do que a descrição acima, mas os fundamentos são os mesmos.

Responder2

Ctrl+ Cfaz com que um SIGINTseja enviado para o processo em execução. Este sinal pode ser captado pelo processo. No código-fonte do make você pode encontrar uma armadilha para este sinal em commands.c:

  /* If we got a signal that means the user
     wanted to kill make, remove pending targets.  */

  if (sig == SIGTERM || sig == SIGINT

  ... remove childrens ...

  /* Delete any non-precious intermediate files that were made.  */

  remove_intermediates (1);

remove_intermediates()é a função de limpeza de make, veja sua definição aqui:

/* Remove all nonprecious intermediate files.
   If SIG is nonzero, this was caused by a fatal signal,
   meaning that a different message will be printed, and
   the message will go to stderr rather than stdout.  */

E mais tarde na função que você vê, eles serão efetivamente excluídos:

status = unlink (f->name);

Conclusão: Geralmente não tenha medo de interromper uma compilação com arquivos make. Se não for um sinal incapturável ( SIGKILL, SIGSEGV, SIGSTOP) ele fará uma limpeza dos arquivos intermediários.

Responder3

Quando algo para make(seja ctrl-C, shutdown ou até mesmo um comando que falha), o trabalho já realizado permanece. Quando reformulado, makefaz como sempre: descobre o que ainda precisa ser feito (porque um arquivo foi alterado ou makenunca foi processado, não importa) e continua com o trabalho.

A descrição acima pressupõe claramente que os Makefiles relevantes descrevem as dependências e comandos para serem executados corretamente, então tudo o que precisa ser (re)feito é.

informação relacionada