tech-toolchain archive

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

Re: make: dealing with targets with multiple outputs



On Fri, May 31, 2019 at 11:06:22AM -0700, Simon J. Gerraty wrote:
 > > We already have a solution for this problem, it's just waiting for
 > > someone to find time to implement it.
 > > 
 > > Namely: given multiple targets on the left, don't schedule them in
 > > parallel, and after building the first one check to see how many of
 > > the others also got knocked off at the same time.
 > 
 > Couple that with a special target to trigger it - sounds good.
 > That way you avoid the need to rewrite lots of makefiles with .for loops

No, the special target should be for the unusual case.

The usual case is:

   y.tab.c y.tab.h: foo.y
           $(YACC) -d foo.y

The unusual case is:

   foo.o bar.o baz.o: $(@:.o=.c)
           $(CC) $(@:.o=.c)

It's the unusual case that expects to run the recipe more than once.
Few real makefiles are written in this form because it doesn't work
very well to derive source names from target names. (And it doesn't
work and hasn't ever worked at all except in BSD make, as best as I
know.)

I might have one or two makefiles like this on a dusty shelf
somewhere, but I very much doubt there are many extant and few of them
will be performance-sensitive.

One could even trigger the special behavior by looking for $@ (or
equivalently $(.TARGET)) in the source list and/or recipe; such a rule
can't really do anything useful without that. I'm not sure this is a
good idea though as it might catch reasonable instances of the yacc
form, such as

   foo.c y.tab.h: foo.y
           $(YACC) -d -o $@ foo.y

I actually lean towards adding syntax for the special (parallelizing)
form, maybe something like

   foo.o bar.o baz.o: $@: $(@:.o=.c)
           $(CC) $(@:.o=.c)

as this is closely analogous to gmake's form for selective pattern
rules, and this construction is really a form of selective pattern
rule.

 > considering that .for loops introduce their own side effects
 > I prefer to avoid them when unnecessary.

They are by far the best (most flexible, least arbitrary gotchas)
choice for complex makefiles.

 > Do you have any of it implemented?

No. :(

 > Actually, unless there's more detail to your proposal, that would
 > totally kill parallelism no?
 > 
 > Since  yacc etc normally handled via .SUFFIX rules
 > that would imply any rule like
 > 
 > ${OBJS}: soemthing
 > 
 > would need to be impacted - that would seriously hurt something like
 > libc

A rule "$(OBJS): everything.h" without a recipe has no particular
effect; it only adds deps.

Makefiles with suffix rules are written

   .c.o:
           $(CC) -c $<

   $(PROG): $(OBJS)
           $(CC) $(OBJS) -o $@


so there's only ever one thing on the left at a time.

 > Adding a special source token, would go a long way to mitigate that.

There is no need...

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


Home | Main Index | Thread Index | Old Index