Pab*_*blo 31 variables export makefile
somevar := apple
export somevar
update := $(shell echo "v=$$somevar")
all:
@echo $(update)
Run Code Online (Sandbox Code Playgroud)
我希望苹果作为命令的输出,但它是空的,这使我认为出口和:=变量扩展发生在不同的阶段.怎么克服这个?
Bet*_*eta 33
问题是export将变量导出到命令使用的子shell; 它不适用于其他作业的扩展.所以不要试图从规则之外的环境中获取它.
somevar := apple
export somevar
update1 := $(shell perl -e 'print "method 1 $$ENV{somevar}\n"')
# Make runs the shell command, the shell does not know somevar, so update1 is "method 1 ".
update2 := perl -e 'print "method 2 $$ENV{somevar}\n"'
# Now update2 is perl -e 'print "method 2 $$ENV{somevar}\n"'
# Lest we forget:
update3 := method 3 $(somevar)
all:
echo $(update1)
$(update2)
echo $(update3)
perl -e 'print method 4 "$$ENV{somevar}\n"'
Run Code Online (Sandbox Code Playgroud)
mkl*_*nt0 16
@ Beta的答案包含关键指针:使用GNU make,标记的变量export仅可用于[为命令启动的shell] 命令(作为规则的一部分的命令),遗憾的是不能调用 $(shell ...)(它们只能看到make自己看到的环境)它被推出了).
但是有一种解决方法:显式将导出的变量作为环境变量传递给shell函数:
update := $(shell somevar='$(somevar)' perl -e 'print "$$ENV{somevar}"')
Run Code Online (Sandbox Code Playgroud)
通过预先添加shell命令<var>=<val>,该定义将作为环境变量添加到命令所看到的环境中 - 这是一个通用的shell功能.
警告:@Kaz在评论中指出,如果$(somevar)包含某些字符,此方法会出错,因为变量扩展是逐字的(无转义),这可能会破坏生成的shell命令,并建议以下变体也适用于嵌入式'实例(将输入值分为单引号子串,引用'拼接in):
update := $(shell somevar='$(subst ','\'',$(somevar))' perl -e 'print "$$ENV{somevar}"')
Run Code Online (Sandbox Code Playgroud)
这应该适用于除多行之外的所有值(这种情况很少见;我所知道的多行值没有解决方法).
旁注,文字$字符.in值必须表示为$$,否则make将把它们解释为对自己变量的引用.
请注意,我故意不选择OP的原始语句,update := $(shell echo "v=$$somevar")用于演示,因为它包含一个混淆问题的陷阱:由于shell如何评估命令行,somevar=apple echo v=$somevar不评估v=apple,因为$somevar引用在 somevar=apple生效之前已经生效.要在这种情况下达到预期效果,您必须使用2个语句:update := $(shell export somevar="$(somevar)"; echo "v=$$somevar")
至于漏洞与特征的争论:
虽然可以说该shell函数应该看到与配方命令相同的环境,但文档没有做出这样的承诺 - 请参阅http://www.gnu.org/software/make/manual/make.html#Shell-Function.相反,http://www.gnu.org/software/make/manual/make.html#Variables_002fRecursion仅提到使导出变量可用于配方命令.
Sco*_*les 10
运行makefile
foo:=apple
export foo
all:
@echo ">"$(shell echo "$$foo")
@echo ">""$$foo"
Run Code Online (Sandbox Code Playgroud)
给我(在环境中未定义foo)
$ make
>
>apple
$ make foo=bar
>
>apple
$ export foo=bar; make
>bar
>apple
$ export foo=bar; make foo=bar
>bar
>bar
Run Code Online (Sandbox Code Playgroud)
尝试使用带引号的表单(update := "v=$$somevar")并在运行命令时让shell处理扩展(您仍然需要导出)
| 归档时间: |
|
| 查看次数: |
72435 次 |
| 最近记录: |