Search code examples
variablesmacrosmakefileexpandexpansion

How to get fully expanded gnu make variable value


I'm trying pass the fully evaluated value of a recursive make variables to a $(shell ...). I've tried many ways, including a macro to compute the final value myself, but have not had success.

I'm getting the intermediate variable syntax in my shell instead of the fully expanded recursive variable value.

VAR1 ?= var1_value
VAR2 ?= var2_value1 var2_value2
VAR3 ?= $(VAR1)
VARLIST := VAR1 VAR2 VAR3

quote     = $(if $(call ne,$(words $(1)),1),"$(1)",$(1))
GENVARS1  = $(foreach v,$(1),set $(v) $(call quote,$(value $(v)));)
SHELLVARLIST = $(shell echo $(call GENVARS1,$(VARLIST)))

shelltest :
    @echo "--->Executing recipe for shelltest"
    @echo "VAR3 is $(VAR3)"
    $(call GENVARS,$(VARLIST))
    @echo "SHELLVARLIST = $(SHELLVARLIST)"

In an ordinary dereference (at least in a recipe), the variable is fully expanded. However, when passed to macro as an argument, it does not. Is there any way to get the fully expanded value into a macro argument?

Here's the result when running make:

bash-4.1$ make -f test_expand.mk shelltest
/bin/sh: VAR1: command not found
--->Executing recipe for shelltest
VAR3 is var1_value
set VAR1 var1_value; set VAR2 var2_value1 var2_value2; set VAR3 $(VAR1);
/bin/sh: VAR1: command not found
SHELLVARLIST = set VAR1 var1_value

As you can see, $(VAR3) does not get passed as "var1_value" but instead gets passed as the literal "$(VAR1)".

Any hints or pointers would be most welcome. This is hair-pullingly frustrating (and I have so little left... :-o)

Thanks, Dave


Solution

  • You are explicitly telling make to NOT expand the variable, by using the $(value $(V)) construct. That's what the value function does: avoids expansion.

    If you want expansion, get rid of the value function. Why did you add it there in the first place?

    GENVARS1  = $(foreach v,$(1),set $(v) $(call quote,$(v));)
    

    ETA

    Sorry, if you want the expansion of the value as a variable name, you need to add an extra level of $(...) to expand it:

    GENVARS1  = $(foreach v,$(1),set $(v) $(call quote,$($(v)));)
    

    The inner $(v) expands to the name of the variable such as VAR3, so then the outer $(...) will be $(VAR3) and expand to the value of the VAR3 variable.