如何解决如何配置 GNU Make 以将导出的变量传递给 shell 函数?
我在 GNU Make 中遇到了一个意想不到的奇怪现象,但找不到合理配置它的方法。我将 SHELL
分配给我自己设计的自定义 shell,但导出哪些变量的问题很容易用一个简单的 bash shell 重现:
SHELL := /bin/bash
export FOO := bar
.PHONY: all a b c
all: a b
a:
@echo A: $$(env | grep FOO)
b:
@echo B: $(shell env | grep FOO)
c:
@echo === main target ===
@echo $$(env | sed -e 's/=.*//')
@echo === shell function ===
@echo $(shell env | sed -e 's/=.*//')
这产生了一个有点出乎意料的结果:
$ make
A: FOO=bar
B:
$ FOO=baz make
A: FOO=bar
B: FOO=baz
如 communicating variables 中所述,导出的 FOO
变量作为环境变量公开给在配方中运行行的 shell。出乎意料的是,
shell function 没有得到同样的待遇!事实上,快速浏览一下 make c
中出现的内容,有几个变量没有通过。我可以通过手动传入每个变量来解决这个问题(例如 $(shell FOO="$(FOO)" env)
),但这会很快变得愚蠢(和危险)。
这尤其成问题,因为我希望导出的变量是 PATH
。构建我的目标的 shell 有一个 PATH
变量,而在 shell 函数中运行的任何东西都具有不同的 PATH
,这一事实是有问题的。如果你查看完整的 env
如何从我的 Makefile
环境中标记一些变量,以便它们作为环境的一部分自动传递给从 shell 函数运行的 shell?
解决方法
正如@MadScientist 所指出的,$(shell ...)
没有传递导出变量。视情况而定,如果已知环境变量的数量,则可以对 shell 命令使用显式变量。例如
c:
@echo === shell function ===
@echo $(shell FOO=$FOO env | sed -e 's/=.*//')
当然,这个解决方案假设可以枚举所有要传递的变量,并且变量的数量相当少,否则代码会变得丑陋。
作为替代方案,请考虑使用临时文件,而不是使用 make values 来传递值
c:
# env var are set,store result in var.txt
do-something > var.txt
# Uses the result of the previous step,from var.txt
step2 $$(cat var.txt)
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。