考虑以下Makefile
:
X = macro-X-value
foo:
echo $$X $(X)
这里的目的是X
同时用作环境变量和宏的名称。使用时bmake
,它按预期工作:
$ env X=env-X-value /usr/bin/bmake
echo $X macro-X-value
env-X-value macro-X-value
$ env -i /usr/bin/bmake
echo $X macro-X-value
macro-X-value
但是当使用 GNU Make(v.4.2.1)时,行为变得很奇怪:
$ env X=env-X-value /usr/bin/gmake
echo $X macro-X-value
macro-X-value macro-X-value
$ env -i /usr/bin/gmake
echo $X macro-X-value
macro-X-value
所以,看起来像gmake
出口的价值宏 X
作为
环境变量 X
, 但仅有的当外部环境已经
出口X
。
我在 中找不到任何关于此的信息POSIX 进行描述。事实上,还有这样的一点:
宏不会导出到要运行的命令的环境中。 […]
这种行为有记录吗?这是一个错误吗?可以禁用吗?
答案1
根据我从手册中读到的内容,GNU make 对待它的变量有点像 shell。当它启动时,它将变量从环境导入到其内部集,并且在运行命令时,将标记为导出的变量导出到其环境。这意味着它只有一个包含所有变量的表,并且无法拥有同名的环境变量和非环境变量。
make 中的变量可以来自 make 运行的环境。 make 启动时看到的每个环境变量都会转换为具有相同名称和值的 make 变量。
除非明确请求,否则 make 仅在最初在环境中定义或在命令行上设置的情况下导出变量 [...] 如果要将特定变量导出到子 make,请使用导出指令,如下所示:
export variable …
如果要阻止导出变量,请使用 unexport 指令,如下所示:
unexport variable …
据我测试,使用unexport X
只是将其从启动进程的环境中完全删除,似乎没有办法保留与内部变量不同的值。
使用.POSIX
内置目标似乎也没有改变这种行为,但是,意见似乎是无论如何,没有哪个 Make 对 POSIX 行为过于严格。