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

时间:2018-03-27 15:45:38

标签: makefile build gnu-make build-automation

我正在学习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只检查了依赖项是否比目标更旧并且退出时什么也没做。我认为应该检测到这个目标不是与其最新调用相对应的目标。不知何故,它应该比较&#34; 依赖和目标的组合&#34;历史,而不仅仅是比较依赖的历史w.r.t.目标。
3 - 这是make的限制吗?我该如何规避这个问题?因为可能有一些外部应用程序弄乱了我的make操作的目标。

3 个答案:

答案 0 :(得分:1)

make程序只是比较目标(hello)和依赖项(hello_world.c)文件的修改时间戳。

如果依赖项文件的时间戳比目标更新,则执行命令。

答案 1 :(得分:1)

  

如何管理文件版本控制以及如何检测某些东西比其他东西更新并且需要更新?

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

通过比较文件系统中的时间戳,可以检测出某些东西是否比其他东西更新。

  

如果我使用编辑器更改hello_world.o并破坏文件,它显然不会执行,但会生成hello报告,不需要执行任何操作!我的意思是,只检查依赖项是否比目标更旧并且退出什么都不做。我认为应该检测到这个目标不是与其最新调用相对应的目标。不知何故,它应该比较依赖和目标的组合&#34;历史,而不仅仅是比较依赖的历史w.r.t.目标

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

  

这是make的限制吗?我该如何规避这个问题?因为可能有一些外部应用程序弄乱了我的make操作的目标。

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

all: hello

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

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

答案 2 :(得分:1)

  

1 - make如何管理文件版本控制?它如何检测某些东西比其他东西更新并且需要更新?

您已经知道这个问题的答案了。你在下一段中说过:“我的意思是,make只检查了依赖项是否比目标更早,并且没有做任何事情。”那就对了。当目标的依赖关系较新时,make会更新相关目标。

  

2 - 如果我使用编辑器更改hello_world.o并损坏文件,则显然不会执行,但make hello报告无需执行任何操作! 我的意思是,make只检查了依赖项是否比目标更旧并且退出时什么也没做。我认为应该检测到这个目标不是与其最新调用相对应的目标。不知何故,它应该比较“依赖关系和目标的组合”历史,而不仅仅是比较依赖关系的历史w.r.t.目标

你要求make比预期做的更多。

  

3 - 这是make的限制吗?我该如何规避这个问题?因为可能有一些外部应用程序弄乱了我的make操作的目标。

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

你怎么能绕过它?

  1. 请勿手动修改由make构建的目标。

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

  3. 提供名为clean的虚拟目标,该目标将删除所有相关目标。然后,运行make clean,然后运行make

  4. 提供名为rebuild的虚拟目标。强制构建您在该目标中构建的任何内容。然后,运行make rebuild

相关问题