[Top][All Lists]

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

Re: Quirk with rules producing multiple output files

From: Roger Pepitone
Subject: Re: Quirk with rules producing multiple output files
Date: Fri, 12 Apr 2013 17:04:42 -0500

How come it only reran the rule once the second time?
All three targets were invalid.

On Fri, Apr 12, 2013 at 6:41 AM, Reinier Post <address@hidden> wrote:
On Thu Apr 11 12:47:56 2013, address@hidden (Paul Smith) wrote:
> 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.

Hmm, indeed:

| /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.

Reinier Post

Bug-make mailing list

reply via email to

[Prev in Thread] Current Thread [Next in Thread]