Como faz a compilação contínua?

11

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

psimon
fonte
2
Principalmente, você só precisa se preocupar se o computador for desligado inesperadamente. Algumas vezes, meu Ubuntu conseguiu entrar em um impasse no kernel (ou seja o que for) e deixou binários meio prontos, o que acabou perdendo mais de duas horas.
Alvin Wong

Respostas:

12

Em termos simples, você pode pensar makeem ter um número (possivelmente grande) de etapas, em que 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, então a etapa atualmente em execução será terminada que vai (ou deveria) remover o arquivo de saída que estava trabalhando. Geralmente, não existem "binários semi-prontos" deixados para trás.

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

  • um arquivo de entrada possui 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 levar facilmente alguns minutos quando makefoi projetada), a interrupção e a reinicialização makeiniciarão 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.

Greg Hewgill
fonte
8

Ctrl+ Cfaz com que SIGINTa seja enviada para o processo em execução. Este sinal pode ser capturado pelo processo. No código-fonte 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 make. Se não for um sinal inacessível ( SIGKILL, SIGSEGV, SIGSTOP), ele fará uma limpeza nos arquivos intermediários.

caos
fonte
1
SIGSEGVé alcançável em muitos Unices.
Chris Baixo
1

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

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

vonbrand
fonte