diff --git a/news/current-py-cc-libs-shared-library.fixed.md b/news/current-py-cc-libs-shared-library.fixed.md new file mode 100644 index 0000000000..9cb1229dc4 --- /dev/null +++ b/news/current-py-cc-libs-shared-library.fixed.md @@ -0,0 +1,2 @@ +Include the Python toolchain's static libraries when `current_py_cc_libs` is used +as a dependency of `cc_shared_library`. diff --git a/python/private/current_py_cc_libs.bzl b/python/private/current_py_cc_libs.bzl index ca68346bcb..da4f8d58b3 100644 --- a/python/private/current_py_cc_libs.bzl +++ b/python/private/current_py_cc_libs.bzl @@ -15,15 +15,24 @@ """Implementation of current_py_cc_libs rule.""" load("@rules_cc//cc/common:cc_info.bzl", "CcInfo") +load("@rules_cc//cc/common:cc_shared_library_hint_info.bzl", "CcSharedLibraryHintInfo") def _current_py_cc_libs_impl(ctx): py_cc_toolchain = ctx.toolchains["//python/cc:toolchain_type"].py_cc_toolchain - return py_cc_toolchain.libs.providers_map.values() + providers = py_cc_toolchain.libs.providers_map + owners = { + linker_input.owner: None + for linker_input in providers["CcInfo"].linking_context.linker_inputs.to_list() + } + return providers.values() + [CcSharedLibraryHintInfo( + attributes = [], + owners = owners.keys() or [ctx.label], + )] current_py_cc_libs = rule( implementation = _current_py_cc_libs_impl, toolchains = ["//python/cc:toolchain_type"], - provides = [CcInfo], + provides = [CcInfo, CcSharedLibraryHintInfo], doc = """\ Provides the currently active Python toolchain's C libraries. @@ -39,5 +48,9 @@ cc_library( deps = ["@rules_python//python/cc:current_py_cc_libs"] ) ``` + +:::{versionchanged} VERSION_NEXT_PATCH +Static libraries are included when this target is a dependency of `cc_shared_library`. +::: """, ) diff --git a/tests/cc/current_py_cc_libs/current_py_cc_libs_tests.bzl b/tests/cc/current_py_cc_libs/current_py_cc_libs_tests.bzl index 26f97244d8..756f82ab44 100644 --- a/tests/cc/current_py_cc_libs/current_py_cc_libs_tests.bzl +++ b/tests/cc/current_py_cc_libs/current_py_cc_libs_tests.bzl @@ -14,9 +14,14 @@ """Tests for current_py_cc_libs.""" +load("@rules_cc//cc:cc_library.bzl", "cc_library") +load("@rules_cc//cc:cc_shared_library.bzl", "cc_shared_library") load("@rules_cc//cc/common:cc_info.bzl", "CcInfo") +load("@rules_cc//cc/common:cc_shared_library_info.bzl", "CcSharedLibraryInfo") load("@rules_testing//lib:analysis_test.bzl", "analysis_test", "test_suite") load("@rules_testing//lib:truth.bzl", "matching") +load("@rules_testing//lib:util.bzl", "util") +load("//python/cc:py_cc_toolchain.bzl", "py_cc_toolchain") load("//tests/support:cc_info_subject.bzl", "cc_info_subject") _tests = [] @@ -71,6 +76,51 @@ def _test_toolchain_is_registered_by_default_impl(env, target): _tests.append(_test_toolchain_is_registered_by_default) +def _test_shared_library(name): + util.helper_target( + cc_library, + name = name + ".libpython", + srcs = ["shared_library.c"], + ) + util.helper_target( + py_cc_toolchain, + name = name + ".py_cc_toolchain", + headers = "//tests/support/cc_toolchains:py_headers", + libs = ":" + name + ".libpython", + python_version = "3.999", + ) + util.helper_target( + native.toolchain, + name = name + ".toolchain", + toolchain = ":" + name + ".py_cc_toolchain", + toolchain_type = "//python/cc:toolchain_type", + ) + util.helper_target( + cc_shared_library, + name = name + ".shared", + deps = ["//python/cc:current_py_cc_libs"], + ) + analysis_test( + name = name, + impl = _test_shared_library_impl, + target = name + ".shared", + config_settings = { + # This transition replaces the C++ toolchain supplied by RBE. + "//command_line_option:extra_toolchains": [ + str(native.package_relative_label(":" + name + ".toolchain")), + str(Label("//tests/support/cc_toolchains:linux_toolchain_definition")), + str(Label("//tests/support/cc_toolchains:mac_toolchain_definition")), + str(Label("//tests/support/cc_toolchains:windows_toolchain_definition")), + ], + }, + ) + +def _test_shared_library_impl(env, target): + libpython = target.label.same_package_label(target.label.name.removesuffix(".shared") + ".libpython") + env.expect.that_collection(target[CcSharedLibraryInfo].link_once_static_libs).contains(str(libpython)) + +_tests.append(_test_shared_library) + def current_py_cc_libs_test_suite(name): test_suite( name = name, diff --git a/tests/cc/current_py_cc_libs/shared_library.c b/tests/cc/current_py_cc_libs/shared_library.c new file mode 100644 index 0000000000..cea2d11795 --- /dev/null +++ b/tests/cc/current_py_cc_libs/shared_library.c @@ -0,0 +1 @@ +int python_library_symbol(void) { return 0; }