views:

360

answers:

3
somevar := apple
export somevar
update := $(shell echo "v=$$somevar")

all:
    @echo $(update)

I was hoping to apple as output of command, however it's empty, which makes me think export and := variable expansion taking place on different phases. how to overcome this?

A: 

Running the makefile

foo:=apple
export foo
all:
        @echo ">"$(shell echo "$$foo")
        @echo ">""$$foo"

gives for me (with foo undefined in the environment)

$ make
>
>apple

$ make foo=bar
>
>apple

$ export foo=bar; make
>bar
>apple

$ export foo=bar; make foo=bar
>bar
>bar

Try using the quoted form (update := "v=$$somevar") and let the shell handle expansion when a command is run (you'll still need the export)

Scott Wales
@Scott Wales: I need to keep it the way that shell function stays out of target's command, since it has conditional statement on it in real life.
Michael
A: 

I think this is because of the double-quotes. This is working:

somevar := apple
export somevar
update := $(shell echo 'v=$$somevar')

all:
    @echo $(update)
RC
That's because variables aren't expanded in single quotes, so update is defined as `v=$somevar`, and then `somevar` is expanded by the `@echo`.
Scott Wales
@RC, Scott Wales: the single quotes helped in this particular example, however, if I use my real shell command it will not expand correctly: `update := $(shell perl -e 'print "$$ENV{somevar}"')`
Michael
@Scott, thanks for the explanation
RC
A: 

The problem is that export exports the variable to the subshells used by the commands; it is not available for expansion in other assignments. So don't try to get it from the environment outside a rule.

somevar := apple
export somevar

update1 := $(shell perl -e 'print method 1 "$$ENV{somevar}\n"')
# Make runs the shell command, the shell does not know somevar, so update1 is "method 1 ".

update2 := perl -e 'print method 2 "$$ENV{somevar}\n"'
# Now update2 is perl -e 'print method 2 "$$ENV{somevar}\n"'

# Lest we forget:
update3 := method 3 $(somevar)

all:
    echo $(update1)
    $(update2)
    $echo $(update3)
    perl -e 'print method 4 "$$ENV{somevar}\n"'
Beta
@Beta: In fact it is bug[http://savannah.gnu.org/bugs/?10593] which is not fixed and maybe will never be. Thanks, I will try not to bother you with weird makefile questions.
Michael
@Michael: From my reading of the GNUMake manual it is not a bug. (And you don't have to put @Beta in front of a comment to my answer.)
Beta