I found this an interesting problem so took a little time from the day job to look into it. There are a number of issues here. First, not directly related but environment variables are supposed to be uppercase by convention though it's not enforced. Even when a variable is passed on the command line it's supposed to be uppercase according to the manual "How To Use Variables". I have a possible solution for the command-line case but not for the environment case.
Second, the variable must be "fixed" before reaching the recipe as shown in the sample makefile below. The trick here is to convert it from a recursively-expanded variable, which all vars passed on the command line are, to simply-expanded which will prevent it from being expanded again when evaluated so the $ is left alone. Third, if passed in from the command line an override directive is required to change it. Fourth, even after all that's solved all you've done is pass the escaping problem on to the shell where $$ will evaluate to the pid. The echo must use single quotes to prevent this. My example shows a solution for command line overrides because those are accessible via MAKEOVERRIDES. When FOO comes in through the environment there's no automated way to know which variables to fix so you'd need to work off a static list of variables. Also, the MAKEOVERRIDES variable is pre-escaped for passing on to child processes which this trick relies on. I haven't thought of a way to fix an environment variable since the pre-escaped value isn't available. David $ cat Makefile $(foreach ov,$(MAKEOVERRIDES),$(eval override $(subst =,:=,$(ov)))) debug: @echo 'FOO=$(FOO)' $ make FOO='FOO$FOO' FOO=FOO$FOO On Thu, Sep 2, 2021 at 6:51 AM Brian J. Murrell <br...@interlinx.bc.ca> wrote: > Given a Makefile: > > debug: > echo "$(foo)" > echo "$(subst $,$$,$(foo))" > echo "$(subst $$,%,$(foo))" > > and given the make command: > > $ foo='FOO$BAR' make -f /tmp/Makefile > > How can I get make to not try to resolve the $ in the value as it seems > to be doing for all of the echos in the debug target: > > $ foo='FOO$BAR' make -f /tmp/Makefile > echo "FOOAR" > FOOAR > echo "FOOAR" > FOOAR > echo "FOOAR" > FOOAR > > I suppose the $(subst) attempts are too late and $(foo) has it's $B > resolved as the variable is expanded before $(subst) can even get a > chance to try to escape it. > > An obvious solution is to escape the $ in the caller's foo assignment > before calling make, but that is asking the caller to do something > surprising simply to appease make. Not nice to do. > > Any solutions other than asking the caller to alter their normal > behaviour? > > Cheers, > b. > >