如何在Starlark中向本地磁盘写入内容并执行action?
在Starlark中执行actions.write的正确方式
核心原理
Bazel的actions.write本身就是用来声明一个写入文件的构建动作,它不会在Starlark代码运行时直接执行——因为Starlark处于Bazel的分析阶段,这个阶段只负责定义构建规则、声明动作,实际的文件写入等操作会由Bazel的执行引擎在构建执行阶段统一调度完成。
具体实现步骤
- 定义自定义规则,在规则的实现函数中用
actions.write声明写入动作:
def _write_file_impl(ctx): # 声明要生成的输出文件 output = ctx.actions.declare_file("my_content.txt") # 声明写入动作:将指定内容写入输出文件 ctx.actions.write( output = output, content = "这是要写入本地磁盘的字符串内容", ) # 返回输出文件信息,让Bazel识别这个规则的产物 return [DefaultInfo(files = depset([output]))] # 封装成可在BUILD文件中调用的规则 write_my_file = rule( implementation = _write_file_impl, attrs = {}, )
- 在BUILD文件中调用这个规则:
write_my_file(name = "generate_my_file")
- 触发Bazel执行这个动作:
在终端运行构建命令:
bazel build //:generate_my_file
执行完成后,写入的文件会出现在Bazel的构建输出目录(通常是bazel-bin/my_content.txt)。
关键说明
- 你不能在Starlark的分析阶段直接执行文件写入操作:Bazel为了保证构建的可重复性、缓存有效性,严格禁止分析阶段修改本地磁盘(除了自身的缓存目录)。所有磁盘操作必须通过
actions系列API声明,由Bazel在执行阶段处理。 actions.write的作用是告诉Bazel“需要生成这个文件,内容是XXX”,Bazel会负责处理文件的写入时机、路径管理和缓存。
内容的提问来源于stack exchange,提问作者Tinyden
相关产品推荐
相关产品推荐

