You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在Bazel中基于WORKSPACE实现带补丁的Python构建工具方案

解决方案:基于WORKSPACE的Python工具依赖C++库构建流程

以下是针对你提出的四个问题的具体解决方法,结合WORKSPACE、BUILD配置和补丁应用的完整示例:

问题1:Python脚本相对导入报错

相对导入失败是因为Bazel运行Python脚本时,默认不会将包目录加入sys.path。解决方法是将foo包定义为py_library,再用py_binary封装baz.py,确保导入路径正确:

在foo包对应的BUILD文件(如foo/BUILD)中添加:

py_library(
    name = "foo_lib",
    srcs = glob(["**/*.py"]),
    visibility = ["//visibility:public"],
)

py_binary(
    name = "baz_script",
    main = "bar/baz.py",
    deps = [":foo_lib"],
    visibility = ["//visibility:public"],
)

这样Bazel会自动处理Python包的导入路径,from . import qux就能正常找到父包。

问题2:给Python包应用补丁

使用http_archive拉取foo包后,通过patches和patch_args参数直接应用补丁,再用py_repository将其转为Python依赖。注意补丁路径要相对于WORKSPACE目录:

在WORKSPACE中添加:

http_archive(
    name = "foo_raw",
    urls = ["https://github.com/xxx/foo/archive/refs/tags/v1.0.0.tar.gz"],
    strip_prefix = "foo-1.0.0",
    patches = ["//:baz.patch"],  # 相对于WORKSPACE的补丁路径
    patch_args = ["-p1"],  # 根据补丁生成时的层级调整参数
)

py_repository(
    name = "foo",
    root = "@foo_raw//",
)

如果补丁是本地文件,需在根目录BUILD文件中声明为filegroup:

filegroup(
    name = "baz_patch",
    srcs = ["baz.patch"],
    visibility = ["//visibility:public"],
)

问题3:自动生成requirements_lock.txt

使用rules_python的pip_generate_lockfile函数,在WORKSPACE中自动生成锁文件,无需手动执行bazel run //:requirements.update:

load("@rules_python//python:pip.bzl", "pip_generate_lockfile", "pip_parse")

pip_generate_lockfile(
    name = "generate_requirements_lock",
    requirements = "//:requirements.txt",  # 你的依赖清单
    output = "//:requirements_lock.txt",
)

pip_parse(
    name = "pip_deps",
    requirements_lock = "@//:requirements_lock.txt",
)

load("@pip_deps//:requirements.bzl", "pip_install")

pip_install()

构建时Bazel会自动生成锁文件,无需手动预处理。

问题4:foo包无入口点导致run_binary报错

直接运行未定义入口点的包会失败,需调用自定义的baz_script(问题1中定义的py_binary)。在根目录BUILD文件中用genrule运行脚本生成C++源文件:

genrule(
    name = "generate_cpp_sources",
    outs = ["generated_source.cpp", "generated_header.h"],
    cmd = "$(execpath @foo//:baz_script) --output $(@D)",
    tools = ["@foo//:baz_script"],
)

cc_library(
    name = "my_cpp_lib",
    srcs = ["src/my_lib.cpp", ":generate_cpp_sources"],
    hdrs = ["include/my_lib.h", ":generate_cpp_sources"],
    visibility = ["//visibility:public"],
)

也可直接用run_binary调用自定义目标:

load("@rules_python//python:run_binary.bzl", "run_binary")

run_binary(
    name = "run_baz_script",
    tool = "@foo//:baz_script",
    arguments = [
        "--output", "$(location generated_source.cpp)",
    ],
    outputs = ["generated_source.cpp"],
)

完整配置示例

WORKSPACE文件

workspace(name = "my_cpp_project")

load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")

# 导入rules_python
http_archive(
    name = "rules_python",
    urls = ["https://github.com/bazelbuild/rules_python/releases/download/0.25.0/rules_python-0.25.0.tar.gz"],
    sha256 = "f999a87c42222784f75b37a89144c1b9395e977e9d50974cb754a6b19d75e954",
)

# 自动生成锁文件并导入Python依赖
load("@rules_python//python:pip.bzl", "pip_generate_lockfile", "pip_parse")

pip_generate_lockfile(
    name = "generate_requirements_lock",
    requirements = "//:requirements.txt",
    output = "//:requirements_lock.txt",
)

pip_parse(
    name = "pip_deps",
    requirements_lock = "@//:requirements_lock.txt",
)

load("@pip_deps//:requirements.bzl", "pip_install")
pip_install()

# 拉取并修补foo包
http_archive(
    name = "foo_raw",
    urls = ["https://github.com/xxx/foo/archive/v1.0.0.tar.gz"],
    strip_prefix = "foo-1.0.0",
    patches = ["//:baz.patch"],
    patch_args = ["-p1"],
)

py_repository(
    name = "foo",
    root = "@foo_raw//",
)

根目录BUILD文件

filegroup(
    name = "baz_patch",
    srcs = ["baz.patch"],
    visibility = ["//visibility:public"],
)

genrule(
    name = "generate_cpp_sources",
    outs = ["generated_source.cpp", "generated_header.h"],
    cmd = "$(execpath @foo//:baz_script) --output $(@D)",
    tools = ["@foo//:baz_script"],
)

cc_library(
    name = "my_cpp_lib",
    srcs = ["src/my_lib.cpp", ":generate_cpp_sources"],
    hdrs = ["include/my_lib.h", ":generate_cpp_sources"],
    visibility = ["//visibility:public"],
)

foo/BUILD(手动添加)

如果拉取的foo包无BUILD文件,需手动创建@foo_raw//:BUILD:

py_library(
    name = "foo_lib",
    srcs = glob(["**/*.py"]),
    visibility = ["//visibility:public"],
)

py_binary(
    name = "baz_script",
    main = "bar/baz.py",
    deps = [":foo_lib"],
    visibility = ["//visibility:public"],
)

内容的提问来源于stack exchange,提问作者cstal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 05:45:10