定义与环境变量同名的递归扩展变量

时间:2013-09-12 10:54:39

标签: makefile gnu-make

我正试图懒洋洋地评估配置选项。我只想在实际使用(替换)变量时才发出Make错误。

考虑以下Makefile:

VAR = $(error "E")

NFS_DIR = NFS_DIR is $(VAR)

T = $(NFS_DIR) is 1

all:
    echo Test

如果我使用我的环境(具有/srv/nfs值)运行它,则输出如下:

➜  ~  make
echo Test
Makefile:3: *** "E".  Stop.

因此递归定义就像简单定义一样。

如果我清除环境,它会按预期工作:

➜  ~  env -i make  
echo Test
Test

我找不到任何提及递归扩展变量,当用环境变量同名定义时,将像简单扩展变量一样。

所以问题是:

  1. 为什么观察到的行为?
  2. 如何实现所需的行为?
  3. 更新:澄清 - 我不想使用?=,因为选项是配置选项我希望它们严格来自Makefile,而不是来自环境。

2 个答案:

答案 0 :(得分:1)

make启动时环境中的任何变量都将被导出到任何命令make运行的环境中(作为配方的一部分等)为了让make将变量的值发送给命令,首先必须扩大它。它不像一个简单扩展的变量。只是运行命令会强制扩展。

这是一种令人讨厌的副作用,但我不确定是否有任何可以直接完成的事情:这种行为是传统的,并且由POSIX强制执行,如果更改了许多makefile会破坏。

你有两个我能想到的选择。第一种是使用unexport make命令告诉make不要在命令环境中发送该变量。

第二种方法是将make中变量的名称更改为非有效环境变量:make只会导出名称为合法shell变量的变量(仅包含字母数字加_)。因此,使用VAR-local而不是VAR之类的名称可以做到这一点。

答案 1 :(得分:0)

该问题在标题中看起来非常清楚,但是实际的请求没有详细说明,因此仅有其他答复大部分未得到答复。直接回答标题中的问题(非常有趣),以在Makefile中定义与环境变量同名的变量,您可以使用printenv来获取其值:

PATH=${shell printenv PATH}:/opt/bin

echo:
    echo $(PATH)

欢迎使用其他技术来获得相同的结果而无需依靠外部命令进行评估。