Adding directory to PATH through Makefile
Solution 1
You simply can't do this. There's no way¹ the make process can change its parent's environment (or its current directory, which you might be thinking of next).
In fact, even less is happending than you think.
- Not all
make
implementations reflect the assignment to the makePATH
variable in the environment; GNU make (found on Linux and other systems) does, but BSD make doesn't. - Each command line under a target runs in a separate subshell. (Except in some older BSD make implementations.) So the
export PATH
line is running on a shell that terminates immediately afterwards. Not that this line would be doing anything in the first place — ifPATH
is defined at that point, it's because it's in the shell's environment already.
Make is for building things automatically. If you want to set variables for your interactive environment, this isn't the tool you should be looking at. Instead, write a shell snippet, and source it in the current shell:
. ./define-my-variables.sh
In your makefile, source the script in every subshell. You can use a backslash to make a long command; remember that
- The backslash-newline sequence is stripped by make, so the shell won't see a newline there.
- Remember to prefix each line by a tab nonetheless.
- Make's error behavior is to abort if a command fails. The shell won't do that by default, and the failure of any command but the last will go unnoticed by default, so you need to run
set -e
.
install:
set -e; \
. ./define-my-variables.sh; \
mkdir -p bin; \
…
¹ Obligatory note: no sane way. Even remotely invoking chdir
via ptrace
from a debugger won't work as is with most shells because they don't like to have their current directory changed under their feet.
Solution 2
Your answer can be found here: https://stackoverflow.com/a/8942216/367461
Basically, you should do this:
export PATH := $(shell pwd)/bin:$(PATH)
test:
mkdir -p ./bin
@echo $(PATH)
I tested this on Fedora 23 with GNU Make 4.0, and it works fine for me.
Solution 3
You can't. It's not possible for a subprocess (like make
) to alter the environment of its parent process.
You could do something like
$ eval `make pathupdate`
Where the pathupdate
target looks like:
pathupdate:
@echo PATH=\"$(PATH)\"
Solution 4
I'm about to ask this same question because I couldn't get the other answer example to work.
However, I managed to achieve the working solution for me by using eval
command. I'm not too sure why this wasn't posted earlier.
do_something:
$(eval export PATH=$(shell pwd)/bin:$(PATH))
@echo $(PATH)
Note: the
PATH
changes is temporary within the make itself. After exit from the make, the PATH is reset to the earlier value.
Solution 5
You can cause Make to recursively call itself with a modified environment, as such:
dummy: build_all
all:
PATH=/new/directory:$(PATH) $(MAKE) build_all
build_all:
your make rules
If you want to use a shell snippet:
dummy: build_all
all:
. ./define-my-variables.sh ; $(MAKE) build_all
build_all:
your make rules
Related videos on Youtube
tshepang
I do software development for a living and as a hobby. My favorite language is Rust, and I've used Python much in the past. My OS of choice is Debian.
Updated on September 18, 2022Comments
-
tshepang almost 2 years
I'm having some trouble in exporting the PATH I've modified inside the Makefile into the current Terminal. I'm trying to add to the PATH, the bin folder inside wherever the Makefile directory is.
Here's the relevant strip of the makefile:
PATH := $(shell pwd)/bin:$(PATH) install: mkdir -p ./bin export PATH echo $(PATH)
The echo prints it correctly but if I redo the echo in the terminal, the PATH remains the same.
-
Brandon Condrey about 3 yearsThis is a poop question because it has nothing to do with a makefile.
-
Brandon Condrey about 3 yearsDoes this answer your question? Is it possible to pass environment variables from child to parent in user space?
-
-
XML almost 7 yearsEr, I think "You simply can't do this" is incorrect. See @Yeo answer: unix.stackexchange.com/a/291973/176350
-
Gilles 'SO- stop being evil' almost 7 yearsThis wasn't posted earlier because it isn't what the question asks: the question asks how to get the changed PATH after exit from make. Also, this could be done in a much simpler way: put
export PATH=…
on thedo_something:
line, you don't needeval
. -
Gilles 'SO- stop being evil' almost 7 years@XML Yeo's answer does something different which is not what the question asks for.
-
rjh about 6 yearsThis is the correct answer for GNU Make. For BSD Make, you can use
.SHELL: name=sh path=/path/to/wrapper-script
and then make a wrapper script likeexport FOO=bar; exec bash "$@"
-
Nathan almost 4 yearsThe PATH isn't being "reset", it was never changed in the parent process, only in the process make runs in, so the new PATH is only available in the make process and it's children. For somewhat obvious reasons a child process can not modify its parents environment