somevar := apple
export somevar
update := $(shell echo \"v=$$somevar\")
all:
@echo $(update)
I was hoping to apple as output of command, however i
Although export
does not play nicely with $(shell ...)
, there is a simple workaround. We can pass the data to the shell script via the command line.
Now of course, environment passage is robust against issues of escaping and quoting. However, the shell language has a single quote quoting method '...'
which handles everything. The only problem is that there is no way to get a single quote in there; but of course that is solved by terminating the quote, backslash-escaping the needed single quote and starting a new quote: In other words:
ab'cd -> 'ab'\''cd'
In the shell script executed by $(shell ...)
we just generate a variable assignment of the form var='$(...)'
, where $(...)
is some make expression that interpolates suitably escaped material. Thus, Makefile
:
somevar := apple with 'quoted' "stuff" and dollar $$signs
shell_escape = $(subst ','\'',$(1))
update := $(shell v='$(call shell_escape,$(somevar))'; echo $$v > file.txt)
.phony: all
all:
cat file.txt
Sample run:
$ make
cat file.txt
apple with 'quoted' "stuff" and dollar $signs
If we want to communicate an environment variable to a command, we can do that using the shell syntax VAR0=val0 VAR1=val1 ... VARn=valn command arg ...
. This can be illustrated by some minor alterations to the above Makefile
:
somevar := apple with 'quoted' "stuff" and dollar $$signs
shell_escape = $(subst ','\'',$(1))
update := $(shell somevar='$(call shell_escape,$(somevar))' env > file.txt)
.phony: all
all:
grep somevar file.txt
Run:
$ make
grep somevar file.txt
somevar=apple with 'quoted' "stuff" and dollar $signs
file.txt
contains a dump of environment variables, where we can see somevar
. If export
in GNU Make did the right thing, we would have been able to just do:
export somevar
update := $(shell env > file.txt)
but the end result is the same.
Since the end result you want is to echo $(update)
, you would shell_escape
anyway, even if GNU Make passed exported vars to $(shell ...)
. That is to say, look at one more Makefile
:
somevar := apple with 'quoted' "stuff" and dollar $$signs
shell_escape = $(subst ','\'',$(1))
update := $(shell v='$(call shell_escape,$(somevar))'; echo $$v)
.phony: all
all:
@echo '$(call shell_escape,$(update))'
@echo $(update)
Output:
apple with 'quoted' "stuff" and dollar $signs
apple with quoted stuff and dollar