如何使用Bazel构建命令处理带循环的genrule及批量构建?
解决Bazel循环生成genrule的批量构建问题
核心方案
要通过单条命令构建所有循环生成的genrule,关键是创建聚合目标,将所有genrule的输出或实例纳入其中,让Bazel通过这个聚合目标自动触发所有依赖的genrule构建。
具体实现步骤
- 保存生成的genrule实例
先把列表推导式生成的genrule存到变量中,方便后续聚合:
# 生成所有genrule并保存到变量 gen_txt_rules = [genrule( name = "gen_txt_" + fin, srcs = [":sources"], outs = [fin + ".cp"], cmd = """ # 注意:原cmd存在逻辑错误,修正为复制源文件到输出路径示例: cp $(location :sources)/{fin} $@ """.format(fin=fin), ) for fin in glob(["*.in"])]
- 创建聚合filegroup目标
用filegroup把所有genrule的输出文件整合到一个统一目标下:
filegroup( name = "all_gen_txt", srcs = [rule.outs[0] for rule in gen_txt_rules], )
批量构建命令
现在只需运行单条命令,即可触发所有genrule的构建:
bazel build //your/package/path:all_gen_txt
额外说明
- 如果需要构建包内所有目标(包括其他非genrule规则),可直接使用:
但该方式会构建包内所有规则,适合无需精准控制的场景。bazel build //your/package/path:all - 原genrule的
cmd存在逻辑错误:cp $@ $@.cp会尝试复制输出文件到副本,但outs仅声明了fin + ".cp",实际生成的fin.cp.cp会与声明的输出不匹配,导致Bazel构建失败,建议修正为复制源文件到输出路径。
内容的提问来源于stack exchange,提问作者Grrrr
相关产品推荐
相关产品推荐

