GNU make 如何管理文件版本控制?

How GNU make manages file version control?

我正在学习 GNU make。假设我有一个 hello_world.c 文件和一个 Makefile:
hello_world.c:

#include <stdio.h>                        

int main() {                              
        printf("Hello World!\n");  
        return 0;                         
} 

生成文件:

hello: hello_world.c
        gcc hello_world.c -o hello_world

现在,我认为 hello 是我的目标,hello_world.c 是它的依赖项。如果 make 以某种方式检测到 hello_world.c 比它的目标文件更新,它会执行相应的命令。

1- make 如何管理文件版本控制以及它如何检测比其他内容更新并需要更新的内容?
2- 如果我使用编辑器更改 hello_world.o 并损坏文件,它显然不会执行,但 make hello 报告 无需执行任何操作完成! 我的意思是,make 只检查了依赖项是否比目标旧,然后什么都不做就退出了。我认为它应该已经检测到这个目标不是与其最新调用对应的目标。不知何故,它应该比较“依赖与目标的组合”历史,而不是仅仅比较依赖的历史w.r.t。目标。
3-这是make的限制吗?我怎样才能避免这个问题?因为可能有一些外部应用程序干扰了我的 make 操作目标。

make程序简单比较目标(hello)和依赖(hello_world.c)文件的修改time-stamps。

如果依赖文件的 time-stamp 比目标更新,则执行命令。

How does make manage file version control and how does it detect something is newer than something else and needs updating?

很简单:make不关心文件版本。

通过比较文件系统中的时间戳来检测是否比其他内容更新。

If I change hello_world.o using an editor and corrupt the file, it obviously does not execute but make hello reports that nothing needs to be done! I mean, make only checked that the dependency is older than the target and exited doing nothing. I think it should have detected that this target is not the one corresponding to its latest invocation. Somehow, it should have compared the "combination of dependency AND target" history instead of just comparing dependency's history w.r.t. target.

您没有告诉 make 关于您的 .o 文件的任何信息。为什么要 make 检查该文件的时间戳? 检查依赖性正是 make 预期要做的。 如果你不告诉它,这个工具怎么可能知道调用 hello_world.o 的文件参与了这个过程?没有魔法发生,只是遵循了 Makefile 的规则。

Is this the limitation of make? How can I circumvent this issue? Because there maybe some external apps messing with the target of my make operation.

您可以指定层次依赖关系:

all: hello

hello: hello_world.o
    <gcc linker command...>

hello_world.o: hello_world.c
    gcc hello_world.c -o hello_world

1- How does make manage file version control and how does it detect something is newer than something else and needs updating?

你已经知道这个问题的答案了。您在下一段中说:"I mean, make only checked that the dependency is older than the target and exited doing nothing." 没错。 make 当目标的依赖关系较新时更新依赖目标。

2- If I change hello_world.o using an editor and corrupt the file, it obviously does not execute but make hello reports that nothing needs to be done! I mean, make only checked that the dependency is older than the target and exited doing nothing. I think it should have detected that this target is not the one corresponding to its latest invocation. Somehow, it should have compared the "combination of dependency AND target" history instead of just comparing dependency's history w.r.t. target.

您要求 make 做的事情超出了预期。

3- Is this the limitation of make? How can I circumvent this issue? Because there maybe some external apps messing with the target of my make operation.

从您的角度来看,这似乎确实是 make 的限制。但是,我想指出您正在通过手动更新目标来破坏 make 的工作。

如何规避它?

  1. 不要手动修改由 make 构建的目标。

  2. 手动更新其中一个依赖项的时间戳,然后运行make。您可以为此使用命令 touch

  3. 提供一个名为 clean 的虚拟目标,它将删除所有从属目标。然后,运行 make clean 后跟 make.

  4. 提供一个名为 rebuild 的虚拟目标。强制构建您需要在该目标中构建的任何内容。那么,运行make rebuild.