Tom
Tom

Reputation: 8012

How can I create a fallback rule in GNU make?

Consider this makefile:

default: c

a:: b
    touch a

a:: b
    ls -lt a b
    touch a

c: a
    touch c

Output is this:

$ touch b
$ make
touch a
ls -lt a b
-rw-r--r-- 1 tkcook tkcook 0 Apr  1 11:32 a
-rw-r--r-- 1 tkcook tkcook 0 Apr  1 11:31 b
touch a
touch c

I understand that double-colon rules permit multiple rules to be executed for the same target, but they do still all depend on prerequisites being newer than the target to trigger. In this case, therefore, I expected that a being newer than b after execution of the first rule would prevent the second rule's recipe from being run, but instead, both rules for making a are executed.

Ultimately, I am trying to handle a situation where there are two possible ways of making a target. One is very cheap but doesn't always work, whereas the other is very expensive but always works. When the target is out of date, I'd basically like to try the first method first, and then fall back to the second (only) if the first fails. Given that double-colon rules don't seem to be achieving that, what can I do instead?

Upvotes: 0

Views: 1066

Answers (1)

Matt
Matt

Reputation: 15196

Why are both rules for making a executed, even though the first one makes a newer than b?

Keep in mind that while executing recipes make only checks for the exit codes. It never cares if the target files were even created, not even mentioning their timestamps.

What the (explicit) double-colon rules are designed for is to choose the recipe(s) based on which prerequisites have changed. That means they are always independent of one another.

I'd basically like to try the first method and if that doesn't work do the other one instead, but both methods get executed.

Use single recipe with "or-ed" commands like ./script1 || ./script2

Upvotes: 2

Related Questions