这有点复杂,所以我上传了一个例子here。
如何测试:
weird.sh的作用就是触摸源文件,重新制作,触摸另一个源文件,重做几次。
这是使用GNU Make 3.81在我的Linux系统上输出的样子:
$ ./weird.sh #### 1 #### gcc -c -g -Wall -Wextra -o ../swu/1/src/foo1.o ../swu/1/src/foo1.c ar cr ../make/libmine.a ../swu/1/src/foo1.o ==== 1 ==== gcc -c -g -Wall -Wextra -o ../swu/1/src/bar1.o ../swu/1/src/bar1.c ar cr ../make/libmine.a ../swu/1/src/bar1.o #### 2 #### gcc -c -g -Wall -Wextra -o ../swu/1/src/foo2.o ../swu/1/src/foo2.c ==== 2 ==== gcc -c -g -Wall -Wextra -o ../swu/1/src/bar2.o ../swu/1/src/bar2.c #### 3 #### gcc -c -g -Wall -Wextra -o ../swu/1/src/foo3.o ../swu/1/src/foo3.c ==== 3 ==== gcc -c -g -Wall -Wextra -o ../swu/1/src/bar3.o ../swu/1/src/bar3.c #### 4 #### gcc -c -g -Wall -Wextra -o ../swu/1/src/foo4.o ../swu/1/src/foo4.c ==== 4 ==== gcc -c -g -Wall -Wextra -o ../swu/1/src/bar4.o ../swu/1/src/bar4.c #### 5 #### gcc -c -g -Wall -Wextra -o ../swu/1/src/foo5.o ../swu/1/src/foo5.c ==== 5 ==== gcc -c -g -Wall -Wextra -o ../swu/1/src/bar5.o ../swu/1/src/bar5.c #### 6 #### gcc -c -g -Wall -Wextra -o ../swu/1/src/foo6.o ../swu/1/src/foo6.c ==== 6 ==== gcc -c -g -Wall -Wextra -o ../swu/1/src/bar6.o ../swu/1/src/bar6.c #### 7 #### gcc -c -g -Wall -Wextra -o ../swu/1/src/foo7.o ../swu/1/src/foo7.c ==== 7 ==== gcc -c -g -Wall -Wextra -o ../swu/1/src/bar7.o ../swu/1/src/bar7.c ar cr ../make/libmine.a ../swu/1/src/bar7.o #### 8 #### gcc -c -g -Wall -Wextra -o ../swu/1/src/foo8.o ../swu/1/src/foo8.c ==== 8 ==== gcc -c -g -Wall -Wextra -o ../swu/1/src/bar8.o ../swu/1/src/bar8.c $
现在我希望每次触摸源都会重建存档,但显然没有发生。
任何人都能解释一下吗? 并解释如何确保它始终按预期工作?
答案 0 :(得分:2)
这里的问题是文件修改时间戳的分辨率相对较低,这会导致make在您连续两次连续运行时感到困惑,就像weird.sh
那样。
具体而言,weird.sh
将:
foo1.c
foo1.o
和libmine.a
bar1.c
bar1.o
libmine.a
如果步骤2.2和步骤4.2之间的时间小于文件系统的时间戳分辨率,则make libmine.a
已将相同的时间戳记视为bar1.o
,因此不会重建它。
Linux ext3文件系统的时间戳分辨率为1秒。这个explanation from the maintainer of make更详细地描述了这个问题,并且还提到Solaris具有更好的时间戳分辨率,这可能解释了为什么你的例子在那里按预期工作。
如果在实际应用程序中这对您来说是个问题,您可以尝试使用具有纳秒分辨率时间戳的ext4文件系统。否则,只需在sleep 1
中的每个make命令之后放置weird.sh
,问题就会消失: - )