make如何继续编译?

psi*_*mon 11 linux compiling make compiler interrupt

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

Gre*_*ill 12

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

一个步骤可能是“编译file.cfile.o”或“用于ld链接main.ofile.o进入program”。如果中断makeCtrlC,则当前执行的步骤将被终止,这将(或应该)删除它正在对输出文件。通常不会留下任何“半就绪的二进制文件”。

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

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

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

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


cha*_*aos 8

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);
Run Code Online (Sandbox Code Playgroud)

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.  */
Run Code Online (Sandbox Code Playgroud)

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

status = unlink (f->name);
Run Code Online (Sandbox Code Playgroud)

结论: 通常不要害怕用make. 如果它不是无法捕获的信号 ( SIGKILL, SIGSEGV, SIGSTOP),它将清理中间文件。