0

这有点复杂,所以我在这里上传了一个示例。

如何测试它:

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

奇怪的.sh 所做的只是触摸一个源文件,重新制作,触摸另一个源文件,重新制作几次。

这是使用 GNU Make 3.81 在我的 Linux 系统上的输出:

$ ./奇怪的.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

$

现在我希望每次触及源时都会重新构建档案,但这显然没有发生。

谁能解释一下?并解释如何确保它始终按预期工作?

4

1 回答 1

2

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

具体来说,weird.sh将:

  1. 触碰foo1.c
  2. 运行 make,其中
    1. 重建foo1.o
    2. 重建libmine.a
  3. 触碰bar1.c
  4. 运行 make,其中
    1. 重建bar1.o
    2. 也许(见下文)重建libmine.a

如果步骤 2.2 和步骤 4.2 之间的时间小于文件系统的时间戳分辨率,则 make 认为libmine.a已经具有与相同的时间戳bar1.o,因此不会重建它。

Linux ext3 文件系统的时间戳分辨率为 1 秒。make 维护者的这个解释更详细地描述了这个问题,并且还提到 Solaris 具有更好的时间戳分辨率,这可能解释了为什么您的示例在那里按预期工作。

如果在实际应用程序中这对您来说是个问题,您可以尝试使用具有纳秒分辨率时间戳的 ext4 文件系统。否则,只需sleep 1在每个 make 命令后加上一个weird.sh,问题就会消失:-)

于 2010-07-11T23:42:54.310 回答