Skip to content

Commit 6281d27

Browse files
avrabeUebelAndre
andauthored
Add missing rustc binaries to rustc_lib filegroup (bazelbuild#3727)
## Summary Add `rust-objcopy` and `wasm-component-ld` to the `rustc_lib` filegroup in `repository_utils.bzl`. These binaries are present in recent rustc distributions (wasm-component-ld since 1.82.0, rust-objcopy since 1.84.0) but were not previously declared. ### Changes - **Binary Declaration**: Add `rust-objcopy{binary_ext}` and `wasm-component-ld{binary_ext}` to the rustc_lib filegroup glob patterns ### Context On Windows, Bazel copies files into the sandbox rather than symlinking, so only explicitly listed files are available. This caused wasm32-wasip2 builds to fail with `linker 'wasm-component-ld.exe' not found`. On Linux/macOS, the issue was masked by symlink-based sandboxing which allowed rustc to access unlisted files in the same directory. --------- Co-authored-by: UebelAndre <github@uebelandre.com>
1 parent 791842f commit 6281d27

3 files changed

Lines changed: 64 additions & 8 deletions

File tree

rust/private/repository_utils.bzl

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -90,12 +90,24 @@ filegroup(
9090
)
9191
"""
9292

93-
def BUILD_for_compiler(target_triple, include_linker = False):
93+
_build_file_for_objcopy_template = """\
94+
filegroup(
95+
name = "rust-objcopy",
96+
srcs = glob(
97+
["lib/rustlib/{target_triple}/bin/rust-objcopy{binary_ext}"],
98+
allow_empty = True,
99+
),
100+
visibility = ["//visibility:public"],
101+
)
102+
"""
103+
104+
def BUILD_for_compiler(target_triple, include_linker = False, include_objcopy = False):
94105
"""Emits a BUILD file the compiler archive.
95106
96107
Args:
97108
target_triple (str): The triple of the target platform
98109
include_linker (bool): Whether to generate targets for linkers.
110+
include_objcopy (bool): Whether to generate targets for rust-objcopy.
99111
100112
Returns:
101113
str: The contents of a BUILD file
@@ -117,6 +129,14 @@ def BUILD_for_compiler(target_triple, include_linker = False):
117129
),
118130
)
119131

132+
if include_objcopy:
133+
content.append(
134+
_build_file_for_objcopy_template.format(
135+
binary_ext = system_to_binary_ext(target_triple.system),
136+
target_triple = target_triple.str,
137+
),
138+
)
139+
120140
return "\n".join(content)
121141

