You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Automake脚本中实现GNU Make式的简单变量展开?

在Automake的Makefile.am中实现GNU Make的简单展开变量语义

GNU Make有两种变量展开风格:递归展开和简单展开。其中VARIABLE:=VALUE是简单展开,定义时就会解析右侧表达式,后续修改原变量不会影响它的值。但直接在Makefile.am中使用这种写法时,Automake生成的Makefile会调整变量定义顺序,导致简单展开的语义失效。

问题示例

直接在Makefile中的表现

运行以下Makefile代码,GNU Make会输出common:

a = common
b := $(a)
a = A
$(info $(b))

因为b是简单展开变量,定义时就取了a当时的值common,后续修改a不影响b。

放入Makefile.am后的表现

把相同代码放到Makefile.am中,Automake生成的Makefile会调整变量顺序,变成:

a = A
b := $(a)
...
$(info $(b))

此时Make运行会输出A,简单展开的语义被破坏——这是因为Automake会收集所有变量定义,按类型重新排序输出,打乱了原本的定义顺序。

实现简单展开语义的方法

要在Makefile.am中保留原本的变量定义顺序,从而实现真正的简单展开,可以用$(eval ...)包裹变量定义逻辑,让Automake将其作为原始Make代码直接保留,不做顺序调整:

$(eval a = common)
$(eval b := $(a))
$(eval a = A)
$(info $(b))

这样生成的Makefile会原封不动保留这几行代码,Make运行时会按定义顺序执行,b会被赋值为common,符合预期的简单展开语义。

原理说明

Automake在处理Makefile.am时,会对普通的变量定义进行归类整理,比如把所有递归展开变量(=定义的)放在一起,简单展开变量(:=定义的)放在一起,导致原本的定义顺序被打乱。而$(eval ...)是GNU Make的内置函数,Automake不会解析其内部内容,只会将整个$(eval ...)块原封不动输出到生成的Makefile中,因此能严格保留变量定义的顺序,实现简单展开的语义。

内容的提问来源于stack exchange,提问作者dais

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 02:40:40