GNU Make忘记了先决条件?

时间:2010-07-06 11:48:35

标签: gnu-make

这有点复杂,所以我上传了一个例子here

如何测试:

  • 下载tarball并解压缩
  • cd make_problem / make
  • make aclean(忘记从存档中删除存档;))
  • 制作alib(将重新创建刚删除的简单而愚蠢的存档)
  • ./ weird.sh

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

$

现在我希望每次触摸源都会重建存档,但显然没有发生。

任何人都能解释一下吗? 并解释如何确保它始终按预期工作?

1 个答案:

答案 0 :(得分:2)

这里的问题是文件修改时间戳的分辨率相对较低,这会导致make在您连续两次连续运行时感到困惑,就像weird.sh那样。

具体而言,weird.sh将:

  1. 触摸foo1.c
  2. 运行make,哪个
    1. 重建foo1.o
    2. 重建libmine.a
  3. 触摸bar1.c
  4. 运行make,哪个
    1. 重建bar1.o
    2. 也许(见下文)重建libmine.a
  5. 如果步骤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,问题就会消失: - )