我遇到GNU make 3.81中修改时间的问题。
我的Makefile使用从远程服务器安装的数据,由于某些原因我不知道,它已经将文件的修改时间设置为遥远的未来(进入下个世纪)。
Makefile首先在本地目录中创建一个“从未来”远程文件的符号链接,然后基于该文件运行几个脚本,这些脚本都生成一些输出文件。
现在,当我想在重叠之后重新运行“make all”以获取所有输出文件时,它将不会使用它生成的最新输出文件重新启动(假设从脚本编号3开始),而是重新生成所有内容从一开始,因为它注意到第一个文件(我将来自未来的符号链接文件的那个文件)更新。
是否有一个选项告诉make接受符号链接本身的修改时间,而不是符号链接目标的修改时间?
例
这是一个重新生成问题的最小工作示例:
设置文件夹和文件:
mkdir symlinkmake
cd symlinkmake
echo $PWD > futurefile.txt
# set file modification time to the future
touch -t 212111111111 futurefile.txt
Makefile的内容:
all: symlink.txt first_output.txt second_output.txt
symlink.txt:
ln -s futurefile.txt symlink.txt
first_output.txt: symlink.txt
cut -f1 -d"/" symlink.txt > first_output.txt
second_output.txt: first_output.txt
wc first_output.txt > second_output.txt
现在运行make all
并删除第二个输出文件。然后重新运行make。由于第一个输出文件已存在,因此只需要生成第二个文件。但由于futurefile.txt
比任何其他文件更新,因此第一个输出文件也将生成:
make all
rm second_output.txt
make all
在我的机器上,输出如下所示:
$ ls
Makefile futurefile.txt symlink.txt
$ make all
make: Warning: File `symlink.txt' has modification time 3.3e+09 s in the future
cut -f1 -d"/" symlink.txt > first_output.txt
wc first_output.txt > second_output.txt
make: warning: Clock skew detected. Your build may be incomplete.
$ rm second_output.txt
$ make all
make: Warning: File `symlink.txt' has modification time 3.3e+09 s in the future
cut -f1 -d"/" symlink.txt > first_output.txt
wc first_output.txt > second_output.txt
make: warning: Clock skew detected. Your build may be incomplete.
有--check-symlink-times
make option但是:
在支持符号链接的系统上,除了这些链接引用的文件上的时间戳之外,此选项还会使make考虑任何符号链接上的时间戳。提供此选项时,文件和符号链接中的最新时间戳将被视为此目标文件的修改时间。
这不是你想要的只考虑链接的时间戳。由于您无法解决日期/时间问题,我只能想象一下2个解决方案
.PHONY: all
all: first_output.txt second_output.txt | symlink.txt
symlink.txt:
ln -s futurefile.txt $@
first_output.txt: | symlink.txt
cut -f1 -d"/" $| > $@
second_output.txt: first_output.txt
wc $< > $@
作为OOP制作的symlink.txt
只会考虑它的存在,而不是它的时间戳。换句话说,make将构建它,并且(重新)构建依赖于它的所有目标,只有它缺失。
注意:我还在任何可能的地方使用过automatic variables。它们很方便,不易出错,并且经常允许对规则进行分解。
缺点:这是一个快速而肮脏的黑客而不是真正的解决方案。实际上,如果链接引用的文件发生更改,则不会重建其他目标:
$ ls -al
Sep 14 14:55 Makefile
Dec 1 2018 futurefile.txt
$ make
ln -s futurefile.txt symlink.txt
cut -f1 -d"/" symlink.txt > first_output.txt
wc first_output.txt > second_output.txt
$ ls -al
Sep 14 14:55 Makefile
Sep 14 15:05 first_output.txt
Dec 1 2018 futurefile.txt
Sep 14 15:05 second_output.txt
Sep 14 15:05 symlink.txt -> futurefile.txt
$ make
make: Warning: File 'symlink.txt' has modification time 6688452 s in the future
make: Nothing to be done for 'all'.
make: warning: Clock skew detected. Your build may be incomplete.
$ touch --date=2018-12-02 futurefile.txt
$ ls -al futurefile.txt
$ make
make: Warning: File 'symlink.txt' has modification time 6774852 s in the future
make: Nothing to be done for 'all'.
make: warning: Clock skew detected. Your build may be incomplete.
touch
命令有一个很好的--reference
选项,强制文件的时间戳是另一个文件的时间戳:
.PHONY: all
all: first_output.txt second_output.txt
first_output.txt: futurefile.txt
cut -f1 -d"/" $< > $@
touch --reference=$< $@
second_output.txt: first_output.txt
wc $< > $@
touch --reference=$< $@
缺点:将来有两个文件(first_output.txt
和second_output.txt
),而不是一个符号链接:
$ ls -al
Sep 14 14:55 Makefile
Dec 1 2018 futurefile.txt
$ make
make: Warning: File 'futurefile.txt' has modification time 6688320 s in the future
cut -f1 -d"/" futurefile.txt > first_output.txt
touch --reference=futurefile.txt first_output.txt
wc first_output.txt > second_output.txt
touch --reference=first_output.txt second_output.txt
make: warning: Clock skew detected. Your build may be incomplete.
$ ls -al
Sep 14 14:55 Makefile
Dec 1 2018 first_output.txt
Dec 1 2018 futurefile.txt
Dec 1 2018 second_output.txt
$ make
make: Warning: File 'first_output.txt' has modification time 6688320 s in the future
make: Nothing to be done for 'all'.
make: warning: Clock skew detected. Your build may be incomplete.
$ touch --date=2018-12-02 futurefile.txt
$ ls -al futurefile.txt
$ make
make: Warning: File 'first_output.txt' has modification time 6688320 s in the future
cut -f1 -d"/" futurefile.txt > first_output.txt
touch --reference=futurefile.txt first_output.txt
wc first_output.txt > second_output.txt
touch --reference=first_output.txt second_output.txt
make: warning: Clock skew detected. Your build may be incomplete.