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

)

+3


source to share


1 answer


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.

+1


source







All Articles