Bazel Genrule中跨目录Python脚本函数导入问题
Bazel跨目录Python导入解决方法
1. 目录结构确认
先对齐项目目录结构(以workspace名为project为例):
project/ ├── WORKSPACE └── test/ ├── sub1/ │ ├── test_python_script.py │ └── BUILD └── sub2/ ├── common.py └── BUILD
2. 配置sub2目录的BUILD文件
在test/sub2/BUILD中定义py_library,并开放sub1目录的访问权限:
py_library( name = "common", srcs = ["common.py"], # 允许sub1目录下的规则依赖此库 visibility = ["//test/sub1:__pkg__"], )
3. 配置sub1目录的BUILD文件
推荐用py_binary封装脚本(自动处理依赖路径),再在genrule中调用:
# 将脚本封装为py_binary,声明依赖sub2的common库 py_binary( name = "test_script", srcs = ["test_python_script.py"], deps = ["//test/sub2:common"], ) # genrule调用py_binary生成目标文件 genrule( name = "generate_file", outs = ["generated_file.txt"], cmd = "$(location test_script) > $@", tools = ["test_script"], )
若不想用py_binary,直接在genrule中调用脚本需手动设置PYTHONPATH:
genrule( name = "generate_file", outs = ["generated_file.txt"], cmd = """ # 指向runfiles下的workspace目录,让Python识别跨目录模块 PYTHONPATH=$(GENDIR)/../runfiles/project \ python $(location test_python_script.py) > $@ """, srcs = ["test_python_script.py"], # 依赖sub2的common库,确保文件被加载到运行环境 data = ["//test/sub2:common"], )
4. 修正Python脚本的导入路径
根据WORKSPACE中定义的项目名调整导入语句,假设WORKSPACE有workspace(name = "project"),则脚本中导入应为:
from project.test.sub2.common import test_python_import
关键注意点
- 可见性设置:必须显式允许sub1访问sub2的
py_library,否则Bazel会拦截依赖请求。 - 依赖声明:无论是
py_binary还是genrule,都要明确声明对sub2库的依赖,Bazel才会将相关文件纳入运行环境。 - PYTHONPATH配置:直接用genrule调用脚本时,必须手动指定PYTHONPATH指向runfiles下的workspace目录,否则Python无法定位跨目录模块。
内容的提问来源于stack exchange,提问作者roschach
相关产品推荐
相关产品推荐

