0

我正在尝试懒惰地评估配置选项。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. 如何实现所需的行为?

更新:澄清-我不想使用?=,因为这些选项是配置选项,我希望它们严格来自 Makefile 而不是来自环境。

4

2 回答 2

1

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

这是一种令人讨厌的副作用,但我不确定有什么可以直接完成的:这种行为是传统的,并且是 POSIX 强制要求的,如果更改它,许多 makefile 会中断。

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

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

于 2013-09-12T11:38:17.727 回答
0

这个问题在标题中似乎非常清楚,但实际的请求在细节中丢失了,所以唯一的其他回复几乎没有回答。直接回答标题中的问题,这很有趣,在Makefile中定义一个与环境变量同名的变量,您可以通过以下方式获取其值printenv

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

echo:
    echo $(PATH)

欢迎使用其他技术来获得相同结果,而不依赖于使用外部命令进行评估。

于 2018-08-02T09:36:12.933 回答