From 0f66bf35678f45f39d92058b3c0408d9e3e1e698 Mon Sep 17 00:00:00 2001 From: Fabrice Date: Mon, 31 Aug 2026 16:45:56 +0200 Subject: [PATCH] Support `cc_lib` targets that only provide a dynamic library and prevent re-anchoring when siblings are generated (#4234, #4233) --- extensions/bindgen/private/bindgen.bzl | 6 ++- .../bindgen/test/analysis/bindgen_test.bzl | 43 ++++++++++++++++++- rust/private/rust_analyzer.bzl | 12 +++++- 3 files changed, 57 insertions(+), 4 deletions(-) diff --git a/extensions/bindgen/private/bindgen.bzl b/extensions/bindgen/private/bindgen.bzl index b5f9ec1cac..74807589d5 100644 --- a/extensions/bindgen/private/bindgen.bzl +++ b/extensions/bindgen/private/bindgen.bzl @@ -179,9 +179,13 @@ def _generate_cc_link_build_info(ctx, cc_lib): rustc_flags.append("-lstatic={}".format(get_lib_name_default(lib.pic_static_library))) linker_search_paths.append(lib.pic_static_library.dirname) compile_data.append(lib.pic_static_library) + elif lib.dynamic_library: + rustc_flags.append("-ldylib={}".format(get_lib_name_default(lib.dynamic_library))) + linker_search_paths.append(lib.dynamic_library.dirname) + compile_data.append(lib.dynamic_library) if not compile_data: - fail("No static libraries found in {}".format( + fail("No static or dynamic libraries found in {}".format( cc_lib.label, )) diff --git a/extensions/bindgen/test/analysis/bindgen_test.bzl b/extensions/bindgen/test/analysis/bindgen_test.bzl index 7cb0e729ca..92c74ed936 100644 --- a/extensions/bindgen/test/analysis/bindgen_test.bzl +++ b/extensions/bindgen/test/analysis/bindgen_test.bzl @@ -1,6 +1,7 @@ """Analysis test for for rust_bindgen_library rule.""" -load("@rules_cc//cc:defs.bzl", "cc_library") +load("@rules_cc//cc:cc_shared_library.bzl", "cc_shared_library") +load("@rules_cc//cc:defs.bzl", "cc_import", "cc_library") load("@rules_rust//rust:defs.bzl", "rust_binary") load("@rules_rust_bindgen//:defs.bzl", "rust_bindgen_library") load("@rules_testing//lib:analysis_test.bzl", "analysis_test", "test_suite") @@ -100,6 +101,45 @@ def _test_cc_lib_object_merging_disabled(name): impl = _test_cc_lib_object_merging_disabled_impl, ) +def _test_cc_lib_dynamic_only_impl(env, target): + env.expect.that_int(len(target.actions)).is_greater_than(2) + env.expect.that_action(target.actions[0]).mnemonic().contains("RustBindgen") + env.expect.that_action(target.actions[1]).mnemonic().contains("FileWrite") + env.expect.that_action(target.actions[1]).content().contains("-ldylib=test_cc_lib_dynamic_only_cc_shared") + +def _test_cc_lib_dynamic_only(name): + cc_library( + name = name + "_cc_objects", + srcs = ["simple.cc"], + hdrs = ["simple.h"], + tags = ["manual"], + ) + cc_shared_library( + name = name + "_cc_shared", + deps = [name + "_cc_objects"], + tags = ["manual"], + ) + cc_import( + name = name + "_cc", + shared_library = name + "_cc_shared", + hdrs = ["simple.h"], + tags = ["manual"], + ) + + rust_bindgen_library( + name = name + "_rust_bindgen", + cc_lib = name + "_cc", + header = "simple.h", + tags = ["manual"], + edition = "2021", + ) + + analysis_test( + name = name, + target = name + "_rust_bindgen__bindgen", + impl = _test_cc_lib_dynamic_only_impl, + ) + def bindgen_test_suite(name): test_suite( name = name, @@ -107,5 +147,6 @@ def bindgen_test_suite(name): _test_cc_linkopt, _test_cc_lib_object_merging, _test_cc_lib_object_merging_disabled, + _test_cc_lib_dynamic_only, ], ) diff --git a/rust/private/rust_analyzer.bzl b/rust/private/rust_analyzer.bzl index 7fa8686caf..76519f5d05 100644 --- a/rust/private/rust_analyzer.bzl +++ b/rust/private/rust_analyzer.bzl @@ -266,7 +266,7 @@ def _create_single_crate(ctx, attrs, info): # We're only interested in the build info for local crates as these are the # only ones for which we want build file watching and code lens runnables support. - if not is_external and not is_generated: + if not is_external: crate["build"] = { "build_file": _WORKSPACE_TEMPLATE + ctx.build_file_path, # Emit canonical `//pkg:name` form. Bazel's BEP reports action @@ -280,8 +280,16 @@ def _create_single_crate(ctx, attrs, info): if is_generated: srcs = getattr(ctx.rule.files, "srcs", []) src_map = {src.short_path: src for src in srcs if src.is_source} + + # Only re-anchor into the workspace when every sibling src lives there too. + has_generated_srcs = any([ + not src.is_source + for src in srcs + if src.short_path != info.crate.root.short_path + ]) if info.crate.root.short_path in src_map: - crate["root_module"] = _WORKSPACE_TEMPLATE + src_map[info.crate.root.short_path].path + if not has_generated_srcs: + crate["root_module"] = _WORKSPACE_TEMPLATE + src_map[info.crate.root.short_path].path crate["source"]["include_dirs"].extend([ _WORKSPACE_TEMPLATE + src_map[info.crate.root.short_path].dirname, path_prefix + info.crate.root.dirname,