| # 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"], |
| ) |