From 48d30c5ca047204db96e439fcc1978afc826e65f Mon Sep 17 00:00:00 2001 From: Nicholas Junge Date: Fri, 26 Jul 2024 07:56:09 +0200 Subject: [PATCH] fix: Fix up search path of bootstrapped Python toolchain dylib Previously, `//tests/cc/current_py_cc_libs::python_libs_linking_test` failed on macOS because the bootstrapped toolchain's dylib had an incorrect LC_ID_DYLIB field set, pointing to a local directory on the Python standalone build host machine. To fix, add a small conditional to the Python repository rule patching the LC_ID_DYLIB field of the bootstrapped Python's dylib with its fully qualified file system path. Patching is carried out with macOS's own `install_name_tool`, which is part of the standard macOS dynamic linking toolchain. Since this needs macOS to be the host platform, restrict this change to macOS host systems only by checking the host OS name. Qualifies the mentioned test as executable on Mac, now only Windows linker errors are left to fix. --- CHANGELOG.md | 4 ++++ python/private/python_repositories.bzl | 16 ++++++++++++++++ tests/cc/current_py_cc_libs/BUILD.bazel | 12 +++++++----- 3 files changed, 27 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ec0682a65e..41df8ad03d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -31,6 +31,10 @@ A brief description of the categories of changes: It would work well in cases to reduce merge conflicts. ### Fixed +* (rules) Fixes build targets linking against `@rules_python//python/cc:current_py_cc_libs` + in host platform builds on macOS, by editing the `LC_ID_DYLIB` field of the hermetic interpreter's + `libpython3.x.dylib` using `install_name_tool`, setting it to its absolute path under Bazel's + execroot. * (rules) Signals are properly received when using {obj}`--bootstrap_impl=script` (for non-zip builds). ([#2043](https://github.com/bazelbuild/rules_python/issues/2043)) diff --git a/python/private/python_repositories.bzl b/python/private/python_repositories.bzl index ea3dd3533f..25d8a96b79 100644 --- a/python/private/python_repositories.bzl +++ b/python/private/python_repositories.bzl @@ -191,6 +191,22 @@ def _python_repository_impl(rctx): elif rctx.attr.distutils_content: rctx.file(distutils_path, rctx.attr.distutils_content) + if "darwin" in platform and "osx" == repo_utils.get_platforms_os_name(rctx): + # Fix up the Python distribution's LC_ID_DYLIB field. + # It points to a build directory local to the GitHub Actions + # host machine used in the Python standalone build, which causes + # dyld lookup errors. To fix, set the full path to the dylib as + # it appears in the Bazel workspace as its LC_ID_DYLIB using + # the `install_name_tool` bundled with macOS. + dylib = "lib/libpython{}.dylib".format(python_short_version) + full_dylib_path = rctx.path(dylib) + repo_utils.execute_checked( + rctx, + op = "python_repository.FixUpDyldIdPath", + arguments = [repo_utils.which_checked(rctx, "install_name_tool"), "-id", full_dylib_path, dylib], + logger = logger, + ) + # Make the Python installation read-only. This is to prevent issues due to # pycs being generated at runtime: # * The pycs are not deterministic (they contain timestamps) diff --git a/tests/cc/current_py_cc_libs/BUILD.bazel b/tests/cc/current_py_cc_libs/BUILD.bazel index fb61435d37..218055532e 100644 --- a/tests/cc/current_py_cc_libs/BUILD.bazel +++ b/tests/cc/current_py_cc_libs/BUILD.bazel @@ -20,12 +20,14 @@ current_py_cc_libs_test_suite(name = "current_py_cc_libs_tests") cc_test( name = "python_libs_linking_test", srcs = ["python_libs_linking_test.cc"], - # Mac and Windows fail with linking errors, but its not clear why; someone - # with more C + Mac/Windows experience will have to figure it out. + # Windows fails with linking errors, but its not clear why; someone + # with more C + Windows experience will have to figure it out. # - rickeylev@ - target_compatible_with = [ - "@platforms//os:linux", - ], + target_compatible_with = select({ + "@platforms//os:linux": [], + "@platforms//os:osx": [], + "//conditions:default": ["@platforms//:incompatible"], + }), deps = [ "@rules_python//python/cc:current_py_cc_headers", "@rules_python//python/cc:current_py_cc_libs",