如何在WAF中实现模型文件变更检测以优化代码生成?
嘿,这个需求在WAF里完全可以通过完善依赖追踪机制来解决,我给你捋捋具体的实现思路和代码示例!
核心思路
WAF的构建逻辑是基于文件依赖关系的,只要我们明确告诉WAF:.h/.cpp生成文件依赖于.m模型文件,它就会自动检测模型文件的修改时间,只有当模型文件变更时才触发代码生成和后续编译。
具体实现方案
1. 自定义代码生成Task
首先我们需要创建一个独立的Task类,专门处理代码生成逻辑,让WAF能清晰追踪输入(模型文件)和输出(生成的.h/.cpp)之间的依赖:
from waflib.Task import Task from waflib.TaskGen import feature class GenMessagingTask(Task): # 定义代码生成器的运行命令,根据你的生成器实际参数调整 run_str = '${CODE_GENERATOR} ${SRC} --output-dir ${TGT_DIR}' color = 'BLUE' # 日志中用蓝色标识这个任务的输出 ext_in = ['.m'] # 声明输入文件的扩展名 ext_out = ['.h', '.cpp'] # 声明输出文件的扩展名 def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) # 设置输出目录为模型文件所在的目录(可根据你的需求修改) self.env.TGT_DIR = self.outputs[0].parent.abspath()
2. 实现gen_messaging Feature逻辑
接下来在Feature里关联模型文件和生成任务,并把生成的文件传递给后续的编译步骤:
@feature('gen_messaging') def apply_gen_messaging(self): # 将输入的source字符串转换为WAF的Node对象,方便路径管理 model_nodes = self.to_nodes(self.source) generated_files = [] for model_node in model_nodes: # 定义每个模型文件对应的生成文件路径 h_node = model_node.change_ext('.h') cpp_node = model_node.change_ext('.cpp') generated_files.extend([h_node, cpp_node]) # 创建代码生成任务,关联输入和输出 self.create_task('GenMessagingTask', src=model_node, tgt=[h_node, cpp_node]) # 把生成的.h/.cpp替换原来的模型文件,作为后续cxx编译的源文件 self.source = generated_files
3. 配置WAF构建脚本
最后在你的wscript里配置代码生成器路径,并调用构建:
def build(bld): # 指定你的代码生成器的绝对路径 bld.env.CODE_GENERATOR = '/path/to/your/code_generator_executable' # 构建共享库,关联cxx和gen_messaging feature bld.shlib( features='cxx gen_messaging', name="messages", source='model1.m model2.m' )
关键注意事项
- 依赖追踪的核心:必须让WAF明确知道生成文件和模型文件的对应关系,上面的代码通过
create_task关联了src(模型文件)和tgt(生成文件),WAF会自动对比两者的修改时间。 - 扩展依赖:如果你的代码生成器还依赖其他文件(比如配置文件、模板),可以在
GenMessagingTask里实现scan方法,把这些额外依赖加入追踪。 - 测试验证:修改任意一个
.m文件后运行waf build,应该会触发代码生成和编译;如果不修改模型文件直接运行,WAF会提示nothing to do,说明依赖检测生效了。
内容的提问来源于stack exchange,提问作者Niklas M




