Code generation 如何编写Makefile规则以仅在文件丢失时下载该文件?

Code generation 如何编写Makefile规则以仅在文件丢失时下载该文件?,code-generation,makefile,Code Generation,Makefile,我正在尝试编写一个Makefile,当且仅当缺少一些源代码时,它应该下载这些源代码 比如: hello: hello.c gcc -o hello hello.c hello.c: wget -O hello.c http://example.org/hello.c 当然,这会导致每次运行make命令时下载hello.c。我希望hello.c仅在该Makefile丢失时由该Makefile下载。GNU make是否可以实现这一点?如果可以,如何实现这一点?您编写的Makefi

我正在尝试编写一个Makefile,当且仅当缺少一些源代码时,它应该下载这些源代码

比如:

hello: hello.c
    gcc -o hello hello.c

hello.c:
    wget -O hello.c http://example.org/hello.c

当然,这会导致每次运行make命令时下载
hello.c
。我希望
hello.c
仅在该Makefile丢失时由该Makefile下载。GNU make是否可以实现这一点?如果可以,如何实现这一点?

您编写的
Makefile
下载
hello.c
只有在缺少时才可以。也许你做错了什么?例如,见:

hello: hello.c
        gcc -o hello hello.c

hello.c:
        echo 'int main() {}' > hello.c
以及:


(第二次未执行
echo
命令)

由于Makefile应能正常工作,因此需要检查一些不太可能的情况:

1) 检查您是否没有提及源文件的任何
.PHONY
规则

2) 检查源目标名称是否与正在下载的文件路径匹配


您还可以尝试运行
make-d
来了解make为什么认为需要“重新构建”源文件。

我猜wget不会更新hello.c上的时间戳,而是保留远程时间戳。这导致
make
相信hello.c是旧的,并试图再次下载它。试一试

hello.c:
        wget ...
        touch $@

编辑:wget的-N选项将阻止wget下载任何内容,除非远程文件较新(但它仍然会检查远程文件的时间戳)。

如果
hello.c
的先决条件已更改或为空,并且Make在文件存在时继续下载该文件,然后,防止Make重新下载文件的一个选项是使用目标主体中的标志来检测文件是否存在:

hello.c:
    test -f $@ || wget -O hello.c http://example.org/hello.c

如果
hello.c
文件存在,
test
命令将返回
true
,否则它将返回
false
,并且
wget
命令将运行。

很抱歉直截了当,但是这样一个模糊的问题将引起一系列猜测。答案是错误的,因为,如果名为“hello.c”的文件已经存在,则目标
hello.c:
不会重新生成(并且文件也不会下载),而不管其时间戳如何。第二个原因是,使用-O选项时,文件的时间戳总是与下载时间一致。但由于问题是错误的,所以错误的答案恰好是正确的答案并不奇怪。>_Pavel,wget 1.15将保留时间戳,即使使用
-O
选项。你仍然正确,make不会查看时间戳(make没有其他时间戳可供比较)。愚蠢的我,忘了运行这个简单的测试。似乎wget在搞乱文件日期。。。谢谢这不会破坏功能。还要确保
wget
没有失败,并且
-O
后面的名称与目标匹配。更好的方法是,在
wget
命令中使用
$@
而不是
hello.c
hello.c:
    test -f $@ || wget -O hello.c http://example.org/hello.c