On Fri, 11 Sep 2026 18:40:33 +0200
joergboe via Bug reports and discussion for GNU  make <[email protected]>
wrote:

> * Further requires the translation of foo.s that bar.i is present (import).

Ok

> foo.o foo.i : bar.i

But the above rule is a bad way to say that foo.o and foo.i only requires
bar.i to be present. The above rule says that foo.o and foo.i should be
rebuilt if bar.i is newer. Instead you might want a order only prerequisite
which means that bar.i first will need to be created, but if it already
exists, it will not cause a rebuild:

foo.o foo.i : | bar.i

> $
> 
> Running the script:
> 
> $ rm -f foo.* bar.* target
> $ touch foo.s bar.s
> $ make -f implicit.mk
> touch bar.o bar.i
> touch foo.o foo.i
> touch target
> $
> 
> Remove bar.o an run implicit.mk again:
> 
> $ rm bar.o
> $ make -f implicit.mk
> touch bar.o bar.i
> touch target
> $
> 
> Running implicit.mk again:
> 
> $ make -f implicit.mk
> touch foo.o foo.i
> touch target
> $
> 
> The target is updated again even if nothing was changed!

But something did change the previous time you run make, bar.i got a new
timestamp and that now causes foo.o and foo.i to be rebuilt.

> Obviously the change of bar.i is not considered and the update of
> foo.o/foo.i is omitted.

The reason that the update of bar.i was not detected at the second run of make
is that bar.i just happened to get touched because of how the recipe was
written. The recipe is something that make just executes. Only targets and
prerequisites are considered when make decides which recipes are to be
executed. So make detects that bar.o needs to be rebuilt after you removed it
and the recipe then just happens to also touch bar.i. I would prefer a rule
like this:

%.o %.i : %.s
        touch $@

With the above rule, only bar.o and target will be rebuilt after bar.o has
been removed.

regards Henrik

Reply via email to