Skip to content

Commit 9cc620e

Browse files
authored
fix(cc): include toolchain libraries in cc_shared_library (#4166)
`current_py_cc_libs` forwards linker inputs with the Python toolchain library's owner labels. `cc_shared_library` does not discover those labels through the toolchain, so it silently omits the static libraries. Return `CcSharedLibraryHintInfo` with the forwarded owner labels. Validation: added a `rules_testing` regression with a static library supplied through `py_cc_toolchain`. It fails before the fix; all three `current_py_cc_libs` analysis tests pass afterward on Bazel 9.1.1.
1 parent ff35ee4 commit 9cc620e

4 files changed

Lines changed: 68 additions & 2 deletions

File tree

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Include the Python toolchain's static libraries when `current_py_cc_libs` is used
2+
as a dependency of `cc_shared_library`.

‎python/private/current_py_cc_libs.bzl‎

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,24 @@
1515
"""Implementation of current_py_cc_libs rule."""
1616

1717
load("@rules_cc//cc/common:cc_info.bzl", "CcInfo")
18+
load("@rules_cc//cc/common:cc_shared_library_hint_info.bzl", "CcSharedLibraryHintInfo")
1819

1920
def _current_py_cc_libs_impl(ctx):
2021
py_cc_toolchain = ctx.toolchains["//python/cc:toolchain_type"].py_cc_toolchain
21-
return py_cc_toolchain.libs.providers_map.values()
22+
providers = py_cc_toolchain.libs.providers_map
23+
owners = {
24+
linker_input.owner: None
25+
for linker_input in providers["CcInfo"].linking_context.linker_inputs.to_list()
26+
}
27+
return providers.values() + [CcSharedLibraryHintInfo(
28+
attributes = [],
29+
owners = owners.keys() or [ctx.label],
30+
)]
2231

2332
current_py_cc_libs = rule(
2433
implementation = _current_py_cc_libs_impl,
2534
toolchains = ["//python/cc:toolchain_type"],
26-
provides = [CcInfo],
35+
provides = [CcInfo, CcSharedLibraryHintInfo],
2736
doc = """\
2837
Provides the currently active Python toolchain's C libraries.
2938
@@ -39,5 +48,9 @@ cc_library(
3948
deps = ["@rules_python//python/cc:current_py_cc_libs"]
4049
)
4150
```
51+
52+
:::{versionchanged} VERSION_NEXT_PATCH
53+
Static libraries are included when this target is a dependency of `cc_shared_library`.
54+
:::
4255
""",
4356
)

‎tests/cc/current_py_cc_libs/current_py_cc_libs_tests.bzl‎

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,14 @@
1414

1515
"""Tests for current_py_cc_libs."""
1616

17+
load("@rules_cc//cc:cc_library.bzl", "cc_library")
18+
load("@rules_cc//cc:cc_shared_library.bzl", "cc_shared_library")
1719
load("@rules_cc//cc/common:cc_info.bzl", "CcInfo")
20+
load("@rules_cc//cc/common:cc_shared_library_info.bzl", "CcSharedLibraryInfo")
1821
load("@rules_testing//lib:analysis_test.bzl", "analysis_test", "test_suite")
1922
load("@rules_testing//lib:truth.bzl", "matching")
23+
load("@rules_testing//lib:util.bzl", "util")
24+
load("//python/cc:py_cc_toolchain.bzl", "py_cc_toolchain")
2025
load("//tests/support:cc_info_subject.bzl", "cc_info_subject")
2126

2227
_tests = []
@@ -71,6 +76,51 @@ def _test_toolchain_is_registered_by_default_impl(env, target):
7176

7277
_tests.append(_test_toolchain_is_registered_by_default)
7378

79+
def _test_shared_library(name):
80+
util.helper_target(
81+
cc_library,
82+
name = name + ".libpython",
83+
srcs = ["shared_library.c"],
84+
)
85+
util.helper_target(
86+
py_cc_toolchain,
87+
name = name + ".py_cc_toolchain",
88+
headers = "//tests/support/cc_toolchains:py_headers",
89+
libs = ":" + name + ".libpython",
90+
python_version = "3.999",
91+
)
92+
util.helper_target(
93+
native.toolchain,
94+
name = name + ".toolchain",
95+
toolchain = ":" + name + ".py_cc_toolchain",
96+
toolchain_type = "//python/cc:toolchain_type",
97+
)
98+
util.helper_target(
99+
cc_shared_library,
100+
name = name + ".shared",
101+
deps = ["//python/cc:current_py_cc_libs"],
102+
)
103+
analysis_test(
104+
name = name,
105+
impl = _test_shared_library_impl,
106+
target = name + ".shared",
107+
config_settings = {
108+
# This transition replaces the C++ toolchain supplied by RBE.
109+
"//command_line_option:extra_toolchains": [
110+
str(native.package_relative_label(":" + name + ".toolchain")),
111+
str(Label("//tests/support/cc_toolchains:linux_toolchain_definition")),
112+
str(Label("//tests/support/cc_toolchains:mac_toolchain_definition")),
113+
str(Label("//tests/support/cc_toolchains:windows_toolchain_definition")),
114+
],
115+
},
116+
)
117+
118+
def _test_shared_library_impl(env, target):
119+
libpython = target.label.same_package_label(target.label.name.removesuffix(".shared") + ".libpython")
120+
env.expect.that_collection(target[CcSharedLibraryInfo].link_once_static_libs).contains(str(libpython))
121+
122+
_tests.append(_test_shared_library)
123+
74124
def current_py_cc_libs_test_suite(name):
75125
test_suite(
76126
name = name,
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
int python_library_symbol(void) { return 0; }

0 commit comments

Comments
 (0)