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

Make中无执行脚本的目标首次调用不评估时间戳是否为预期行为?

GNU Make依赖更新检测的异常行为疑问

背景:强制目标的定义

若规则无依赖或执行脚本(recipe),且目标文件不存在,Make会认为该目标每次运行时都已更新,这意味着所有依赖此目标的规则都会始终执行其脚本。

用户认为强制目标的前提是目标文件不存在,因此下述案例不属于强制目标场景。

Makefile示例

.PHONY: update-db-type
.DEFAULT: run-only-if-env-var-updated

ifeq ("$(shell echo $$DB_TYPE)","mysql")
DB_TYPE := mysql
else
DB_TYPE := tidb
endif

run-only-if-env-var-updated: db_type
    echo "Do an expensive operation"
    sleep 1
    touch $@

# Note that db_type is a real file.
db_type: update-db-type

update-db-type:
    echo "DB_TYPE: $(DB_TYPE)"
ifneq ("$(shell cat db_type)","$(DB_TYPE)")
    echo "$(DB_TYPE)" > db_type
endif

执行命令及输出

echo mysql > db_type
DB_TYPE=mysql make
# Output
# echo "DB_TYPE: mysql"
# DB_TYPE: mysql
# echo "Do an expensive operation"
# Do an expensive operation
# sleep 1
# touch run-only-if-env-var-updated

DB_TYPE=tidb make
# Output
# echo "DB_TYPE: tidb"
# DB_TYPE: tidb
# echo "tidb" > db_type

DB_TYPE=tidb make
# echo "DB_TYPE: tidb"
# DB_TYPE: tidb
# echo "Do an expensive operation"
# Do an expensive operation
# sleep 1
# touch run-only-if-env-var-updated

现象分析

可以看到,耗时操作run-only-if-env-var-updated仅在第二次执行DB_TYPE=tidb make时运行。这表明首次执行时,Make未检测到文件db_type的时间戳已更新且晚于run-only-if-env-var-updated,与预期的“Make始终比较依赖与目标时间戳来判断是否执行”不符。

若给目标db_type添加非空执行脚本,修改后的规则如下:

db_type: update-db-type
    echo "Running DB_TYPE"

此时首次执行DB_TYPE=tidb make时,耗时操作会按预期运行。

疑问

第一个示例(无额外echo脚本)中的行为是否为Make的预期行为?若是,是否有文档解释为何首次执行会忽略更新的时间戳?

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 15:03:20