如何使继续编译?


11

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


2
通常,您只需要担心计算机意外关闭电源即可。几次,我的Ubuntu都陷入了内核死锁(或死锁)并留下了一半就绪的二进制文件,最终浪费了两个多小时。
Alvin Wong

Answers:


12

简而言之,您可以将其make视为具有多个步骤(可能很多),其中每个步骤都将多个文件作为输入并创建一个文件作为输出。

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

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

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

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

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


8

Ctrl+ C使a SIGINT发送到正在运行的进程。该信号可以被过程捕获。在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),它将清除中间文件。


1
SIGSEGV在许多Unices上都是可捕获的。
克里斯·

1

当某些事情停止时make(例如ctrl-C,关闭或什至是失败的命令),已经完成的工作会保留下来。重新声明后,make将照常执行:找出仍然需要执行的操作(因为文件已更改或make从未处理过该文件无关紧要),然后继续工作。

上面的描述清楚地假设相关的Makefiles描述了正确执行的依赖项和命令,因此需要(重新)制作所有内容。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.