Make 似乎会将文件修改时间与某种内部缓存中的修改时间进行比较。是否有人知道这个缓存位于何处或如何访问它?
缓存本身就是你的文件系统:
make
程序读取makefile文件,当make
执行规则时,期望构建的目标将被更新(比原来新),但即使目标没有实际更新,它仍将继续前进至初始文件系统检查结果中下一个过时的目标。
重新执行make
强制它从分析开始重新使用您的文件系统的当前状态。
使用strace
等工具来查看程序正在做什么。在这里,我们可以跟踪make程序执行的所有文件操作(-e trace=file
)。
假设我们有一个foo.c
文件和一个简单的Makefile,用它来构建一个名为foo
的可执行文件:
$ cat Makefile
foo: foo.c
我们来运行 make
命令:
$ strace -e trace=file make
execve("/usr/bin/make", ["make"], [/* 20 vars */]) = 0
...
open("Makefile", O_RDONLY) = 3
stat("Makefile", {st_mode=S_IFREG|0644, st_size=11, ...}) = 0
...
stat("foo", 0x7ffd4373c8c0) = -1 ENOENT (No such file or directory)
stat("foo.c", {st_mode=S_IFREG|0644, st_size=36, ...}) = 0
cc foo.c -o foo
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=27717, si_status=0, si_utime=0, si_stime=0} ---
stat("foo", {st_mode=S_IFREG|0755, st_size=8549, ...}) = 0
+++ exited with 0 +++
在这里,你可以看到它检查了foo
是否存在并找不到它,然后它检查foo.c
是否存在,接着调用规则对其进行编译。
现在你可以再次调用make,得到略有不同的结果:
$ strace -e trace=file make
...
stat("foo", {st_mode=S_IFREG|0755, st_size=8549, ...}) = 0
stat("foo.c", {st_mode=S_IFREG|0644, st_size=36, ...}) = 0
make: `foo' is up to date.
+++ exited with 0 +++
如果正在使用某种缓存文件,我们会看到一个open()
和read()
。如果该缓存在运行之间被使用,则我们也会看到一个write()
。