编写Makefile规则实现zsh函数变更时自动编译.zwc文件
问题原因分析
你之前的通用规则失效,核心问题通常是以下几点:
- 依赖关系错误:比如写成
*.zwc: *.zsh这类规则,会让所有.zwc文件依赖目录下所有源文件,只要有一个源文件更新,所有.zwc都会被重新编译 - 目标列表不明确:没有精准生成需要处理的
.zwc文件列表,导致Make无法逐个判断文件的更新状态 - 规则逻辑缺陷:误用了无条件触发的规则(比如用
FORCE目标强制每次执行),或者编译命令没有正确关联源文件与目标文件
正确实现方案
以下是能实现「仅源文件变更时编译对应.zwc」的Makefile规则:
# 1. 匹配functions目录下所有zsh函数源文件(无后缀则用*,有后缀比如.zsh就改成*.zsh) SRC_FILES := $(wildcard functions/*) # 2. 生成对应的.zwc目标文件路径 ZWC_FILES := $(patsubst functions/%, functions/%.zwc, $(SRC_FILES)) # 默认执行目标:编译所有需要更新的.zwc文件 all: $(ZWC_FILES) # 3. 单个文件的编译规则:每个.zwc仅依赖对应的源文件 functions/%.zwc: functions/% zsh -c "zcompile $<" # 可选:清理所有.zwc文件的规则 clean: rm -f $(ZWC_FILES)
关键逻辑说明
$(wildcard functions/*):精准获取functions目录下的所有源文件,避免遗漏或误匹配$(patsubst ...):将每个源文件路径转换为对应的.zwc路径,生成明确的目标文件列表,让Make能逐个追踪文件状态functions/%.zwc: functions/%:这是模式规则,明确每个.zwc目标的唯一依赖是同名的源文件。Make会自动对比两者的修改时间,只有源文件更新(或.zwc不存在)时,才会执行编译命令zcompile $<:$<是Make的自动变量,代表当前规则的依赖文件(即源文件),zcompile会在源文件同目录下生成对应的.zwc编译文件
验证方式
运行make命令时:
- 如果某源文件的修改时间晚于对应的
.zwc,或.zwc不存在,会执行该文件的编译 - 所有源文件都未更新时,Make会输出
make: Nothing to be done for 'all'.,不会执行任何编译操作
内容的提问来源于stack exchange,提问作者Martin Vegter
相关产品推荐
相关产品推荐

