tech-pkg archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: bmake .OODATE confusion



On Fri, Aug 30, 2024 at 05:16:25PM +0000, Taylor R Campbell wrote:
 > [${.OODATE}]
 > 
 > It seems what this means is:
 > 
 > - For a non-phony target that exists, .OODATE is the list of sources
 >   that are newer than the target.
 > 
 >   (The language in the man page is backwards: it's the target, not the
 >   sources, that's out-of-date.  But that error isn't germane to your
 >   issue.)
 > 
 > - For a non-phony target that does not exist, .OODATE is the list of
 >   all sources.
 > 
 > - For a phony target, .OODATE is _also_ the list of all sources, just
 >   as if it were a non-phony target that does not exist.

It is not entirely clear from either the sources or the docs what
.OODATE is supposed to mean, but it seems to be intended to be the
same as $? in legacy make. gmake says about that:

     The names of all the prerequisites that are newer than the target,
     with spaces between them.  If the target does not exist, all
     prerequisites will be included.

and arguably including all the sources is a reasonable interpretation
for phony targets, since there's not really supposed to be a
difference an explicitly phony target and a target whose name just
doesn't exist in the filesystem. And the behavior of gmake is the same
here, 

There is some grumbling in the source (which is essentially unchanged
since -r1.1 although rillig's reindented it a few times) about the
distinction between specifically _newer than_ vs. _having been judged
out of date_, and this strikes me as both somewhat foolish and
problematic.

My understanding after wading through this for the past half hour is
that .OODATE should contain the subset of .ALLSRC that render the
_current_ target out of date, which is unrelated to whether they were
themselves out of date.

Both the wording in make(1) and in the PSD (which, though woefully
outdated, is also old enough to give some insight into what the
original authors of this code were thinking) suggest that .OODATE
should contain the subset of .ALLSRC that were themselves found to be
out of date, which is a different concept.

ISTM that make(1) should be fixed (and so should the PSD, but it's
probably better to leave it alone until someone's prepared to rewrite
it from scratch; I am still intending to do that sometime...)

...and also, the implementation should be cleaned up and simplified. I
see no reason .OODATE can't be initialized from the graph rather than
done as a separate pass, provided it's done with the intended
semantics, with the proviso that it might need to be updated if
something gets touched on the fly.

As for what you might actually be wanted for do-fetch, neither this
nor what the pmake authors 35 years ago appear to have in mind seems
to be it. There ought to be a way to collect up a bunch of targets
that need building and then run one recipe for all of them, but there
isn't really any good way as things stand.

Meanwhile:

 > General comment: make(1) is really designed for many-to-one recipes,
 > not for many-to-many recipes.  You can write `foo bar baz: quux' but
 > it's not actually many-to-many -- it's just multiple many-to-one
 > recipes and sometimes makes make(1) confused, especially in parallel.
 > gmake has syntax `&:' for a real many-to-many rule.  Perhaps if its
 > semantics is good we should adopt that, and you could use that instead
 > of the do-fetch kludge.

as I apparently have to point out over and over again, in traditional
make those _are_ many-to-many recipes. Traditionally there's no
operational difference between a many-to-many recipe and multiple
many-to-one recipes, or even for that matter mutliple many-to-many
recipes. Parallelizing broke that, and nobody including us managed to
do a damn thing about it for decades.

We should adopt the gmake syntax, because clearly trying to invent
anything else has failed.

-- 
David A. Holland
dholland%netbsd.org@localhost


Home | Main Index | Thread Index | Old Index