[Top][All Lists]

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

Re: Should this makefile really hang make?

From: Paul Smith
Subject: Re: Should this makefile really hang make?
Date: Sun, 20 Nov 2011 09:14:20 -0500

On Sat, 2011-11-19 at 22:07 -0800, Bryan Ischo wrote:
> I thought that the first 'expansion' was simply the resolution of all 
> variable references, so that, e.g.
> %.a: $$($(SRCDIR)/$$@:%.a=%.c)
> Would, by first expansion, result in:
> %.a: $(foo/bar/$@:%.a=%.c)

Yes, that's exactly right.

> Then the second expansion would have access to the automatic variables
> of the rule, so $@ would be meaningful, and the result of that second 
> expansion would treat the substitution pattern as it would in any
> other substitution pattern variable reference.

So during second expansion the above value has to be resolved.  For a
pattern rule, two things have to happen: one thing is that the pattern
has to be resolved: the "%" values have to be replaced by the stem.  So
remember in a normal pattern rule you'd have:

  %.o : %.c

and the "%" in "%.c" needs to be replaced by the stem.  Same in the
second expansion.

And the second thing that has to happen in second expansion is the
evaluation of variables/functions/etc.

The question is, in which order are those done?  Do you evaluate the
prerequisite first, or do you replace the stem first?  Today, make will
replace the stem first.  That allows constructs like this:

  all: foo.a
  foo_OBJECTS = obj1.o obj2.o obj3.o
  %.a: $$(%_OBJECTS)

to work properly: first the stem "%" is replaced with "foo", then make
evaluates the resulting "$(foo_OBJECTS)" and you get the right answer.
However, it breaks in constructs such as you used:

  %.a: $$($(SRCDIR)/$$@:%.a=%.c)

because here the first "%" is replaced with "foo" first, then the
evaluation happens.

But if you do things the other way, which is what you're suggesting,
where first you evaluate then you replace the stem, that works for your
construct but will fail for the one I list above: "$(%_OBJECTS)"; if
that is evaluated first then it evaluates to the empty string (since the
literal variable "%_OBJECTS" is not defined) and there's no stem to

The ultimate problem is that the operator "%" is used in two contexts:
it's used as the stem in a pattern rule and also inside functions like
patsubst etc.  In this situation those two operators conflict and
there's no way, today, to disambiguate them.

 Paul D. Smith <address@hidden>          Find some GNU make tips at:            
 "Please remain calm...I may be mad, but I am a professional." --Mad Scientist

reply via email to

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