[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Substitution references
From: |
Paul D. Smith |
Subject: |
Re: Substitution references |
Date: |
Tue, 30 Oct 2001 14:34:39 -0500 |
%% Phil Endecott <address@hidden> writes:
pe> X=$(words Y)
pe> test:
pe> echo $(X)
pe> echo $(X:Y=a b c)
pe> I expected to get "1" and "3", but actually I got "1" and "1".
pe> Is this the expected behaviour? (GNU Make version 3.73).
Yes.
There is no such thing as "shallow evaluation" in make. When make
evaluates a variable it _always_ evaluates it recursively and
completely, right there.
Since the $(V:X=Y) operator replaces X with Y in the _value_ of the
variable V, that variable must be evaluated. The result of that will
not be "$(words Y)", since that would be a shallow, non-recursive
evaluation and make doesn't do that. It would be the result of
evaluating $(words Y), which is "1". So, you are replacing "Y" with "a
b c" in the value "1", where there is of course no "Y", so it doesn't do
anything and resolves to just "1".
pe> What I was really trying to do was to use substitution references
pe> to give a common interface to multiple programs that have the same
pe> purpose but with different command-line formats. My first idea
pe> was (vaguely) like this:
pe> if some-condition
pe> DO_FOO=fooprog IN > OUT
pe> else
pe> DO_FOO=otherfoo -in IN -out OUT
pe> endif
pe> y: x
pe> $(DO_FOO:IN=x:OUT=y)
pe> But of couse I can't do two substitututions in one go like this. I could
pe> go for this:
pe> $(subst IN,x,$(subst OUT,y,$(DO_FOO)))
pe> but that's a bit long, so I tried this:
pe> DO_FOO=fooprog $(word 1,IN_OUT) > $(word 2,IN_OUT)
pe> or DO_FOO=otherfoo -in $(word 1,IN_OUT) -out $(word 2,IN_OUT)
pe> and then
pe> $(DOO_FOO:IN_OUT=x y)
pe> but this fails because the $(word...) functions seem to be applied before
pe> IN_OUT is substituted. It ends up doing "fooprog x y >" or
pe> "otherfoo -in x y -out".
pe> So, experts!, how would you do this?
Well, in this particular case in your example it's trivial because the
values you want to replace are provided as automatic variables. So, you
can just do this:
if some-condition
DO_FOO = fooprog $< > $@
else
DO_FOO = otherfoo -in $< -out $@
endif
y: x
$(DO_FOO)
As long as all the values you're using are targets or prerequisites or
are derivable from them, then you're fine with the above.
See the GNU make manual section "Automatic Variables".
If you need something more generic, then I would upgrade to a newer
version of GNU make (3.73!?!? Ouch!), and use the $(call ...) function:
if some-condition
DO_FOO = fooprog $1 > $2
else
DO_FOO = otherfoo -in $1 -out $2
endif
y: x
$(call DO_FOO, input, output)
Again, see the GNU make manual.
--
-------------------------------------------------------------------------------
Paul D. Smith <address@hidden> Find some GNU make tips at:
http://www.gnu.org http://www.paulandlesley.org/gmake/
"Please remain calm...I may be mad, but I am a professional." --Mad Scientist