仅当宏已经存在时,GNU Make 才会将宏导出为环境变量

仅当宏已经存在时,GNU Make 才会将宏导出为环境变量

考虑以下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。当它启动时,它将变量从环境导入到其内部集,并且在运行命令时,将标记为导出的变量导出到其环境。这意味着它只有一个包含所有变量的表,并且无法拥有同名的环境变量和非环境变量。

6.10 来自环境的变量:

make 中的变量可以来自 make 运行的环境。 make 启动时看到的每个环境变量都会转换为具有相同名称和值的 make 变量。

5.7.2 将变量传递给子品牌:

除非明确请求,否则 make 仅在最初在环境中定义或在命令行上设置的情况下导出变量 [...] 如果要将特定变量导出到子 make,请使用导出指令,如下所示:

export variable …

如果要阻止导出变量,请使用 unexport 指令,如下所示:

unexport variable …

据我测试,使用unexport X只是将其从启动进程的环境中完全删除,似乎没有办法保留与内部变量不同的值。


使用.POSIX内置目标似乎也没有改变这种行为,但是,意见似乎是无论如何,没有哪个 Make 对 POSIX 行为过于严格。

相关内容