能否将目录设为Ninja构建的依赖项?
Ninja构建是否支持目录作为依赖项?
问题描述
Ninja构建默认支持将文件作为依赖项,请问是否支持将目录作为依赖项?希望当目录内容发生变更(如新增或删除文件)时,能触发对应的构建规则。例如现有以下构建规则,希望该规则不仅依赖指定的构建脚本,还能在脚本所在目录内容变更时触发:
# Regenerate build files if build script changes. rule configure command = ${configure_env}python $root/configure.py $configure_args generator = 1 build build.ninja: configure | $root/configure.py $root/misc/ninja_syntax.py
解决方案
Ninja本身不直接支持将目录作为有效依赖项——因为它依赖文件的修改时间(mtime)触发构建,而目录的mtime仅在目录元数据(如重命名、权限变更)修改时才会更新,目录内新增/删除文件不会改变目录的mtime,所以直接依赖目录无法实现需求。
要实现目录内容变更触发构建,有两种实用方法:
方法1:生成目录内容清单作为依赖
通过脚本生成目标目录的文件清单,将清单文件作为依赖项,当目录内容变化时,清单文件会更新,从而触发构建:
- 添加生成目录清单的规则:
rule generate_dir_list command = find $dir_path -type f | sort > $out
- 修改原有构建规则,添加清单依赖:
# 生成misc目录的文件清单 build misc_dir_contents.txt: generate_dir_list dir_path = $root/misc # 让configure规则依赖清单文件 build build.ninja: configure | $root/configure.py $root/misc/ninja_syntax.py misc_dir_contents.txt
这样每次构建时,Ninja会检查清单文件的mtime,若目录内容有变化,generate_dir_list规则会更新清单,进而触发configure规则重新生成build.ninja。
方法2:在构建脚本内检查目录内容
直接修改configure.py脚本,添加目录内容检查逻辑:
- 在脚本中遍历目标目录,记录所有文件的修改时间或哈希值
- 将上次构建的记录保存到一个临时文件(如
dir_state.cache) - 每次运行脚本时比对当前目录状态与缓存记录,若有变化则重新生成
build.ninja
这种方法无需额外的Ninja规则,但需要修改构建脚本的逻辑。
内容的提问来源于stack exchange,提问作者SRobertJames
相关产品推荐
相关产品推荐

