Makefile 是否在导出递归变量之前使其展开?
Makefile 是否在导出递归变量之前使其展开?,makefile,gnu-make,Makefile,Gnu Make,给定一个生成文件: ifeq“$(MAKELEVEL)”0 0 :: @$(制造) 其他的 1 :: @echo'foo is:“$(foo)”' 恩迪夫 然后执行,我们得到: $make foo='$@' make[1]:输入目录“/home/myname” 傅是:“1” make[1]:离开目录“/home/myname” $make foo='$@'--环境覆盖 make[1]:输入目录“/home/myname” 富是:“0” make[1]:离开目录“/home/myname”
给定一个生成文件:
ifeq“$(MAKELEVEL)”0
0 ::
@$(制造)
其他的
1 ::
@echo'foo is:“$(foo)”'
恩迪夫
然后执行,我们得到:
$make foo='$@'
make[1]:输入目录“/home/myname”
傅是:“1”
make[1]:离开目录“/home/myname”
$make foo='$@'--环境覆盖
make[1]:输入目录“/home/myname”
富是:“0”
make[1]:离开目录“/home/myname”
因此,我们这里有一个递归变量
foo
,其值为:$@
,当然,它会扩展到目标的名称。现在,我们有两个选择:
使用此“逻辑”,当Make运行第一个makefile(
MAKELEVEL=0
)时,它将构建目标0,因此:将变量foo
(及其值:$@
)展开为0
,然后将此已展开的值导出到子Make。
这个结果是,当子make运行其makefile时,变量
foo
的值很简单:0
。
事实上,当我们运行
make--environment overrides
时就是这种情况,正如您在上面示例中的makefile的第二次运行中所看到的那样。
因此,当传递给第二个Make时,所有递归变量都将保持不变。
对于该逻辑,仅允许子make递归扩展其变量,因此:任何递归扩展都将在子make的上下文中完成。
在上面的示例中,我们使用了
foo
及其值$@
,如果我们遵循此逻辑,Make将传递值$
“verbatim”,而不进行任何扩展,因此子Make将有效地看到其foo
变量的值$
,因此:当在其目标的上下文中进行扩展时,恰好是1,它将递归地将foo
(及其值:$@
)扩展到1。
实际上,这是第一次运行makefile时明显的“正常”行为,如上面的示例所示
--environment--overrides
),作为决定Make必须选择什么方法的因素
但是,我们真的能证明这些看似不相关的特性(即导出/递归与环境覆盖)最终会对彼此产生如此巨大的影响吗
(版本说明:4.0及更高版本)。
make
以扩展形式导出foo,如下所示:
target:
@echo "'$$foo'"
输出:
$make foo='$@'
'target'
$make foo='$@'
' -- foo=$$@'
但是,要将其参数传递给sub make,它不直接使用环境——而是将所有内容填充到变量MAKEFLAGS
中。在那里它通过了未展开的foo:
target:
@echo "'$$MAKEFLAGS'"
输出:
$make foo='$@'
'target'
$make foo='$@'
' -- foo=$$@'
需要明确的是:子make确实从环境中导入foo
,但随后会被MAKEFLAGS
中的设置覆盖
指定
--environment--overrides
时,意味着环境变量优先于makefile中的设置。GNU make文档没有明确指定在存在--environment--overrides
的情况下,通过MAKEFLAGS
传入的变量会发生什么情况,但显然它们也被重写了。非常好的一点。谢谢我们仍然必须解决如何和为什么这样做的问题。也就是说,命令行变量的导出是如何受到命令行选项(如--environment overrides
)的影响的。但更令人不安的是,原因何在。i、 e.为什么导出在命令行上定义的变量(仅在命令行上定义的变量)会受到看似不相关的命令行选项的影响,例如--环境覆盖
。因为从语义上讲,它总是如此(即,无论是否使用--环境覆盖
)一个命令行级别变量(当然,它比环境级别变量高一个级别,即使使用--环境覆盖
)。因此,导出wize、Make应始终使用相同(或等效)机制来执行相同类型的导出(即,要么先展开,要么不展开)。