use crate_info.owner for linker inputs, if available (#4177)
Fixes an inconsistency where we use crate_info.owner as the owner of
Rust actions, while we used ctx.label as the owner of the corresponding
C++ linker inputs. Most of the time, these are the same, but we've got a
use case in rust proto integration where we wanna be able to customize
the owner of the C++ infos (so that these can be distinguished from the
C++ infos of the standard c++ proto bindings).
diff --git a/rust/private/common.bzl b/rust/private/common.bzl
index 64da3d9..095dad3 100644
--- a/rust/private/common.bzl
+++ b/rust/private/common.bzl
@@ -65,6 +65,8 @@
kwargs.update({"data": depset([])})
if not "root_path" in kwargs:
kwargs.update({"root_path": ""})
+ if not "owner" in kwargs:
+ kwargs.update({"owner": None})
return CrateInfo(**kwargs)
rust_common = struct(
diff --git a/rust/private/rustc.bzl b/rust/private/rustc.bzl
index 2fb2f46..43d139e 100644
--- a/rust/private/rustc.bzl
+++ b/rust/private/rustc.bzl
@@ -2446,7 +2446,7 @@
fail("Unexpected case")
link_input = cc_common.create_linker_input(
- owner = ctx.label,
+ owner = crate_info.owner or ctx.label,
libraries = depset([library_to_link]) if library_to_link else depset(),
)
diff --git a/rust/private/rustdoc.bzl b/rust/private/rustdoc.bzl
index cc0a23e..2114d37 100644
--- a/rust/private/rustdoc.bzl
+++ b/rust/private/rustdoc.bzl
@@ -66,6 +66,7 @@
compile_data = crate_info.compile_data,
compile_data_targets = crate_info.compile_data_targets,
data = crate_info.data,
+ owner = crate_info.owner,
)
def rustdoc_compile_action(
diff --git a/test/unit/cc_info/cc_info_test.bzl b/test/unit/cc_info/cc_info_test.bzl
index f90c78b..3530a48 100644
--- a/test/unit/cc_info/cc_info_test.bzl
+++ b/test/unit/cc_info/cc_info_test.bzl
@@ -8,6 +8,7 @@
load("@rules_cc//cc:defs.bzl", "cc_import", "cc_library")
load("@rules_cc//cc/common:cc_info.bzl", "CcInfo")
load("//rust:defs.bzl", "rust_binary", "rust_common", "rust_library", "rust_proc_macro", "rust_shared_library", "rust_static_library")
+load("//rust/private:rustc.bzl", "establish_cc_info") # buildifier: disable=bzl-visibility
def _is_windows(ctx):
return ctx.target_platform_has_constraint(ctx.attr._windows[platform_common.ConstraintValueInfo])
@@ -362,6 +363,121 @@
target_under_test = ":rust_dylib_with_interface_lib_dep",
)
+ mock_rust_library_with_custom_owner(
+ name = "custom_owner_target",
+ owner = ":rlib",
+ )
+
+ linker_input_owner_test(
+ name = "linker_input_owner_test",
+ target_under_test = ":custom_owner_target",
+ expected_owner = ":rlib",
+ )
+
+ mock_rust_library_with_custom_owner(
+ name = "none_owner_target",
+ set_owner_to_none = True,
+ )
+
+ linker_input_owner_test(
+ name = "none_owner_test",
+ target_under_test = ":none_owner_target",
+ )
+
+ mock_rust_library_with_custom_owner(
+ name = "absent_owner_target",
+ )
+
+ linker_input_owner_test(
+ name = "absent_owner_test",
+ target_under_test = ":absent_owner_target",
+ )
+
+def _mock_rust_library_with_custom_owner_impl(ctx):
+ output = ctx.actions.declare_file(ctx.label.name + ".rlib")
+ ctx.actions.write(output, "")
+
+ owner = ctx.attr.owner
+
+ crate_info_kwargs = dict(
+ name = "mock_crate",
+ type = "rlib",
+ root = output,
+ srcs = depset([output]),
+ deps = depset(),
+ proc_macro_deps = depset(),
+ aliases = {},
+ output = output,
+ edition = "2021",
+ is_test = False,
+ )
+ if ctx.attr.set_owner_to_none:
+ crate_info_kwargs["owner"] = None
+ elif owner:
+ crate_info_kwargs["owner"] = owner.label
+
+ crate_info = rust_common.create_crate_info(
+ **crate_info_kwargs
+ )
+
+ mock_toolchain = struct(
+ stdlib_linkflags = CcInfo(),
+ libstd_and_allocator_ccinfo = CcInfo(),
+ _experimental_use_global_allocator = False,
+ _experimental_use_allocator_libraries_with_mangled_symbols = 0,
+ _no_std = "off",
+ _link_std_dylib = False,
+ )
+
+ providers = establish_cc_info(
+ ctx = ctx,
+ attr = ctx.attr,
+ crate_info = crate_info,
+ toolchain = mock_toolchain,
+ cc_toolchain = None,
+ feature_configuration = None,
+ interface_library = None,
+ use_pic = False,
+ )
+
+ return providers
+
+mock_rust_library_with_custom_owner = rule(
+ implementation = _mock_rust_library_with_custom_owner_impl,
+ attrs = {
+ "owner": attr.label(mandatory = False),
+ "set_owner_to_none": attr.bool(default = False),
+ },
+)
+
+def _linker_input_owner_test_impl(ctx):
+ env = analysistest.begin(ctx)
+ tut = analysistest.target_under_test(env)
+
+ asserts.true(env, CcInfo in tut, "Target should provide CcInfo")
+ cc_info = tut[CcInfo]
+ linker_inputs = cc_info.linking_context.linker_inputs.to_list()
+ asserts.equals(env, 1, len(linker_inputs))
+
+ linker_input = linker_inputs[0]
+
+ expected_owner = ctx.attr.expected_owner
+ if expected_owner:
+ expected_owner_label = expected_owner.label
+ else:
+ expected_owner_label = tut.label
+
+ asserts.equals(env, expected_owner_label, linker_input.owner)
+
+ return analysistest.end(env)
+
+linker_input_owner_test = analysistest.make(
+ _linker_input_owner_test_impl,
+ attrs = {
+ "expected_owner": attr.label(mandatory = False),
+ },
+)
+
def cc_info_test_suite(name):
"""Entry-point macro called from the BUILD file.
@@ -383,5 +499,8 @@
":is_cc_interface_library_test",
":rust_lib_with_interface_lib_dep_test",
":rust_dylib_with_interface_lib_dep_test",
+ ":linker_input_owner_test",
+ ":none_owner_test",
+ ":absent_owner_test",
],
)