Как настроить Bazel так, чтобы он предпочитал одну цепочку инструментов другой? Я могу определить, какую цепочку инструментов использовать с помощью аргумента командной строки или указать, что следует использовать в конкретной цели.
В настоящее время в моем файле WORKSPACE определены две цепочки инструментов. У меня есть две цепочки инструментов Python. Один из них собирает Python из исходного кода и включает его в исполняемый файл .zip, а другой — нет.
При построении цепочка инструментов, которая используется, всегда является первой зарегистрированной цепочкой инструментов. В этом случае используется python3_tooolchain, хотя цель сборки импортирует requirement из hermetic_python3_toolchain.
# 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"])
Это можно сделать, зарегистрировав цепочку инструментов либо в файле WORKSPACE с помощью register_toolchains(), либо передав метки цепочек инструментов в командной строке с помощью флага --extra_toolchains.
Я уже регистрирую цепочки инструментов в WORKSPACE... некоторые сборки должны быть герметичными (эти сборки должны создавать интерпретатор Python из исходного кода и включать его в сборку), но другие сборки могут использовать системный интерпретатор. Как указать, какую цепочку инструментов использовать после того, как они оба зарегистрированы?
Подумайте об обновлении rules_python, так как этот набор правил включает в себя герметичную цепочку инструментов Python, начиная с https://github.com/bazelbuild/rules_python/releases/tag/0.7.0.
Если это не вариант:
В настоящее время вы регистрируете две цепочки инструментов в своем 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_python или bazel build --config=system_python.
Однако имейте в виду, что это не влияет на то, какая из цепочек инструментов Python использовалась для запуска pip_parse(). Вам нужно проявлять особую осторожность при загрузке функции requirement(). Просто выполняя функцию load(), вы вызываете оценку pip_parse() и, следовательно, выборку/компиляцию соответствующего интерпретатора Python.
Пожалуйста, отредактируйте вопрос, чтобы ограничить его конкретной проблемой с достаточной детализацией, чтобы найти адекватный ответ.