如何编写Makefile规则以仅在缺少文件时下载文件?

时间:2009-10-19 10:47:11

标签: 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。我希望只有在缺少的情况下才能通过此Makefile下载hello.c。这是可能的GNU make以及如果它是如何做到的?

4 个答案:

答案 0 :(得分:11)

我的猜测是wget不会更新hello.c上的时间戳,但会保留远程时间戳。这会导致make认为hello.c已经过时并尝试再次下载它。尝试

hello.c:
        wget ...
        touch $@

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

答案 1 :(得分:7)

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

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

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

% make
echo 'int main() {}' > hello.c
gcc -o hello hello.c
% rm hello
% make
gcc -o hello hello.c
% rm hello*
% make
echo 'int main() {}' > hello.c
gcc -o hello hello.c

(第二次没有执行echo命令)

答案 2 :(得分:7)

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

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

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

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

答案 3 :(得分:1)

如果hello.c的先决条件已更改或为空,并且Make继续存在时Make继续下载文件,那么防止Make重新下载文件的一种方法是在文件正文中使用一个标志。目标以检测文件是否存在:

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

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