Re: Question/Proposal: Incomplete debug graph output when using -o (--old-file)

WaitronCharm <[email protected]> Tue, 23 Jun 2026 17:36:15 +0000
Newsgroups gmane.comp.gnu.make.bugs
Message-ID <P8CGaSHmGhg935o2wMzoOAjx9o75i-M6r_3dRK9v2jNZGR8UMnIaERGoPhzSj3rnMnp5wyd8fRA5xlQRJpe7rqsLNEpSbbfsam7OS4a6pCE=@proton.me>
Hello everyone

I've spent some time digging into 'src/remake.c' to better understand how t=
his behaves and wanted to share my findings, along with a potential logic c=
hange I am considering.

To clarify the exact case driving this:

1. I have a specific target that can no longer be remade because it relies =
on a web resource that is not available anymore.
2. However, it has other local prerequisites that still get updated regular=
ly. These updates would normally trigger a remake of this target and would =
not succeed in any meaningful way.
3. I would need to keep these prerequisites in a dependency graph (which I =
capture via 'makefile2graph').
4. Other higher targets rely on this outdated but locally still fine target=
. They can be updated at any time, but I don't want them constantly and end=
lessly rebuilding on every single make run.

As noted before, using '-o' keeps the status clean but prunes the prerequis=
ites from the graph entirely. Conversely, '-W' (which I haven't tried but a=
ssume) would preserve the graph but constantly force higher rebuilds. I als=
o cannot simply touch the target with a custom timestamp because its real m=
odification date must remain strictly bound to its last effective, successf=
ul remake.

This led me to the conclusion -- which might be wrong -- that make could in=
ternally fake this target's timestamp to be 'just good enough' (i.e., exact=
ly equal to or one tick newer than its latest prerequisite).

Doing so would:

- Keep its prerequisites alive in the traversal graph.
- Report a correctly faked 'up-to-date' status in the visual log.
- Avoid triggering cascading rebuilds for higher targets.

I am considering hacking together a local patch to introduce a new command-=
line option -- something along the lines of '--not-too-old-not-too-young-bu=
t-up-to-date=3DTARGET' -- to enable this behavior for specific targets. The=
 logic would essentially intercept the target, declare it up-to-date so no =
recipe executes and dynamically set the file's internal modification date t=
o match the highest timestamp of its prerequisites so subsequent processing=
 runs smoothly.

Could anyone familiar with 'src/remake.c' point me toward the correct place=
 where these specific date comparisons and status assignments happen? Thank=
s.

On Tuesday, May 26th, 2026 at 3:50 PM, WaitronCharm <[email protected]=
> wrote:

> To clarify further, simply removing -o and using -n (--just-print) instea=
d is also not a viable workaround. While -n would traverse the prerequisite=
s and make the graph structurally complete, the reported target build statu=
ses would be wrong for this use case. The debug output would show targets a=
s 'needing to be remade' rather than treating them as up-to-date via the -o=
 override.
>=20
> There seems to be no combination of current options that yields both a fu=
lly traversed dependency graph and the correct target statuses in the debug=
 logs.
>=20
> On Tuesday, May 26th, 2026 at 3:30 PM, WaitronCharm <WaitronCharm@proton.=
me> wrote:
>=20
> > Hello,
> >
> > I am working on reconstructing the visual dependency graph of a build u=
sing GNU Make's --debug output. However, I have run into a limitation when =
combining debugging with the -o (--old-file) option.
> >
> > When a target is marked as old via -o, GNU Make seems to immediately op=
timize away the traversal of that target's prerequisites. Because these pre=
requisites are not traversed, they are completely omitted from the debug lo=
g. This leaves the reconstructed visual graph incomplete.
> >
> > From an execution standpoint, optimizing out these checks makes perfect=
 sense. However, for tooling and visualization, it creates a blind spot. Co=
uld the final decision to consider a target up-to-date (based on -o) be def=
erred until after its prerequisites have been traversed in the graph?
> >
> > I tried using the -n (--just-print / dry-run) option as an alternative =
to see the full graph without executing commands, but it has a different li=
mitation: rules that update included makefiles are still actively executed =
under -n.
> >
> > This leaves a gap in the current options. There appears to be no combin=
ation of flags that allows a user to safely skip a target's execution while=
 still fully discovering and dumping its underlying dependency tree in the =
debug output.
> >
> > Here is a minimal example demonstrating the behavior:
> >
> > $ make --debug -f - -o t1
> > GNU Make 4.4.1
> > Built for x86_64-pc-cygwin
> > Copyright (C) 1988-2023 Free Software Foundation, Inc.
> > License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gp=
l.html>
> > This is free software: you are free to change and redistribute it.
> > There is NO WARRANTY, to the extent permitted by law.
> > t1: t2; echo $@
> > t2:; echo $@
> > Reading makefiles...
> > Updating makefiles....
> > Updating goal targets....
> > make: 't1' is up to date.
> >
> > Notice that t2 is never mentioned or evaluated in the debug output abov=
e. Compare this to a normal run where the full relationship is explicitly p=
rinted:
> >
> > $ make --debug -f -
> > GNU Make 4.4.1
> > Built for x86_64-pc-cygwin
> > Copyright (C) 1988-2023 Free Software Foundation, Inc.
> > License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gp=
l.html>
> > This is free software: you are free to change and redistribute it.
> > There is NO WARRANTY, to the extent permitted by law.
> > t1: t2; echo $@
> > t2:; echo $@
> > Reading makefiles...
> > Updating makefiles....
> > Updating goal targets....
> >  File 't1' does not exist.
> >   File 't2' does not exist.
> >  Must remake target 't2'.
> > echo t2
> > t2
> >  Successfully remade target file 't2'.
> > Must remake target 't1'.
> > echo t1
> > t1
> > Successfully remade target file 't1'.
> >
> > Is this immediate pruning of the graph an intentional design constraint=
 for performance, or would the maintainers consider a patch/option that for=
ces prerequisite traversal even when a target is short-circuited by -o?
> >
> > I would love to hear your thoughts on whether this use case is currentl=
y supported through other means, or if a feature request is appropriate her=
e.
> >
> >