Prevent reinstallation only when ordering if outdated
College just stumbled upon this and I thought I'd ask if there is any neat solution for the next problem, I have a GNU makefile:
a: | b
touch $@
b:c
touch $@
c:
touch $@
Then I run:
~/tmp> make a
touch c
touch b
touch a
~/tmp> make a
make: `a' is up to date.
~/tmp> touch b
~/tmp> make a
make: `a' is up to date.
~/tmp> touch c
~/tmp> make a
touch b
It repairs b
, but not a
if I touch c
. Is there a way to NOT rebuild b
if only called by the order condition? (in real case it b
is a file with hundreds of dependencies, which may not be there when called make a
. I cannot make the preconditions b
available only in order, since that will break make b
)
source to share
The behavior is completely correct. You have instructed to make
ignore the hard relationship between a
and b
and depend on presence only b
. So far a
and c
use the date dependency .
This is the difference between a: b
and a: | b
.
If anyone wants to investigate this case (or other make
magic :)):
Try this, you will see that it is make
very sharp and says what it does for the purpose b
:
% touch b
% LANG=C make -rd | awk '/^Considering/,/^$/ {print}'
Considering target file `a'.
Considering target file `b'.
Considering target file `c'.
Finished prerequisites of target file `c'.
No need to remake target `c'.
Finished prerequisites of target file `b'.
Prerequisite `c' is older than target `b'.
No need to remake target `b'.
Finished prerequisites of target file `a'.
Prerequisite `b' is order-only for target `a'. <--- "order-only"
No need to remake target `a'.
Now add a hard dependency:
% echo "a:b" >> Makefile
And compare the results:
% touch b
% LANG=C make -rd | awk '/^Considering/,/^$/ {print}'
Considering target file 'a'.
Considering target file 'b'.
Considering target file 'c'.
Finished prerequisites of target file 'c'.
No need to remake target 'c'.
Finished prerequisites of target file 'b'.
Prerequisite 'c' is older than target 'b'.
No need to remake target 'b'.
Pruning file 'b'.
Finished prerequisites of target file 'a'.
Prerequisite 'b' is order-only for target 'a'.
Prerequisite 'b' is newer than target 'a'. <--- additional "date dependency"
Must remake target 'a'.
touch a <--- 'a' is rebuilt
Putting child 0x1b09ec0 (a) PID 5940 on the chain.
Live child 0x1b09ec0 (a) PID 5940
Reaping winning child 0x1b09ec0 PID 5940
Removing child 0x1b09ec0 PID 5940 from chain.
Successfully remade target file 'a'.
I used make -r
(no implied rules) since this example does not use them and is boring to read.
source to share