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 Sat, Jun 15, 2019 at 12:47:21PM +0100, David Laight wrote:
 > > 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'm not dead!)
 > 
 > $(OBJS): $(HEADERS)
 > Is common - but doesn't have any rules.
 > (They usually come from the .c.o suffix rule.)

...doesn't have a recipe, you should probably say. But yeah, that's
important, because it's recipe invocations we're talking about.

 > ISTR that:
 > $(OBJS): $$(@:.o=.c)
 > is valid in SYSV make (from 30+ years ago).
 > (But that might be after I fixed 'suffix translations on dynamic dependencies'.)

I don't think this method ever worked except in BSD make... although
given System V vendors, if it worked in some versions of System V make
it would not have worked in others and therefore couldn't be relied
on.

It doesn't work in gmake, in any event, which means even if it did
work in some versions of System V make it never caught on enough to
get attention.

 > GNU make has its pattern match syntax - and that does get used.
 > 
 > I suspect there are far more cases of your 'unusual case' than you expect.
 > There are plenty of makefiles that generate a list of object files and
 > then rely on make to find the sources.

I don't think so. I mean, I've written some, and then based on that
experience decided it was a bad idiom, and I'm probably not alone in
the first half of that (or the second either), but almost all build
systems are either (a) not specific to bsd make, or (b) if they are
use for loops because that's one of the primary things being specific
to bsd make buys you, or are (c) directly descended from the 4.4 build
system and use suffix rules for their recipes.

All of those cases will work as expected in my proposal; any leftover
ones will still run correctly, they just lose some parallelism.

 > If your object tree matches the source tree then you get:
 > $(CC_OBJS): $(SRC_DIR)/$(@:.o=.c)
 > 	$(CC) -o $@ $*

You can't use $* here. Nowadays you can use $< here and it does what
you want, but that's fairly recent; historically you have to repeat
the whole RHS of the rule, and that sucks a lot if it's in any way
complicated.

Note also that you can't use .PATH searches with this construction,
only with suffix rules.

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


Home | Main Index | Thread Index | Old Index