Eu sei que posso interromper um make
processo a qualquer momento sem precisar recompilar toda a árvore de origem novamente. Como eu sei, make
só 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 make
um 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.c
para file.o
" ou "usar ld
para vincular main.o
e file.o
entrar program
". Se você interromper make
com 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 ld
etapa para programas grandes pode facilmente levar muitos minutos quando make
foi projetada), parar e reiniciar make
iniciará 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 SIGINT
seja 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, make
faz como sempre: descobre o que ainda precisa ser feito (porque um arquivo foi alterado ou make
nunca foi processado, não importa) e continua com o trabalho.
A descrição acima pressupõe claramente que os Makefile
s relevantes descrevem as dependências e comandos para serem executados corretamente, então tudo o que precisa ser (re)feito é.