如何在waf中定义支持文件输入的符号化构建任务
Waf 实现类 Make 伪目标与文件依赖任务的方案
Waf 没有和 Make .PHONY 完全同名的概念,但通过任务生成器的属性配置,可以1:1实现你需要的伪目标、文件依赖、有序执行逻辑,且依赖追踪精度比Make更高(默认按文件内容哈希判断是否需要重构建,而非仅时间戳)。
核心实现逻辑
你给出的Make示例可以拆为两类任务:生成实际文件的zip打包任务、无实际文件产出的伪目标复制任务,两类任务在Waf中都在工程根目录的wscript文件中定义。
1. 定义文件生成类任务
对应Make中生成file123、filexyz的zip规则,Waf要求明确声明每个任务的输入源文件、输出目标文件、执行命令,框架会自动处理依赖顺序和增量构建判断:
# wscript 完整示例 def build(bld): # 打包生成file123.zip,等价make中file123规则 bld( rule = 'zip ${TGT} ${SRC}', source = ['input1', 'input2'], target = 'file123.zip' ) # 打包生成filexyz.zip,等价make中filexyz规则 bld( rule = 'zip ${TGT} ${SRC}', source = ['input11', 'input12'], target = 'filexyz.zip' )
代码中${SRC}、${TGT}是Waf内置变量,会自动替换为你声明的输入、输出文件路径,避免手动拼路径出错。
2. 定义等价PHONY的伪目标任务
对应Make中.PHONY: command1的规则,只需要给任务加上两个关键属性:
name:指定任务的调用名,对应Make中伪目标的名称always=True:标记该任务不检查文件系统中是否存在同名输出文件,只要被调用就触发执行,同时会自动先跑完所有依赖的前置文件任务
# 接上面的build函数内代码 # 伪目标command1,等价make中.PHONY标记的command1规则 bld( rule = 'cp ${SRC} targetdir/', source = ['file123.zip', 'filexyz.zip'], always = True, name = 'command1' )
调用方式
和执行make command1逻辑完全一致,在工程目录下执行命令即可:
./waf build command1
Waf会自动按依赖顺序执行:
- 先检查input1、input2的内容是否有变化,有变更则重新生成file123.zip
- 再检查input11、input12的内容是否有变化,有变更则重新生成filexyz.zip
- 两个前置文件都就绪后,执行复制命令将两个压缩包拷贝到targetdir目录
优化建议
- 如果不需要每次调用command1都执行复制,只想在前置压缩包变化时才触发复制,可以去掉
always=True,给任务加一个标记输出文件target='command1.stamp',Waf会通过这个stamp文件的状态判断是否需要重跑,构建效率更高 - 复制、压缩这类通用操作不用手动写shell命令,Waf内置了跨平台的实现,比如复制文件可以直接用内置copy特性,避免Windows/macOS/Linux平台命令差异问题:
# 内置copy特性示例,无需写cp/xcopy等平台相关命令 bld( features = 'copy', source = ['file123.zip', 'filexyz.zip'], install_path = 'targetdir/', always = True, name = 'command1' )
内容的提问来源于stack exchange,提问作者maver
相关产品推荐
相关产品推荐

