help-make
[Top][All Lists]
Advanced

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

Re: quoting $$ (or something completely different?)


From: Philip Guenther
Subject: Re: quoting $$ (or something completely different?)
Date: Sat, 1 Apr 2006 01:03:57 -0700

On 3/31/06, Tom Bachmann <address@hidden> wrote:
...
> In the attached makefile, foo_bar_CFLAGS is set to `$(CFLAGS)', if I use
> 3 `$' for quoting in SET, foo_bar_CFLAGS is not set at all.
...
> NAME = $(subst /,_,$(1))
>
> define SET
> $$(NAME)_$(1) := $$$$($(1))
> endef
>
> define FOO
> CFLAGS := foo bar baz foo2
> $(eval $(call SET,CFLAGS))
> endef
>
> $(eval $(call FOO,foo/bar))
>
> all:
>         @echo '$(foo_bar_CFLAGS)'

The main problem here is that, despite the apparent ordering of
actions in the FOO variable/function, CFLAGS has _not_ yet been set
when foo_bar_CFLAGS is assigned to.  The $(eval) inside FOO has to be
executed in order to determine the expansion of the $(call
FOO,foo/bar), and it's the evaluation of _that_ that sets CFLAGS.  So,
the first step to fixing this is to evaluate the CFLAGS assignment as
part of the FOO expansion:

define FOO
$(eval CFLAGS := foo bar baz foo2)
$(eval $(call SET,CFLAGS))
endef

With that change, foo_bar_CFLAGS gets set to the literal $(CFLAGS). 
So, let's drop a pair of dollar-signs in the definition of SET:

define SET
$$(NAME)_$(1) := $$($(1))
endef

...and poof, it works:
$ gmake
foo bar baz foo2
$

Before declaring success, let's examine things a bit more closely. 
What is FOO actually expanding to when called?  Well, let's replace
the $(eval $(call FOO,...)) with $(info $(call FOO,...)).  The result:

$ gmake


foo bar baz foo2
$

Ah, the $(eval)s inside FOO are themselves expanding to nothing, so
FOO is expanding to just the newline between them (there are two blank
lines because $(info) adds one).  So, that outer $(eval) isn't
actually evaluating any real snippets of makefile; all it's doing is
letting make ignore that newline.  If we remove the $(eval) and the
newline inside FOO, things continue to work.  (If you only remove the
$(eval), then when make calls FOO, it'll see that newline are complain
"*** missing separator").

So, my final makefile reads:
----------------------------------
NAME = $(subst /,_,$(1))

define SET
$$(NAME)_$(1) := $$($(1))
endef

define FOO
$(eval CFLAGS := foo bar baz foo2)$(eval $(call SET,CFLAGS))
endef

$(call FOO,foo/bar)

all:
        @echo '$(foo_bar_CFLAGS)'

-----------------------------

Make sense?


Philip Guenther




reply via email to

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