我发现当我修改某些文件,然后输入make命令时,它会运行与这些文件相关的某些命令。如果我没有做任何更改,那么make就不会执行任何操作,显示程序已经是最新的。这告诉我make有一种方法可以知道上一次运行以来哪些文件被修改过。它是怎么知道的?它似乎没有将任何东西放在运行目录中,因此它必须将这些信息存储在其他地方。
我发现当我修改某些文件,然后输入make命令时,它会运行与这些文件相关的某些命令。如果我没有做任何更改,那么make就不会执行任何操作,显示程序已经是最新的。这告诉我make有一种方法可以知道上一次运行以来哪些文件被修改过。它是怎么知道的?它似乎没有将任何东西放在运行目录中,因此它必须将这些信息存储在其他地方。
make
通过检查文件X的修改时间(在文件系统中记录)是否早于其任何依赖项,来确定目标文件X是否需要重新构建。例如,如果您有一个如下的make规则:
foo.o: foo.c foo.h common.h
如果foo.c
、foo.h
或common.h
的修改时间比foo.o
更晚,那么make
就知道需要重建foo.o
。这意味着执行touch common.h
会使foo.o
在下一次make
时被重新构建。
这意味着如果修改时间不可靠,例如系统时钟回跳,或者如果您将文件存储在某些网络文件系统上并且有多个客户端访问它们(特别是如果您网络上的各台机器的时钟不同步),则make
可能会感到困惑。如果您正在使用分布在网络上的文件运行make
,通常最好运行NTP以保持正确设置您的时钟。
Make
比表面上看起来要复杂得多。它有一个带有复杂算法的推理引擎;当与您的配置数据相结合时,make
是一种称为专家系统的程序+数据库类型。
无论如何,回答您的问题,make
进行的检查有些棘手,因为可能存在多个先决条件链,而这些先决条件链本身可以以任意方式交叉链接。
因此,“它是怎么知道的?”的答案是:
make
使用 stat(2)
函数获取文件的修改时间make
对其从 Makefile 中制作的图进行拓扑排序您是正确的,make
通常不会留下任何关于记录状态的 cookie 或其他文件。(偶尔一些 Makefile 本身会创建时间戳 cookie,但这是罕见的。)但是这并不重要,毕竟最后一次Make 运行可能仍然失败。它只是比较正在生成的目标文件的日期与源文件的日期。它只关心目标是否是最新的,通常不会考虑上次运行 make
的时间。
它的作用是检查源文件的日期/时间戳是否晚于相应的中间文件(或可能是输出文件 - 我已经很久没有处理过make文件了)。如果是,则需要编译该文件。这将触发最终可执行文件的链接。