(Sigh, I sent two messages off-list because of bad gmail UX. Forwarding to
the list…)

---------- Forwarded message ----------
From: *Philip Guenther* <guent...@gmail.com>
Date: Thursday, June 19, 2025
Subject: Re-executing..., when and when not?
To: WaitronCharm <waitronch...@proton.me>


On Thu, Jun 19, 2025 at 11:13 AM WaitronCharm via Bug reports and
discussion for GNU make <bug-make@gnu.org> wrote:
>
> Hi everyone
>
> Story is the following. There is a 'makefile' which includes a couple of
others, some are itself generated by the same 'make' run (i.e. NO recursive
'make' processes). Issue is that the 'make' re-run is not triggered as ...
I wished.
>
> Interesting part from the below log is this:
>
> ...
>  Finished prerequisites of target file 't2'.
>   Prerequisite 't1' is newer than target 't2'.
>   Prerequisite 't3' is older than target 't2'.
>  Must remake target 't2'.
> t1:1: update target 't2' due to: t1
> m4 -D n=t7 t3 > t2
> ...
>   Finished prerequisites of target file 't4'.
>    Prerequisite 't5' is older than target 't4'.
>    Prerequisite 't2' is newer than target 't4'.
>    Prerequisite 't6' is older than target 't4'.
>   Must remake target 't4'.
> t2:1: update target 't4' due to: t2
> m4 -D n=t6 t5 > t4
> ...
> Re-executing[1]: make -d -r -R t10
> ...
>
> 't2' is 'include'-d and there is another 't9' also 'include'-d and this
't9' has 't4' as prerequisite. This all sounds overly complicated but there
is reason why it is like it is. (The stripped down version of the scripts
attached here would not justify this level of complexity / indirection.)
>
> I expected that 'Re-executing' happens between re-making 't2' and 't4'
since 't4' is dependent on 't2' which was just re-made.

Let's start from the info pages.  Trimmed lightly:
----
3.5 How Makefiles Are Remade
============================
...
   To this end, after reading in all makefiles `make' will consider
each as a goal target, in the order in which they were processed, and
attempt to update it.  <...>

   If a makefile has a rule which says how to update it (found either in
that very makefile or in another one) or if an implicit rule applies to
it, it will be updated if necessary.  After all makefiles have been checked,
if any have actually been changed, `make' starts with a clean slate and
reads all the makefiles over again.  (It will also attempt to update each of
them over again, but normally this will not change them again, since they
are already up to date.)  Each restart will cause the special variable
`MAKE_RESTARTS' to be updated.
----

So, make will make sure _all_ the included makefiles are up to date
before possibly re-executing.



> Any idea what could be adjusted to achieve the re-execution?

It sounds like the t4 build process doesn't directly use t2, but
rather is also dependent on the make variables/rules read by make from
t2, such that rebuilding t2 and then t4 in the same make process
results in an incorrect t4.

I suspect the simple solution would be to change the rule for t4 to
actually start its own make process, ala
t4: t2 whatever-else
    $(MAKE) t4

as that submake would load the updated rules/variables from the updated t2.


Could probably do something subtle like put a generation number in a
variable in t2 and have t4 contain its own "generation of t2 that I
was built from" value and then

ifneq(${T2_GEN},${T4s_T2_GEN})
.PHONY: t4
endif

so that make will rebuild t2, then t4, re-execute, see that t4 is now
phony so rebuild it again and re-execute again.

If  building t4 is expensive then the first case is better.  If there
are a bunch of _distinct_ interdependencies like this then maybe the
latter would allow them to be redone in parallel, but...meh.  Maybe do
both as the later catches mismatches when the build is interrupted?


Philip Guenther

Reply via email to