[Top][All Lists]
[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