views:

154

answers:

3

I'm trying to write a Makefile which should download some sources if and only if they are missing.

Something like:

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

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

But of course this causes hello.c to be downloaded every time make command is run. I would like hello.c to be downloaded by this Makefile only if it is missing. Is this possible with GNU make and how to do this if it is?

+6  A: 

The Makefile you wrote downloads hello.c only if it's missing. Perhaps you are doing something else wrong? See for example:

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

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

And:

% 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

(the echo command was not executed the second time)

Lukáš Lalinský
Silly me, forgot to run this simple test. It appeared that wget was messing with file dates... Thanks!
abbot
That doesn't break the functionality.
Lukáš Lalinský
+4  A: 

Since the Makefile should be working as you want, you need to check a few unlikely cases:

1) Check that you don't have any .PHONY rules mentioning the source file.

2) Check that the source target name matches the file path you are downloading.

You could also try running make -d to see why make thinks it needs to 're-build' the source file.

Douglas Leeder
+2  A: 

My guess is that wget doesn't update the timestamp on hello.c, but retains the remote timestamp. This causes make to believe that hello.c is old and attempts to download it again. Try

hello.c:
        wget ...
        touch $@

EDIT: The -N option to wget will prevent wget from downloading anything unless the remote file is newer (but it'll still check the timestamp of the remote file, of course.)

JesperE
Another answer with the word "guess" and another wrong one.
Pavel Shved
Sorry for being blunt, but a vague question like that is going to get a bunch of guesses.
JesperE
@Pavel: how do you know its wrong, BTW?
JesperE
**The answer is wrong** because, target `hello.c: ` is **not** remade (and the file's not downloaded) if file named "hello.c" already exists--regardless of its timestamp. The second reason is that with -O option the file's timestamp *always* coincides with download time.
Pavel Shved
But since the question was wrong, I'm not surprised that the wrong answer occurred to be correct one. >_<
Pavel Shved