我注意到当我对某些文件进行更改然后输入make时,它会运行与这些文件相关的某些命令。如果我没有改变任何东西,那么make不做任何事情,说该程序是最新的。这告诉我make有一种方法可以知道自上次运行以来哪些文件已被更改。怎么知道的?它似乎没有在运行它的目录中放置任何内容,因此它必须将此信息存储在其他位置。
答案 0 :(得分:28)
它检查文件系统的修改日期元信息。
例如,请参见st_mtime
的{{3}}和struct stat
成员。
它具有内置规则,告诉它(例如)如果相应的.c文件已更改,则需要重新生成.o文件; stat() man page说:
过时的标准是 按照规定 先决条件,由文件组成 以空格分隔的名称。 (通配符 和档案成员(见档案)是 也允许在这里。)目标已经过时了 如果日期不存在或是否存在,则为日期 比任何先决条件都要早 (通过比较最后修改 次)。
答案 1 :(得分:13)
make
通过检查其修改时间(记录在文件系统中)是否比其任何依赖项更旧来确定是否需要重建目标文件X.例如,如果你有一个make规则,如:
foo.o: foo.c foo.h common.h
然后它知道如果foo.o
,foo.c
或foo.h
中的任何一个的修改时间比common.h
更新,则需要重建foo.o
。这意味着执行touch common.h
会强制在下一个make重建foo.o
。
这意味着如果修改时间不可靠,make
可能会混淆 - 例如,如果您的系统时钟向后跳,或者您将文件存储在某些网络文件系统上并且有多个客户端访问它们(特别是如果网络上各种机器上的时钟不同步的话。如果您将make
与通过网络分发的文件一起使用,通常最好运行NTP以正确设置时钟。
答案 2 :(得分:13)
Make
比表面看起来要复杂得多。它有一个带有复杂算法的推理引擎;与您的配置数据结合使用make
是一种程序+数据库,称为 expert system 。
无论如何,要回答你的问题,检查make
确实有点棘手,因为可能存在多个先决条件链,而这些先决条件链本身可以以任意方式交叉链接。
所以,“它如何知道?”的答案是:
stat(2)
的文件获得修改时间你是对的,make
通常不会留下任何类型的cookie或其他状态跟踪文件。 (有时候一些 Makefile 会自己创建时间戳cookie,但这种情况很少见。)但这无关紧要,毕竟最后一次 Make 运行可能会失败。它的作用是简单地将目标文件的日期与源文件上的日期进行比较。它只关心目标是否是最新的,通常不会考虑最后一次运行make
。
答案 3 :(得分:3)
检查是查看源文件上的日期/时间戳是否晚于相应中间文件上的日期/时间戳(或者输出文件 - 自从我处理make文件以来已经有一段时间了)。如果是,则需要编译该文件。然后,这将触发最终可执行文件的链接。