Reputation: 135
I am trying to pass a shell variable from one makefile command to another, but so far have not been successful.
target1:
curl ... ${myvar} ## using myvar from target2
target2:
export myvar=$(shell curl .....);
echo $myvar
In the above case, I am not even getting the output on echo $myvar. Is there something I'm doing wrong?
Upvotes: 1
Views: 2813
Reputation: 311416
In a Makefile
, every line of a target is run in a separate shell. Additionally, a command can only change the environment for itself and its children. So when you have:
target2:
export myvar=$(shell curl .....);
echo $myvar
And you run make target2
, the following happens:
export myvar=...some value...
echo $myvar
First, there's a syntax problem here: when you write $myvar
, this
will be interpreted by make
as a request for the value $m
followed
by the text yvar
. To access shell variables, you need to escape the
$
, like this:
echo $$myvar
But that won't solve this problem, because as we see from the above
sequence, the export
command happens in a shell process which
immediately exits, so it's effectively invisible to anything else.
This target would work the way you expect if you were to write:
target2:
export myvar=$(shell curl .....); \
echo $$myvar
Here, because we're using the \
to escape the end-of-line, this is
all one long "virtual" line and executes in a single shell process, so
the echo
statement will see the variable value set in the previous
statement.
But nothing will make an environment variable set in a shell process in one target visible in another target, because there's no way to get these to execute in the same process.
If you need to set variables in your Makefile
that are visible
across all targets, set make
variables:
myvar = $(shell curl ...)
target1:
curl ... $(myvar)
A workaround, as you have discovered, is to re-execute make
as a
child process from within the process that set the environment
variable as in:
target2:
export myvar=$(shell curl .....); \
echo $$myvar; \
$(MAKE) myvar=$$myvar
But often this sort of recursive call to make
results in a more
complicated Makefile
.
Upvotes: 2
Reputation: 135
Found the answer. Posting if anyone comes across this. I needed to use $$ instead of $
target1:
curl ... ${myvar} ## using myvar from target2
target2:
export myvar=$(shell curl .....);
echo $$myvar
$(MAKE) myvar=$${myvar} target1
Upvotes: 0