Search code examples
bashmakefilesubst

Makefile subst variable not affected?


I want to perform a string substitution in my Makefile. I can easily do this with a string literal like so:

foo:
    echo $(subst /,-,"hello/world")

Which yields the expected:

hello-world

But when I switch to using a variable, I can't seem to get the substitution to stick:

foo:
    x="hello/world" ; \
    echo $(subst /,-,$$x)

Instead of replacing the slash with a dash, I still get the original string printed back. Can someone explain what is going on here? Does the variable need to be explicitly converted to a string literal or something?

UPDATE:

The fix based on MadScientist's answer--this will allow me to reference the modified string as a variable.

foo:
    x="hello/world" ; \
    y=`echo $$x | tr / -` ; \
    echo $$y

But instead of echo $$y this could be something more useful.


Solution

  • You can't combine make functions with shell variables... all make functions are expanded first, then the resulting script is passed to the shell to be run. When the shell gets the script there are no more make functions in it (and if there were, the shell wouldn't know what to do with them!)

    Your subst is running on the literal string $x, which has no / so nothing to replace and results in $x, which the shell expands to the string hello/world.

    If you have to work on a shell variable value you must use shell commands such as sed or tr, not make's subst function:

    foo:
            x="hello/world" ; \
            echo $$x | tr / -