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

Make赋值命令不符合预期:延迟与立即赋值未按文档表现

Makefile延迟/立即变量求值不符合预期的问题

测试用Makefile代码

A = $(shell date)
B := $(shell date)

all:
  @echo $(A)
  sleep 2s;
  @echo $(A)
  sleep 2s;
  @echo $(A)
  @echo $(B)

预期与实际结果

根据Make文档说明,B属于立即展开变量(:=),会在Make启动时立即求值;A属于延迟展开变量(=),会在每次被调用时重新求值。

原本预期echo $(B)会输出最早的时间,而三次echo $(A)会依次输出递增的时间,但实际所有输出的时间值完全相同:

Wed Jun 11 12:44:46 CEST 2025
sleep 2s;
Wed Jun 11 12:44:46 CEST 2025
sleep 2s;
Wed Jun 11 12:44:46 CEST 2025
Wed Jun 11 12:44:46 CEST 2025

已测试Make版本3.1和4.1,在Rocky OS和Ubuntu系统上均得到相同结果。

问题原因与解决方法

原因

Make在解析规则的命令列表时,会提前将所有变量展开为最终的shell命令,之后才把整个命令序列交给shell一次性执行。也就是说,三次$(A)在Make解析阶段就已经被展开为同一个date的输出值,后续shell执行时只是重复输出这个固定值,自然不会随时间变化。B作为立即展开变量,值在Make启动时就已确定,所以也和其他输出时间一致。

解决方法

要实现每次输出不同的时间,需要让date命令在shell执行阶段才被调用,而非Make解析阶段,有两种常用方式:

  1. 使用shell转义:用$$(date)代替$(shell date),让shell负责执行date命令:
all:
  @echo $$(date)
  sleep 2s;
  @echo $$(date)
  sleep 2s;
  @echo $$(date)
  @echo $(shell date)
  1. 拆分规则步骤:将每个echo命令拆分为独立的目标步骤,Make会在执行每个步骤前重新展开变量:
A = $(shell date)
B := $(shell date)

all: step1 step2 step3 step4

step1:
  @echo $(A)

step2:
  sleep 2s;
  @echo $(A)

step3:
  sleep 2s;
  @echo $(A)

step4:
  @echo $(B)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 21:59:54