Skip to content

Commit 118573b

Browse files
authored
feat: allow py_cc_toolchain libs to be optional (bazel-contrib#2197)
This is for cases when shared libraries aren't available.
1 parent f4596fb commit 118573b

File tree

4 files changed

+40
-13
lines changed

4 files changed

+40
-13
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@ A brief description of the categories of changes:
2828
* (gazelle): Update error messages when unable to resolve a dependency to be more human-friendly.
2929
* (flags) The {obj}`--python_version` flag now also returns
3030
{obj}`config_common.FeatureFlagInfo`.
31+
* (toolchains) {obj}`py_cc_toolchain.libs` and {obj}`PyCcToolchainInfo.libs` is
32+
optional. This is to support situations where only the Python headers are
33+
available.
3134

3235
### Fixed
3336
* (whl_library): Remove `--no-index` and add `--no-build-isolation` to the

python/private/py_cc_toolchain_info.bzl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,9 @@ Information about the header files, struct with fields:
4141
represents).
4242
""",
4343
"libs": """\
44-
:type: struct
44+
:type: struct | None
4545
46-
Information about C libraries, struct with fields:
46+
If available, information about C libraries, struct with fields:
4747
* providers_map: A dict of string to provider instances. The key should be
4848
a fully qualified name (e.g. `@rules_foo//bar:baz.bzl#MyInfo`) of the
4949
provider to uniquely identify its type.

python/private/py_cc_toolchain_rule.bzl

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,19 +23,24 @@ load("@rules_cc//cc:defs.bzl", "CcInfo")
2323
load(":py_cc_toolchain_info.bzl", "PyCcToolchainInfo")
2424

2525
def _py_cc_toolchain_impl(ctx):
26+
if ctx.attr.libs:
27+
libs = struct(
28+
providers_map = {
29+
"CcInfo": ctx.attr.libs[CcInfo],
30+
"DefaultInfo": ctx.attr.libs[DefaultInfo],
31+
},
32+
)
33+
else:
34+
libs = None
35+
2636
py_cc_toolchain = PyCcToolchainInfo(
2737
headers = struct(
2838
providers_map = {
2939
"CcInfo": ctx.attr.headers[CcInfo],
3040
"DefaultInfo": ctx.attr.headers[DefaultInfo],
3141
},
3242
),
33-
libs = struct(
34-
providers_map = {
35-
"CcInfo": ctx.attr.libs[CcInfo],
36-
"DefaultInfo": ctx.attr.libs[DefaultInfo],
37-
},
38-
),
43+
libs = libs,
3944
python_version = ctx.attr.python_version,
4045
)
4146
extra_kwargs = {}
@@ -59,7 +64,6 @@ py_cc_toolchain = rule(
5964
doc = ("Target that provides the Python runtime libraries for linking. " +
6065
"Typically this is a cc_library target of `.so` files."),
6166
providers = [CcInfo],
62-
mandatory = True,
6367
),
6468
"python_version": attr.string(
6569
doc = "The Major.minor Python version, e.g. 3.11",

tests/cc/py_cc_toolchain/py_cc_toolchain_tests.bzl

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,16 @@
1616

1717
load("@rules_testing//lib:analysis_test.bzl", "analysis_test", "test_suite")
1818
load("@rules_testing//lib:truth.bzl", "matching", "subjects")
19+
load("//python/cc:py_cc_toolchain.bzl", "py_cc_toolchain")
1920
load("//tests/support:cc_info_subject.bzl", "cc_info_subject")
2021
load("//tests/support:py_cc_toolchain_info_subject.bzl", "PyCcToolchainInfoSubject")
2122

2223
_tests = []
2324

24-
def _py_cc_toolchain_test(name):
25+
def _test_py_cc_toolchain(name):
2526
analysis_test(
2627
name = name,
27-
impl = _py_cc_toolchain_test_impl,
28+
impl = _test_py_cc_toolchain_impl,
2829
target = "//tests/support/cc_toolchains:fake_py_cc_toolchain_impl",
2930
attrs = {
3031
"header": attr.label(
@@ -34,7 +35,7 @@ def _py_cc_toolchain_test(name):
3435
},
3536
)
3637

37-
def _py_cc_toolchain_test_impl(env, target):
38+
def _test_py_cc_toolchain_impl(env, target):
3839
env.expect.that_target(target).has_provider(platform_common.ToolchainInfo)
3940

4041
toolchain = PyCcToolchainInfoSubject.new(
@@ -80,7 +81,26 @@ def _py_cc_toolchain_test_impl(env, target):
8081
matching.str_matches("/libpython3."),
8182
)
8283

83-
_tests.append(_py_cc_toolchain_test)
84+
_tests.append(_test_py_cc_toolchain)
85+
86+
def _test_libs_optional(name):
87+
py_cc_toolchain(
88+
name = name + "_subject",
89+
libs = None,
90+
headers = "//tests/support/cc_toolchains:fake_headers",
91+
python_version = "4.5",
92+
)
93+
analysis_test(
94+
name = name,
95+
target = name + "_subject",
96+
impl = _test_libs_optional_impl,
97+
)
98+
99+
def _test_libs_optional_impl(env, target):
100+
libs = target[platform_common.ToolchainInfo].py_cc_toolchain.libs
101+
env.expect.that_bool(libs == None).equals(True)
102+
103+
_tests.append(_test_libs_optional)
84104

85105
def py_cc_toolchain_test_suite(name):
86106
test_suite(

0 commit comments

Comments
 (0)