user541686
user541686

Reputation: 210525

How to change PATH for Makefile $(shell ...) commands?

When I run

export PATH := mypath
$(error $(shell echo "$${PATH}"))

it seems my PATH isn't changed on the call to shell.

Why is this and how do I actually change the PATH for shell calls?

Upvotes: 5

Views: 1338

Answers (2)

Stefan Becker
Stefan Becker

Reputation: 5962

The solution is simple: never ever use $(shell) or export.

Environment variables should be part of the recipe that needs them.

For $(shell) invocations that are supposed to fill a makefile variable you can use instead.

  • it also has the advantage to be more flexible, because you can fill more than one variable with one recipe
  • you can also define proper dependencies, whereas $(shell) is always executed, either when the makefile is parsed or the recursively expanded variable gets expanded.
  • you get build errors and recipes are logged, whereas $(shell) can make the DevOp engineers life a living h...
PATH := mypath

Makefile.variables:
    @PATH=$(PATH) echo "This my path '$${PATH}'"
    echo >$@ "MY_DYNAMIC_CONTENT := abcd"

include Makefile.variables

$(info MY_DYNAMIC_CONTENT '$(MY_DYNAMIC_CONTENT)')

Example run:

$ make
MY_DYNAMIC_CONTENT ''
This my path 'mypath'
echo >Makefile.variables "MY_DYNAMIC_CONTENT := abcd"
MY_DYNAMIC_CONTENT 'abcd'
make: 'Makefile.variables' is up to date.

Upvotes: 1

Florian Weimer
Florian Weimer

Reputation: 33719

Is this with GNU make? There is a long-standing GNU make feature request to honor exported variables with $(shell …). This is not specific to PATH at all, it affects (or does not affect) all export variables.

According to the GNU make sources, this is tricky to implement:

  /* Using a target environment for 'shell' loses in cases like:
       export var = $(shell echo foobie)
       bad := $(var)
     because target_environment hits a loop trying to expand $(var) to put it
     in the environment.  This is even more confusing when 'var' was not
     explicitly exported, but just appeared in the calling environment.

     See Savannah bug #10593.

  envp = target_environment (NULL);
  */

Upvotes: 3

Related Questions