blob: 23fa99dfa956013e9a894b67e3d7735c61c390c5 [file] [log] [blame]
# Copyright 2024 The Bazel Authors. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Setup code called by the code generated by `local_runtime_repo`."""
load("@bazel_skylib//lib:selects.bzl", "selects")
load("@rules_cc//cc:defs.bzl", "cc_library")
load("@rules_python//python:py_runtime.bzl", "py_runtime")
load("@rules_python//python:py_runtime_pair.bzl", "py_runtime_pair")
load("@rules_python//python/cc:py_cc_toolchain.bzl", "py_cc_toolchain")
load("@rules_python//python/private:py_exec_tools_toolchain.bzl", "py_exec_tools_toolchain")
_PYTHON_VERSION_FLAG = Label("@rules_python//python/config_settings:python_version")
def define_local_runtime_toolchain_impl(
name,
lib_ext,
major,
minor,
micro,
interpreter_path,
implementation_name,
os):
"""Defines a toolchain implementation for a local Python runtime.
Generates public targets:
* `python_runtimes`: The target toolchain type implementation
* `py_exec_tools_toolchain`: The exec tools toolchain type implementation
* `py_cc_toolchain`: The py cc toolchain type implementation
* `os`: A constraint (or alias to one) for the `target_compatible_with` this
toolchain is compatible with.
* `is_matching_python_version`: A `config_setting` for `target_settings`
this toolchain is compatible with.
Args:
name: `str` Only present to satisfy tooling
lib_ext: `str` The file extension for the `libpython` shared libraries
major: `str` The major Python version, e.g. `3` of `3.9.1`.
minor: `str` The minor Python version, e.g. `9` of `3.9.1`.
micro: `str` The micro Python version, e.g. "1" of `3.9.1`.
interpreter_path: `str` Absolute path to the interpreter.
implementation_name: `str` The implementation name, as returned by
`sys.implementation.name`.
os: `str` A label to the OS constraint (e.g. `@platforms//os:linux`) for
this runtime.
"""
major_minor = "{}.{}".format(major, minor)
major_minor_micro = "{}.{}".format(major_minor, micro)
cc_library(
name = "_python_headers",
# NOTE: Keep in sync with watch_tree() called in local_runtime_repo
srcs = native.glob(["include/**/*.h"]),
includes = ["include"],
)
cc_library(
name = "_libpython",
# Don't use a recursive glob because the lib/ directory usually contains
# a subdirectory of the stdlib -- lots of unrelated files
srcs = native.glob([
"lib/*{}".format(lib_ext), # Match libpython*.so
"lib/*{}*".format(lib_ext), # Also match libpython*.so.1.0
]),
hdrs = [":_python_headers"],
)
py_runtime(
name = "_py3_runtime",
interpreter_path = interpreter_path,
python_version = "PY3",
interpreter_version_info = {
"major": major,
"micro": micro,
"minor": minor,
},
implementation_name = implementation_name,
)
py_runtime_pair(
name = "python_runtimes",
py2_runtime = None,
py3_runtime = ":_py3_runtime",
visibility = ["//visibility:public"],
)
py_exec_tools_toolchain(
name = "py_exec_tools_toolchain",
visibility = ["//visibility:public"],
precompiler = "@rules_python//tools/precompiler:precompiler",
)
py_cc_toolchain(
name = "py_cc_toolchain",
headers = ":_python_headers",
libs = ":_libpython",
python_version = major_minor_micro,
visibility = ["//visibility:public"],
)
native.alias(
name = "os",
# Call Label() to force the string to evaluate in the context of
# rules_python, not the calling BUILD-file code. This is because
# the value is an `@platforms//foo` string, which @rules_python has
# visibility to, but the calling repo may not.
actual = Label(os),
visibility = ["//visibility:public"],
)
native.config_setting(
name = "_is_major_minor",
flag_values = {
_PYTHON_VERSION_FLAG: major_minor,
},
)
native.config_setting(
name = "_is_major_minor_micro",
flag_values = {
_PYTHON_VERSION_FLAG: major_minor_micro,
},
)
selects.config_setting_group(
name = "is_matching_python_version",
match_any = [
":_is_major_minor",
":_is_major_minor_micro",
],
visibility = ["//visibility:public"],
)