122142
_build_file_for_cargo_template = """\
@@ -325,6 +345,7 @@ rust_toolchain(
325345
rustc = "//:rustc",
326346
linker = {linker_label},
327347
linker_type = {linker_type},
348+
rust_objcopy = {rust_objcopy_label},
328349
rustfmt = {rustfmt_label},
329350
cargo = "//:cargo",
330351
clippy_driver = "//:clippy_driver_bin",
@@ -362,6 +383,7 @@ def BUILD_for_rust_toolchain(
362383
include_rustfmt,
363384
include_llvm_tools,
364385
include_linker,
386+
include_objcopy = False,
365387
stdlib_linkflags = None,
366388
extra_rustc_flags = None,
367389
extra_exec_rustc_flags = None,
@@ -382,6 +404,7 @@ def BUILD_for_rust_toolchain(
382404
include_rustfmt (bool): Whether rustfmt is present in the toolchain.
383405
include_llvm_tools (bool): Whether llvm-tools are present in the toolchain.
384406
include_linker (bool): Whether a linker is available in the toolchain.
407+
include_objcopy (bool): Whether rust-objcopy is available in the toolchain.
385408
stdlib_linkflags (list, optional): Overridden flags needed for linking to rust
386409
stdlib, akin to BAZEL_LINKLIBS. Defaults to
387410
None.
@@ -419,6 +442,10 @@ def BUILD_for_rust_toolchain(
419442
linker_label = "//:rust-lld"
420443
linker_type = "direct"
421444

445+
rust_objcopy_label = None
446+
if include_objcopy:
447+
rust_objcopy_label = "//:rust-objcopy"
448+
422449
return _build_file_for_rust_toolchain_template.format(
423450
toolchain_name = name,
424451
binary_ext = system_to_binary_ext(target_triple.system),
@@ -436,6 +463,7 @@ def BUILD_for_rust_toolchain(
436463
llvm_lib_label = repr(llvm_lib_label),
437464
linker_label = repr(linker_label),
438465
linker_type = repr(linker_type),
466+
rust_objcopy_label = repr(rust_objcopy_label),
439467
extra_rustc_flags = extra_rustc_flags,
440468
extra_exec_rustc_flags = extra_exec_rustc_flags,
441469
opt_level = opt_level,
@@ -520,7 +548,7 @@ def load_rustfmt(ctx, target_triple, version, iso_date):
520548

521549
return BUILD_for_rustfmt(target_triple), sha256
522550

523-
def load_rust_compiler(ctx, iso_date, target_triple, version, include_linker = False):
551+
def load_rust_compiler(ctx, iso_date, target_triple, version, include_linker = False, include_objcopy = False):
524552
"""Loads a rust compiler and yields corresponding BUILD for it
525553
526554
Args:
@@ -529,6 +557,7 @@ def load_rust_compiler(ctx, iso_date, target_triple, version, include_linker = F
529557
target_triple (struct): The Rust-style target that this compiler runs on.
530558
version (str): The version of the tool among \"nightly\", \"beta\", or an exact version.
531559
include_linker (bool): Whether to include linker targets in the output BUILD contents.
560+
include_objcopy (bool): Whether to include rust-objcopy targets in the output BUILD contents.
532561
533562
Returns:
534563
Tuple[str, Dict[str, str]]: The BUILD file contents for this compiler and compiler library
@@ -544,7 +573,7 @@ def load_rust_compiler(ctx, iso_date, target_triple, version, include_linker = F
544573
version = version,
545574
)
546575

547-
return BUILD_for_compiler(target_triple, include_linker), sha256
576+
return BUILD_for_compiler(target_triple, include_linker, include_objcopy), sha256
548577

549578
def load_clippy(ctx, iso_date, target_triple, version):
550579
"""Loads Clippy and yields corresponding BUILD for it

rust/repositories.bzl

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -434,6 +434,19 @@ def _include_llvm_tools(version, iso_date):
434434

435435
return False
436436

437+
def _include_rust_objcopy(version, iso_date):
438+
"""rust-objcopy is available in Rust 1.84.0+ and nightly builds after 2024-10-17"""
439+
if version in ("nightly", "beta"):
440+
if iso_date > "2024-10-17":
441+
return True
442+
return False
443+
444+
version_semver = semver(version)
445+
if version_semver.major >= 1 and version_semver.minor >= 84:
446+
return True
447+
448+
return False
449+
437450
def _rust_toolchain_tools_repository_impl(ctx):
438451
"""The implementation of the rust toolchain tools repository rule."""
439452
sha256s = dict(ctx.attr.sha256s)
@@ -450,12 +463,16 @@ def _rust_toolchain_tools_repository_impl(ctx):
450463

451464
include_linker = True
452465

466+
# rust-objcopy is only available in Rust 1.84.0+
467+
include_objcopy = _include_rust_objcopy(version, iso_date)
468+
453469
rustc_content, rustc_sha256 = load_rust_compiler(
454470
ctx = ctx,
455471
iso_date = iso_date,
456472
target_triple = exec_triple,
457473
version = version,
458474
include_linker = include_linker,
475+
include_objcopy = include_objcopy,
459476
)
460477
clippy_content, clippy_sha256 = load_clippy(
461478
ctx = ctx,
@@ -534,6 +551,7 @@ def _rust_toolchain_tools_repository_impl(ctx):
534551
include_rustfmt = not (not ctx.attr.rustfmt_version),
535552
include_llvm_tools = include_llvm_tools,
536553
include_linker = include_linker,
554+
include_objcopy = include_objcopy,
537555
extra_rustc_flags = ctx.attr.extra_rustc_flags,
538556
extra_exec_rustc_flags = ctx.attr.extra_exec_rustc_flags,
539557
opt_level = ctx.attr.opt_level if ctx.attr.opt_level else None,

rust/toolchain.bzl

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ def _symlink_sysroot_tree(ctx, name, target, target_files = None):
152152
tree_files = []
153153
if target_files == None:
154154
target_files = target.files
155-
for file in target.files.to_list():
155+
for file in target_files.to_list():
156156
# Parse the path to the file relative to the workspace root so a
157157
# symlink matching this path can be created within the sysroot.
158158

@@ -284,11 +284,14 @@ def _generate_sysroot(
284284
linker.label,
285285
))
286286
linker_bin = linker_files[0]
287+
288+
# Extract lib/rustlib/{triple}/bin from linker source path.
289+
# rustc adds {sysroot}/lib/rustlib/{host}/bin/ to PATH when invoking
290+
# linkers, so tools like wasm-component-ld can find rust-lld there.
287291
dest = "bin"
288-
if "/bin/" in linker_bin.path:
289-
_, _, subdir = linker_bin.path.partition("/bin/")
290-
if subdir:
291-
dest = "bin/{}".format(subdir[:-len("/" + linker_bin.basename)]).rstrip("/")
292+
if "/lib/rustlib/" in linker_bin.dirname:
293+
idx = linker_bin.dirname.find("/lib/rustlib/")
294+
dest = linker_bin.dirname[idx + 1:]
292295

293296
sysroot_linker = _symlink_sysroot_bin(ctx, name, dest, linker_bin)
294297
sysroot_linker_files = _symlink_sysroot_tree(ctx, name, linker, linker[DefaultInfo].default_runfiles.files)
@@ -585,6 +588,7 @@ def _rust_toolchain_impl(ctx):
585588
llvm_cov = ctx.file.llvm_cov,
586589
llvm_profdata = ctx.file.llvm_profdata,
587590
llvm_lib = ctx.files.llvm_lib,
591+
rust_objcopy = ctx.file.rust_objcopy,
588592
lto = lto,
589593
make_variables = make_variable_info,
590594
rust_doc = sysroot.rustdoc,
@@ -780,6 +784,11 @@ rust_toolchain = rule(
780784
cfg = "exec",
781785
mandatory = True,
782786
),
787+
"rust_objcopy": attr.label(
788+
doc = "The location of the `rust-objcopy` binary. Can be a direct source or a filegroup containing one item.",
789+
allow_single_file = True,
790+
cfg = "exec",
791+
),
783792
"rust_std": attr.label(
784793
doc = "The Rust standard library.",
785794
mandatory = True,

0 commit comments

Comments
 (0)