如何在Bazel中为C工具链提供py_binary的.runfiles目录
解决Bazel工具链中Python包装器找不到.runfiles目录的问题
问题背景
为Clang开发处理平台逻辑的Python包装器作为Bazel自定义CC工具链,构建命令为:
bazel build --platforms=//:custom_platform //:test
构建时触发断言错误:
AssertionError: Cannot find .runfiles directory for bazel-out/k8-opt-exec-ST-d57f47055a04/bin/clang_wrapper
解决方案
1. 修改Python包装器的runfiles查找逻辑
Bazel在执行工具链中的Python脚本时,会自动设置RUNFILES_DIR环境变量指向正确的runfiles目录。修改包装器中的FindModuleSpace函数,优先读取该环境变量:
def FindModuleSpace(main_rel_path): # 优先使用Bazel设置的RUNFILES_DIR环境变量 runfiles_dir = os.environ.get('RUNFILES_DIR') if runfiles_dir and os.path.isdir(runfiles_dir): return runfiles_dir # 保留原有路径推导逻辑作为降级方案 main_abs_path = os.path.abspath(sys.argv[0]) main_dir = os.path.dirname(main_abs_path) # 检查同目录下的xxx.runfiles candidate = os.path.join(main_dir, "%s.runfiles" % os.path.basename(main_abs_path)) if os.path.isdir(candidate): return candidate # 检查同目录下的.runfiles目录 candidate = os.path.join(main_dir, ".runfiles") if os.path.isdir(candidate): return candidate raise AssertionError('Cannot find .runfiles directory for %s' % sys.argv[0])
2. 确保工具链定义正确传递runfiles
在自定义CC工具链规则中,需要显式收集Python包装器的runfiles并传递给编译动作:
- 确保
clang_wrapper的py_binary目标正确声明所有依赖(通过deps或data属性) - 在工具链实现规则中,收集并传递包装器的runfiles:
def _custom_cc_toolchain_impl(ctx): clang_wrapper = ctx.executable.clang_wrapper # 收集Python包装器的runfiles tool_runfiles = clang_wrapper[DefaultInfo].default_runfiles # 创建CC工具链信息 toolchain_info = cc_common.create_cc_toolchain_info( # ... 其他工具链配置项 tool_paths = { "clang": clang_wrapper.path, # ... 其他工具路径配置 }, ) return [ toolchain_info, DefaultInfo(runfiles=tool_runfiles), ]
3. 调整Bazel构建配置
- 升级到Bazel 6.x及以上版本,旧版本存在工具链runfiles处理的已知问题
- 构建时添加
--runfiles_manifest_only=false参数,强制Bazel生成物理的.runfiles目录(部分场景下默认使用manifest文件替代) - 通过
bazel build --sandbox_debug查看沙箱内的目录结构,确认.runfiles是否存在于预期路径
内容的提问来源于stack exchange,提问作者mallwright
相关产品推荐
相关产品推荐

