|Subject:||Re: Quirk with rules producing multiple output files|
|Date:||Fri, 12 Apr 2013 17:04:42 -0500|
On Thu Apr 11 12:47:56 2013, address@hidden (Paul Smith) wrote:Hmm, indeed:
> On Thu, 2013-04-11 at 12:14 +0200, Reinier Post wrote:
> > > It's just a shorthand for writing a lot of identical rules; it does NOT
> > > mean that a single invocation if the rule will generate all three
> > > targets, which is what you are expecting.
> > Incidentally: other workflow/inference languages can express this
> > distinction perfectly and still allow the resulting specifications to
> > be analyzed for proper termination (e.g. safe Petri nets, Datalog);
> > I'd love to know of an alternative to make that is based on such a
> > language, but it seems too much to ask for make to be extended
> > in this way.
> I'm not sure exactly what you mean by "this distinction", but GNU make
> already supports multi-target generators with pattern rules, as
> mentioned in the part of the email you clipped. So the basic
> infrastructure exists. There were proof-of-concept patches floating
> around to support it for explicit rules as well.
| /tmp % cat Makefile
| %.1:; echo $*.1 for $@ > $@
| %.e.1 %.f.1:; echo $*.1 for $@ > $@
| %.c.1 %.d.1:; for f in $*.c.1 $*.d.1; do echo $$f for $@ > $$f; done
| %.ab.2: %.a.1 %.b.1; cat $+ > $@
| %.cd.2: %.c.1 %.d.1; cat $+ > $@
| %.ef.2: %.e.1 %.f.1; cat $+ > $@
| /tmp % make -rR stage.ab.2 stage.cd.2 stage.ef.2
| echo stage.a.1 for stage.a.1 > stage.a.1
| echo stage.b.1 for stage.b.1 > stage.b.1
| cat stage.a.1 stage.b.1 > stage.ab.2
| for f in stage.c.1 stage.d.1; do echo $f for stage.d.1 > $f; done
| cat stage.c.1 stage.d.1 > stage.cd.2
| echo stage.1 for stage.f.1 > stage.f.1
| cat stage.e.1 stage.f.1 > stage.ef.2
| cat: stage.e.1: No such file or directory
| make: *** [stage.ef.2] Error 1
| rm stage.a.1 stage.b.1 stage.c.1
| /tmp %
I didn't realise make would skip the creation of stage.e.1;
yet this is documented very clearly:
I thought this was just describing an optimization;
I didn't realize it would actually affect the build process.
Why does it work this way? What is a possible use case?
I use symbolic intermediate targets a lot, but my targets
in pattern rules are always real files.
Or is it just intended as an optimization to avoid a stat() call?
(I tried cvs annotate to find this out,
but this documentation text is in r1.1 already.)
In any case, it may be useful to also be able to state that
a multi-target pattern rule only makes its actual target.
With :: we can already have alternative rules for the same targets.
Considering these features together, the rule selection and execution
mechanism becomes difficult to understand; a formal model might help.
> Really the trickiest part is the user interface (makefile syntax): it
> must be backward-compatible with existing makefiles, or at least be sure
> to break virtually none of them.
|[Prev in Thread]||Current Thread||[Next in Thread]|