make如何继续编译?

make如何继续编译?

我知道我可以make随时中断进程,而不必再次重新编译整个源代码树。据我所知,make只有在尚未编译的情况下才编译目标,或者在上次编译后修改了源代码。
但如果我中断make,肯定会有一个或多个(取决于并发级别)半就绪的二进制文件。下次我跑步时它们会做什么make?或者当我按Ctrl+C以避免部分编译的二进制文件时它是否完成当前目标?

答案1

简单来说,您可以将其视为make具有(可能很大)数量的步骤,其中每个步骤都采用多个文件作为输入并创建一个文件作为输出。

步骤可能是“编译file.c到”file.o或“使用ld链接main.o到”。如果您用中断,则当前执行的步骤将终止,这将(或应该)删除它正在处理的输出文件。通常不会留下任何“半就绪的二进制文件”。file.oprogrammakeCtrlC

当您重新启动时make,它将查看所​​有输入和输出文件的时间戳并重新运行以下步骤:

  • 输入文件的时间戳比输出文件更新
  • 输出文件不存在

这通常意味着,如果一个步骤需要很长时间才能运行(这在现代计算机上很少见,但大型程序的步骤在设计ld时很容易花费很多分钟),那么停止并重新启动将从头开始该步骤。makemake

平均值的实际情况Makefile比上述描述要复杂得多,但基本原理是相同的。

答案2

Ctrl+C导致 aSIGINT被发送到正在运行的进程。该信号可以被进程捕获。在 make 源代码中,您可以在以下位置找到此信号的陷阱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()是 的清理函数make,请参阅此处的定义:

/* 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.  */

稍后在您看到的函数中,它们将被有效删除:

status = unlink (f->name);

结论: 一般来说,不要害怕中断编译make。如果它不是不可捕获的信号 ( SIGKILL, SIGSEGV, SIGSTOP),它将清理中间文件。

答案3

当某些事情停止时make(无论是 ctrl-C、关机,还是命令失败),已经完成的工作会保留下来。重述时,make一如既往:它找出还需要做什么(因为文件已更改或make永远不需要处理它并不重要)并继续工作。

上面的描述清楚地假设相关的Makefile描述了正确执行的依赖关系和命令,所以所有需要(重新)制作的都是。

相关内容