我在将 Makefile 中修改的 PATH 导出到当前终端时遇到一些问题。我正在尝试将 Makefile 目录所在的 bin 文件夹添加到 PATH 中。
这是 makefile 的相关部分:
PATH := $(shell pwd)/bin:$(PATH)
install:
mkdir -p ./bin
export PATH
echo $(PATH)
echo 可以正确打印它,但是如果我在终端中重做 echo,则 PATH 保持不变。
答案1
你根本无法做到这一点。 make 进程无法更改其父级环境(或其当前目录,您接下来可能会想到)。
事实上,发生的事情比你想象的还要少。
- 并非所有实现都会反映对环境中
make
make 变量的赋值;PATH
GNU make(在 Linux 和其他系统上找到)可以,但 BSD make 不能。 - 目标下的每个命令行都在单独的子 shell 中运行。 (除了一些较旧的 BSD make 实现。)因此该
export PATH
行在 shell 上运行,然后立即终止。并不是说这一行首先会做任何事情 - 如果PATH
在那时定义,那是因为它已经在 shell 的环境中。
Make 是为了自动构建东西。如果您想为交互式环境设置变量,那么这不是您应该考虑的工具。相反,编写一个 shell 片段,然后来源在当前 shell 中:
. ./define-my-variables.sh
在您的 makefile 中,获取脚本在每个子shell中。您可以使用反斜杠来组成长命令;请记住
- 反斜杠换行序列被 make 去除,因此 shell 不会在那里看到换行符。
- 尽管如此,请记住在每行前面添加一个制表符。
- Make 的错误行为是在命令失败时中止。默认情况下,shell 不会执行此操作,并且默认情况下,除最后一个命令之外的任何命令的失败都不会被注意到,因此您需要运行
set -e
.
install:
set -e; \
. ./define-my-variables.sh; \
mkdir -p bin; \
…
1必须注意:没有明智的方法。即使从调试器远程调用chdir
via也ptrace
无法像大多数 shell 那样工作,因为它们不喜欢在其脚下更改当前目录。
答案2
您可以在这里找到答案:https://stackoverflow.com/a/8942216/367461
基本上,你应该这样做:
export PATH := $(shell pwd)/bin:$(PATH)
test:
mkdir -p ./bin
@echo $(PATH)
我在 Fedora 23 上使用 GNU Make 4.0 对此进行了测试,它对我来说工作得很好。
答案3
你不能。子进程(如 )不可能make
改变其父进程的环境。
你可以做类似的事情
$ eval `make pathupdate`
目标pathupdate
看起来像:
pathupdate:
@echo PATH=\"$(PATH)\"
答案4
您可以使 Make 使用修改后的环境递归调用自身,如下所示:
dummy: build_all
all:
PATH=/new/directory:$(PATH) $(MAKE) build_all
build_all:
your make rules
如果你想使用 shell 片段:
dummy: build_all
all:
. ./define-my-variables.sh ; $(MAKE) build_all
build_all:
your make rules