Tom Lane writes:
> What bothers me is that you seem to be saying that *any* construct
> involving multiple outputs from one rule is unsafe in a parallel make.
> That strikes me as a huge restriction, and one that would surely be
> mentioned prominently in the gmake manual if it were real. But I can't
> find anything that says that.
I think we have been victims of a misunderstanding of how multiple-target
rules work. The gmake manual says:
"A rule with multiple targets is equivalent to writing many rules, each
with one target, and all identical aside from that."
So when we write this:
| $(srcdir)/preproc.c $(srcdir)/preproc.h: preproc.y
| $(YACC) -d $(YFLAGS) $<
| mv y.tab.c $(srcdir)/preproc.c
| mv y.tab.h $(srcdir)/preproc.h
make reads it as this:
| $(srcdir)/preproc.c: preproc.y
| $(YACC) -d $(YFLAGS) $<
| mv y.tab.c $(srcdir)/preproc.c
| mv y.tab.h $(srcdir)/preproc.h
|
| $(srcdir)/preproc.h: preproc.y
| $(YACC) -d $(YFLAGS) $<
| mv y.tab.c $(srcdir)/preproc.c
| mv y.tab.h $(srcdir)/preproc.h
So it's completely conceivable that both rules get executed in parallel.
(In general, you cannot optimize this away, because the actual commands
may differ depending on the value of $@.)
This basically means that you cannot correctly write a target that
generates more than one file. The only workaround I see is to cheat about
the dependencies, as Klaus' patch does:
y.tab.c: preproc.y
$(YACC) -d $(YFLAGS) $<
$(srcdir)/preproc.c: y.tab.c
mv y.tab.c $(srcdir)/preproc.c
$(srcdir)/preproc.h: y.tab.c
mv y.tab.h $(srcdir)/preproc.h
It's the latter rule where we're technically cheating and which I was
initially regarding as part of the "details I don't like", but now I think
it's the best (only?) way to go.
--
Peter Eisentraut peter_e@gmx.net