我如何指定在Bazel中使用哪个Python工具链?



我如何配置Bazel来选择一个工具链而不是另一个?我可以通过命令行参数定义使用哪个工具链,或者指定应该在特定目标中使用哪个工具链。

目前在我的WORKSPACE文件中定义了两个工具链。我有两个Python工具链。其中一个从源代码构建Python,并将其包含在可执行的.zip输出中,而另一个没有。

在构建时,使用的工具链总是注册的第一个工具链。在本例中,即使构建目标从hermetic_python3_toolchain导入requirement,也使用python3_tooolchain

# WORKSPACE
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
load("@rules_python//python:pip.bzl", "pip_install")
http_archive(
name = "rules_python",
url = "https://github.com/bazelbuild/rules_python/releases/download/0.5.0/rules_python-0.5.0.tar.gz",
sha256 = "cd6730ed53a002c56ce4e2f396ba3b3be262fd7cb68339f0377a45e8227fe332",
)
# Non-hermetic toolchain 
register_toolchains("//src:python3_toolchain")
pip_install(
quiet = False,
name = "python_dependencies",
requirements = "//:requirements.txt",
python_interpreter = "/usr/bin/python3"
)
load("@python_dependencies//:requirements.bzl", "requirement")


# Hermetic toolchain 
_py_configure = """
if [[ "$OSTYPE" == "darwin"* ]]; then
./configure --prefix=$(pwd)/bazel_install --with-openssl=$(brew --prefix openssl)
else
./configure --prefix=$(pwd)/bazel_install
fi
"""
http_archive(
name = "hermetic_interpreter",
urls = ["https://www.python.org/ftp/python/3.11.0/Python-3.11.0.tar.xz"],
sha256 = "a57dc82d77358617ba65b9841cee1e3b441f386c3789ddc0676eca077f2951c3",
strip_prefix = "Python-3.11.0",
patch_cmds = [
"mkdir $(pwd)/bazel_install",
_py_configure,
"make",
"make install",
"ln -s bazel_install/bin/python3 python_bin",
],
build_file_content = """
exports_files(["python_bin"])
filegroup(
name = "files",
srcs = glob(["bazel_install/**"], exclude = ["**/* *"]),
visibility = ["//visibility:public"],
)
""",
)
pip_install(
name = "hermetic_python3_dependencies",
requirements = "//:requirements.txt",
python_interpreter_target = "@hermetic_interpreter//:python_bin",
)
load("@hermetic_python3_dependencies//:requirements.bzl", "requirement")


load("@rules_python//python:defs.bzl", "py_binary")
load("@rules_python//python:defs.bzl", "py_library")
register_toolchains("//src:hermetic_python3_toolchain")
# src/BUILD
load("@bazel_tools//tools/python:toolchain.bzl", "py_runtime_pair")
# Non-hermetic toolchain 
py_runtime(
name = "python3_runtime",
interpreter_path = "/usr/bin/python3",
python_version = "PY3",
visibility = ["//visibility:public"],
)
py_runtime_pair(
name = "python3_runtime_pair",
py2_runtime = None,
py3_runtime = ":python3_runtime",
)
toolchain(
name = "python3_toolchain",
toolchain = ":python3_runtime_pair",
toolchain_type = "@bazel_tools//tools/python:toolchain_type",
)
# Hermetic toolchain
py_runtime(
name = "hermetic_python3_runtime",
files = ["@hermetic_interpreter//:files"],
interpreter = "@hermetic_interpreter//:python_bin",
python_version = "PY3",
visibility = ["//visibility:public"],
)
py_runtime_pair(
name = "hermetic_python3_runtime_pair",
py2_runtime = None,
py3_runtime = ":hermetic_python3_runtime",
)
toolchain(
name = "hermetic_python3_toolchain",
toolchain = ":hermetic_python3_runtime_pair",
toolchain_type = "@bazel_tools//tools/python:toolchain_type",
)

package(default_visibility = ["//visibility:public"])
# /src/some_tool/BUILD
load("@hermetic_python3_dependencies//:requirements.bzl", "requirement") # Can load this rule from either `hermetic_python3_dependencies` or `python3_dependencies`, but does not seem to make a difference 
py_binary(
name = "some-tool",
main = "some_tool.py",
srcs = ["some_tool_file.py"],
python_version = "PY3",
srcs_version = "PY3",
deps = [
requirement("requests"),
"//src/common/some-library:library",
]
)
package(default_visibility = ["//visibility:public"])

考虑升级rules_python,因为该规则集自https://github.com/bazelbuild/rules_python/releases/tag/0.7.0以来包含了一个密封的python工具链。

如果没有选项:

当前你在WORKSPACE.bazel文件中注册了两个工具链,bazel将使用它的工具链解析来选择其中一个。您可以使用--toolchain_resolution_debug=regex标志调试该分辨率,以查看发生了什么。

如果您想强制整个构建使用一个工具链,从WORKSPACE.bazel文件中删除注册的工具链,并创建一个.bazelrc:

build:hermetic_python --extra_toolchains=//src:hermetic_python3_toolchain
build:system_python --extra_toolchains=//src:python3_toolchain

现在您可以通过使用bazel build --config=hermetic_pythonbazel build --config=system_python在这些工具链之间切换。

请注意,这并不影响使用哪个python工具链来运行pip_parse()。您需要特别注意从何处加载requirement()函数。只需通过load()调用函数,就可以强制执行pip_parse()的求值,从而获取/编译相应的python解释器。

最新更新