Skip to content

Commit 64a4b52

Browse files
krasimirggscentini
andauthored
rust_stdlib_filegroup: update to support srcs from another package (#2735)
The `rust_stdlib_filegroup` rule would sometimes break when passing `.rlib`-s originating from another package to `srcs`. The root cause is the logic inside it that creates `.a` -> `.rlib` symlinks, where the `.a` symlink is declared sibling of the `.rlib`. Bazel only allows symlink siblings to be in the same package as the rule. This updates the logic to detect this and create an intermediary `.rlib` under the rule's package, allowing the `.a` to be symlinked to that. --------- Co-authored-by: scentini <[email protected]>
1 parent 4a530aa commit 64a4b52

File tree

5 files changed

+55
-3
lines changed

5 files changed

+55
-3
lines changed

rust/private/rustc.bzl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1616,7 +1616,7 @@ def establish_cc_info(ctx, attr, crate_info, toolchain, cc_toolchain, feature_co
16161616
# bazel hard-codes a check for endswith((".a", ".pic.a",
16171617
# ".lib")) in create_library_to_link, so we work around that
16181618
# by creating a symlink to the .rlib with a .a extension.
1619-
dot_a = make_static_lib_symlink(ctx.actions, crate_info.output)
1619+
dot_a = make_static_lib_symlink(ctx.label.package, ctx.actions, crate_info.output)
16201620

16211621
# TODO(hlopko): handle PIC/NOPIC correctly
16221622
library_to_link = cc_common.create_library_to_link(

rust/private/utils.bzl

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -420,7 +420,7 @@ def dedent(doc_string):
420420
block = " " * space_count
421421
return "\n".join([line.replace(block, "", 1).rstrip() for line in lines])
422422

423-
def make_static_lib_symlink(actions, rlib_file):
423+
def make_static_lib_symlink(ctx_package, actions, rlib_file):
424424
"""Add a .a symlink to an .rlib file.
425425
426426
The name of the symlink is derived from the <name> of the <name>.rlib file as follows:
@@ -432,17 +432,31 @@ def make_static_lib_symlink(actions, rlib_file):
432432
* `crateb.rlib` is `libcrateb.a`.
433433
434434
Args:
435+
ctx_package (string): The rule's context package name.
435436
actions (actions): The rule's context actions object.
436437
rlib_file (File): The file to symlink, which must end in .rlib.
437438
438439
Returns:
439440
The symlink's File.
440441
"""
442+
441443
if not rlib_file.basename.endswith(".rlib"):
442444
fail("file is not an .rlib: ", rlib_file.basename)
443445
basename = rlib_file.basename[:-5]
444446
if not basename.startswith("lib"):
445447
basename = "lib" + basename
448+
449+
# The .a symlink below is created as a sibling to the .rlib file.
450+
# Bazel doesn't allow creating a symlink outside of the rule's package,
451+
# so if the .rlib file comes from a different package, first symlink it
452+
# to the rule's package. The name of the new .rlib symlink is derived
453+
# as the name of the original .rlib relative to its package.
454+
if rlib_file.owner.package != ctx_package:
455+
new_path = rlib_file.short_path.removeprefix(rlib_file.owner.package).removeprefix("/")
456+
new_rlib_file = actions.declare_file(new_path)
457+
actions.symlink(output = new_rlib_file, target_file = rlib_file)
458+
rlib_file = new_rlib_file
459+
446460
dot_a = actions.declare_file(basename + ".a", sibling = rlib_file)
447461
actions.symlink(output = dot_a, target_file = rlib_file)
448462
return dot_a

rust/toolchain.bzl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ def _rust_stdlib_filegroup_impl(ctx):
5454
#
5555
# alloc depends on the allocator_library if it's configured, but we
5656
# do that later.
57-
dot_a_files = [make_static_lib_symlink(ctx.actions, f) for f in std_rlibs]
57+
dot_a_files = [make_static_lib_symlink(ctx.label.package, ctx.actions, f) for f in std_rlibs]
5858

5959
alloc_files = [f for f in dot_a_files if "alloc" in f.basename and "std" not in f.basename]
6060
between_alloc_and_core_files = [f for f in dot_a_files if "compiler_builtins" in f.basename]
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
genrule(
2+
name = "dummy_rlib",
3+
outs = ["core.rlib"],
4+
cmd = "touch $@",
5+
)
6+
7+
filegroup(
8+
name = "std_libs_srcs",
9+
srcs = [":dummy_rlib"],
10+
visibility = ["//test/unit/toolchain:__subpackages__"],
11+
)

test/unit/toolchain/toolchain_test.bzl

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,26 @@ def _toolchain_location_expands_linkflags_impl(ctx):
4747

4848
return analysistest.end(env)
4949

50+
def _std_libs_support_srcs_outside_package_test_impl(ctx):
51+
env = analysistest.begin(ctx)
52+
tut = analysistest.target_under_test(env)
53+
actions = analysistest.target_actions(env)
54+
55+
symlinks = [a for a in actions if a.mnemonic == "Symlink"]
56+
asserts.equals(env, 2, len(symlinks))
57+
58+
rlib_symlink = symlinks[0].outputs.to_list()[0]
59+
asserts.equals(env, tut.label.package + "/core.rlib", rlib_symlink.short_path)
60+
61+
a_symlink = symlinks[1].outputs.to_list()[0]
62+
asserts.equals(env, tut.label.package + "/libcore.a", a_symlink.short_path)
63+
64+
return analysistest.end(env)
65+
5066
toolchain_specifies_target_triple_test = analysistest.make(_toolchain_specifies_target_triple_test_impl)
5167
toolchain_specifies_target_json_test = analysistest.make(_toolchain_specifies_target_json_test_impl)
5268
toolchain_location_expands_linkflags_test = analysistest.make(_toolchain_location_expands_linkflags_impl)
69+
std_libs_support_srcs_outside_package_test = analysistest.make(_std_libs_support_srcs_outside_package_test_impl)
5370

5471
def _define_test_targets():
5572
native.filegroup(
@@ -61,6 +78,11 @@ def _define_test_targets():
6178
srcs = [":stdlib_srcs"],
6279
)
6380

81+
rust_stdlib_filegroup(
82+
name = "std_libs_with_srcs_outside_package",
83+
srcs = ["//test/unit/toolchain/subpackage:std_libs_srcs"],
84+
)
85+
6486
native.filegroup(
6587
name = "target_json",
6688
srcs = ["toolchain-test-triple.json"],
@@ -166,6 +188,10 @@ def toolchain_test_suite(name):
166188
name = "toolchain_location_expands_linkflags_test",
167189
target_under_test = ":rust_location_expand_toolchain",
168190
)
191+
std_libs_support_srcs_outside_package_test(
192+
name = "std_libs_support_srcs_outside_package_test",
193+
target_under_test = ":std_libs_with_srcs_outside_package",
194+
)
169195

170196
native.test_suite(
171197
name = name,
@@ -174,5 +200,6 @@ def toolchain_test_suite(name):
174200
":toolchain_specifies_target_json_test",
175201
":toolchain_specifies_inline_target_json_test",
176202
":toolchain_location_expands_linkflags_test",
203+
":std_libs_support_srcs_outside_package_test",
177204
],
178205
)

0 commit comments

Comments
 (0)