From e14a64f7c881e52a7484c27b27eccbcfe0381c81 Mon Sep 17 00:00:00 2001 From: Richard Levasseur Date: Tue, 15 Jul 2025 21:21:44 -0700 Subject: [PATCH 1/4] fix: support debian multiarch with local toolchains --- python/private/get_local_runtime_info.py | 5 +++++ python/private/local_runtime_repo.bzl | 6 ++++++ 2 files changed, 11 insertions(+) diff --git a/python/private/get_local_runtime_info.py b/python/private/get_local_runtime_info.py index 19db3a2935..016ef44c9a 100644 --- a/python/private/get_local_runtime_info.py +++ b/python/private/get_local_runtime_info.py @@ -45,6 +45,11 @@ # The platform-specific filename suffix for library files. # Includes the dot, e.g. `.so` "SHLIB_SUFFIX", + # Debian has a "multiarch" layout that has libs for different archs + # in slightly other locations. The MULTIARCH sysconfig varible tells + # which directory under `LIBDIR` these exist in, if any. + # See https://wiki.debian.org/Python/MultiArch + "MULTIARCH", ] data.update(zip(config_vars, sysconfig.get_config_vars(*config_vars))) print(json.dumps(data)) diff --git a/python/private/local_runtime_repo.bzl b/python/private/local_runtime_repo.bzl index 3b4b4c020d..8ee4cd19ef 100644 --- a/python/private/local_runtime_repo.bzl +++ b/python/private/local_runtime_repo.bzl @@ -126,6 +126,7 @@ def _local_runtime_repo_impl(rctx): # In some cases, the same value is returned for multiple keys. Not clear why. shared_lib_names = {v: None for v in shared_lib_names}.keys() shared_lib_dir = info["LIBDIR"] + multiarch = info["MULTIARCH"] # The specific files are symlinked instead of the whole directory # because it can point to a directory that has more than just @@ -141,6 +142,11 @@ def _local_runtime_repo_impl(rctx): repo_utils.watch(rctx, origin) rctx.symlink(origin, "lib/" + name) + origin_multiarch = rctx.path("{}/{}/{}".format(shared_lib_dir, multiarch, name)) + if origin_multiarch.exists: + repo_utils.watch(rctx, origin) + rctx.symlink(origin, "lib/{}/{}".format(multiarch, name)) + rctx.file("WORKSPACE", "") rctx.file("MODULE.bazel", "") rctx.file("REPO.bazel", "") From ed49e9dd1f6df7d89a861f106f9791d80764a918 Mon Sep 17 00:00:00 2001 From: Richard Levasseur Date: Tue, 15 Jul 2025 22:23:32 -0700 Subject: [PATCH 2/4] make multiarch origin a fallback --- python/private/get_local_runtime_info.py | 13 ++++++++----- python/private/local_runtime_repo.bzl | 9 ++++----- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/python/private/get_local_runtime_info.py b/python/private/get_local_runtime_info.py index 016ef44c9a..c8371357c2 100644 --- a/python/private/get_local_runtime_info.py +++ b/python/private/get_local_runtime_info.py @@ -35,7 +35,15 @@ # of settings. # https://stackoverflow.com/questions/47423246/get-pythons-lib-path # For now, it seems LIBDIR has what is needed, so just use that. + # See also: MULTIARCH "LIBDIR", + # On Debian, with multiarch enabled, prior to Python 3.10, `LIBDIR` didn't + # tell the location of the libs, just the base directory. The `MULTIARCH` + # sysconfig variable tells the subdirectory within it with the libs. + # See: + # https://wiki.debian.org/Python/MultiArch + # https://git.launchpad.net/ubuntu/+source/python3.12/tree/debian/changelog#n842 + "MULTIARCH", # The versioned libpythonX.Y.so.N file. Usually? # It might be a static archive (.a) file instead. "INSTSONAME", @@ -45,11 +53,6 @@ # The platform-specific filename suffix for library files. # Includes the dot, e.g. `.so` "SHLIB_SUFFIX", - # Debian has a "multiarch" layout that has libs for different archs - # in slightly other locations. The MULTIARCH sysconfig varible tells - # which directory under `LIBDIR` these exist in, if any. - # See https://wiki.debian.org/Python/MultiArch - "MULTIARCH", ] data.update(zip(config_vars, sysconfig.get_config_vars(*config_vars))) print(json.dumps(data)) diff --git a/python/private/local_runtime_repo.bzl b/python/private/local_runtime_repo.bzl index 8ee4cd19ef..7a0864878f 100644 --- a/python/private/local_runtime_repo.bzl +++ b/python/private/local_runtime_repo.bzl @@ -136,17 +136,16 @@ def _local_runtime_repo_impl(rctx): for name in shared_lib_names: origin = rctx.path("{}/{}".format(shared_lib_dir, name)) + # If the origin doesn't exist, try the multiarch location + if not origin.exists and multiarch: + origin = rctx.path("{}/{}/{}".format(shared_lib_dir, multiarch, name)) + # The reported names don't always exist; it depends on the particulars # of the runtime installation. if origin.exists: repo_utils.watch(rctx, origin) rctx.symlink(origin, "lib/" + name) - origin_multiarch = rctx.path("{}/{}/{}".format(shared_lib_dir, multiarch, name)) - if origin_multiarch.exists: - repo_utils.watch(rctx, origin) - rctx.symlink(origin, "lib/{}/{}".format(multiarch, name)) - rctx.file("WORKSPACE", "") rctx.file("MODULE.bazel", "") rctx.file("REPO.bazel", "") From 38c64cc0848bc0661975b6483ad4fbefc770744d Mon Sep 17 00:00:00 2001 From: Richard Levasseur Date: Tue, 15 Jul 2025 22:25:03 -0700 Subject: [PATCH 3/4] better comment --- python/private/local_runtime_repo.bzl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/python/private/local_runtime_repo.bzl b/python/private/local_runtime_repo.bzl index 7a0864878f..b8b7164b54 100644 --- a/python/private/local_runtime_repo.bzl +++ b/python/private/local_runtime_repo.bzl @@ -136,7 +136,8 @@ def _local_runtime_repo_impl(rctx): for name in shared_lib_names: origin = rctx.path("{}/{}".format(shared_lib_dir, name)) - # If the origin doesn't exist, try the multiarch location + # If the origin doesn't exist, try the multiarch location, in case + # it's an older Python / Debian release. if not origin.exists and multiarch: origin = rctx.path("{}/{}/{}".format(shared_lib_dir, multiarch, name)) From 72472f72cb9fbbf70049cddad04744bf4d463a60 Mon Sep 17 00:00:00 2001 From: Richard Levasseur Date: Tue, 15 Jul 2025 22:27:04 -0700 Subject: [PATCH 4/4] changelog --- CHANGELOG.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7248e1f9f2..b36ceafa27 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -85,10 +85,12 @@ END_UNRELEASED_TEMPLATE ([#2503](https://github.com/bazel-contrib/rules_python/issues/2503)). * (toolchains) `local_runtime_repo` now checks if the include directory exists before attempting to watch it, fixing issues on macOS with system Python - ({gh-issue}`3043`). + ([#3043](https://github.com/bazel-contrib/rules_python/issues/3043)). * (pypi) The pipstar `defaults` configuration now supports any custom platform name. * Multi-line python imports (e.g. with escaped newlines) are now correctly processed by Gazelle. +* (toolchains) `local_runtime_repo` works with multiarch Debian with Python 3.8 + ([#3099](https://github.com/bazel-contrib/rules_python/issues/3099)). {#v0-0-0-added} ### Added