diff --git a/rust/private/repository_utils.bzl b/rust/private/repository_utils.bzl index 05b741947d..632ff7163a 100644 --- a/rust/private/repository_utils.bzl +++ b/rust/private/repository_utils.bzl @@ -90,12 +90,24 @@ filegroup( ) """ -def BUILD_for_compiler(target_triple, include_linker = False): +_build_file_for_objcopy_template = """\ +filegroup( + name = "rust-objcopy", + srcs = glob( + ["lib/rustlib/{target_triple}/bin/rust-objcopy{binary_ext}"], + allow_empty = True, + ), + visibility = ["//visibility:public"], +) +""" + +def BUILD_for_compiler(target_triple, include_linker = False, include_objcopy = False): """Emits a BUILD file the compiler archive. Args: target_triple (str): The triple of the target platform include_linker (bool): Whether to generate targets for linkers. + include_objcopy (bool): Whether to generate targets for rust-objcopy. Returns: str: The contents of a BUILD file @@ -117,6 +129,14 @@ def BUILD_for_compiler(target_triple, include_linker = False): ), ) + if include_objcopy: + content.append( + _build_file_for_objcopy_template.format( + binary_ext = system_to_binary_ext(target_triple.system), + target_triple = target_triple.str, + ), + ) + return "\n".join(content) _build_file_for_cargo_template = """\ @@ -324,6 +344,7 @@ rust_toolchain( rustc = "//:rustc", linker = {linker_label}, linker_type = {linker_type}, + rust_objcopy = {rust_objcopy_label}, rustfmt = {rustfmt_label}, cargo = "//:cargo", clippy_driver = "//:clippy_driver_bin", @@ -361,6 +382,7 @@ def BUILD_for_rust_toolchain( include_rustfmt, include_llvm_tools, include_linker, + include_objcopy = False, stdlib_linkflags = None, extra_rustc_flags = None, extra_exec_rustc_flags = None, @@ -381,6 +403,7 @@ def BUILD_for_rust_toolchain( include_rustfmt (bool): Whether rustfmt is present in the toolchain. include_llvm_tools (bool): Whether llvm-tools are present in the toolchain. include_linker (bool): Whether a linker is available in the toolchain. + include_objcopy (bool): Whether rust-objcopy is available in the toolchain. stdlib_linkflags (list, optional): Overridden flags needed for linking to rust stdlib, akin to BAZEL_LINKLIBS. Defaults to None. @@ -418,6 +441,10 @@ def BUILD_for_rust_toolchain( linker_label = "//:rust-lld" linker_type = "direct" + rust_objcopy_label = None + if include_objcopy: + rust_objcopy_label = "//:rust-objcopy" + return _build_file_for_rust_toolchain_template.format( toolchain_name = name, binary_ext = system_to_binary_ext(target_triple.system), @@ -435,6 +462,7 @@ def BUILD_for_rust_toolchain( llvm_lib_label = repr(llvm_lib_label), linker_label = repr(linker_label), linker_type = repr(linker_type), + rust_objcopy_label = repr(rust_objcopy_label), extra_rustc_flags = extra_rustc_flags, extra_exec_rustc_flags = extra_exec_rustc_flags, opt_level = opt_level, @@ -519,7 +547,7 @@ def load_rustfmt(ctx, target_triple, version, iso_date): return BUILD_for_rustfmt(target_triple), sha256 -def load_rust_compiler(ctx, iso_date, target_triple, version, include_linker = False): +def load_rust_compiler(ctx, iso_date, target_triple, version, include_linker = False, include_objcopy = False): """Loads a rust compiler and yields corresponding BUILD for it Args: @@ -528,6 +556,7 @@ def load_rust_compiler(ctx, iso_date, target_triple, version, include_linker = F target_triple (struct): The Rust-style target that this compiler runs on. version (str): The version of the tool among \"nightly\", \"beta\", or an exact version. include_linker (bool): Whether to include linker targets in the output BUILD contents. + include_objcopy (bool): Whether to include rust-objcopy targets in the output BUILD contents. Returns: Tuple[str, Dict[str, str]]: The BUILD file contents for this compiler and compiler library @@ -543,7 +572,7 @@ def load_rust_compiler(ctx, iso_date, target_triple, version, include_linker = F version = version, ) - return BUILD_for_compiler(target_triple, include_linker), sha256 + return BUILD_for_compiler(target_triple, include_linker, include_objcopy), sha256 def load_clippy(ctx, iso_date, target_triple, version): """Loads Clippy and yields corresponding BUILD for it diff --git a/rust/repositories.bzl b/rust/repositories.bzl index d3609c2d07..65fdc8f391 100644 --- a/rust/repositories.bzl +++ b/rust/repositories.bzl @@ -449,6 +449,7 @@ def _rust_toolchain_tools_repository_impl(ctx): exec_triple = triple(ctx.attr.exec_triple) include_linker = True + include_objcopy = True rustc_content, rustc_sha256 = load_rust_compiler( ctx = ctx, @@ -456,6 +457,7 @@ def _rust_toolchain_tools_repository_impl(ctx): target_triple = exec_triple, version = version, include_linker = include_linker, + include_objcopy = include_objcopy, ) clippy_content, clippy_sha256 = load_clippy( ctx = ctx, @@ -534,6 +536,7 @@ def _rust_toolchain_tools_repository_impl(ctx): include_rustfmt = not (not ctx.attr.rustfmt_version), include_llvm_tools = include_llvm_tools, include_linker = include_linker, + include_objcopy = include_objcopy, extra_rustc_flags = ctx.attr.extra_rustc_flags, extra_exec_rustc_flags = ctx.attr.extra_exec_rustc_flags, opt_level = ctx.attr.opt_level if ctx.attr.opt_level else None, @@ -769,6 +772,7 @@ _RUST_ANALYZER_TOOLCHAIN_TOOLS_REPOSITORY_ATTRS = { def _rust_analyzer_toolchain_tools_repository_impl(repository_ctx): sha256s = dict(repository_ctx.attr.sha256s) include_linker = True + include_objcopy = True iso_date = None version = repository_ctx.attr.version @@ -794,6 +798,7 @@ def _rust_analyzer_toolchain_tools_repository_impl(repository_ctx): target_triple = host_triple, version = version, include_linker = include_linker, + include_objcopy = include_objcopy, ) build_contents = [rustc_content] sha256s.update(rustc_sha256) @@ -929,6 +934,7 @@ def _rustfmt_toolchain_tools_repository_impl(repository_ctx): )) include_linker = True + include_objcopy = True iso_date = None version = repository_ctx.attr.version @@ -949,6 +955,7 @@ def _rustfmt_toolchain_tools_repository_impl(repository_ctx): target_triple = exec_triple, version = version, include_linker = include_linker, + include_objcopy = include_objcopy, ) rustfmt_content, rustfmt_sha256 = load_rustfmt( ctx = repository_ctx, diff --git a/rust/toolchain.bzl b/rust/toolchain.bzl index 91e3032166..c2aa484ac2 100644 --- a/rust/toolchain.bzl +++ b/rust/toolchain.bzl @@ -152,7 +152,7 @@ def _symlink_sysroot_tree(ctx, name, target, target_files = None): tree_files = [] if target_files == None: target_files = target.files - for file in target.files.to_list(): + for file in target_files.to_list(): # Parse the path to the file relative to the workspace root so a # symlink matching this path can be created within the sysroot. @@ -284,11 +284,14 @@ def _generate_sysroot( linker.label, )) linker_bin = linker_files[0] + + # Extract lib/rustlib/{triple}/bin from linker source path. + # rustc adds {sysroot}/lib/rustlib/{host}/bin/ to PATH when invoking + # linkers, so tools like wasm-component-ld can find rust-lld there. dest = "bin" - if "/bin/" in linker_bin.path: - _, _, subdir = linker_bin.path.partition("/bin/") - if subdir: - dest = "bin/{}".format(subdir[:-len("/" + linker_bin.basename)]).rstrip("/") + if "/lib/rustlib/" in linker_bin.dirname: + idx = linker_bin.dirname.find("/lib/rustlib/") + dest = linker_bin.dirname[idx + 1:] sysroot_linker = _symlink_sysroot_bin(ctx, name, dest, linker_bin) sysroot_linker_files = _symlink_sysroot_tree(ctx, name, linker, linker[DefaultInfo].default_runfiles.files) @@ -585,6 +588,7 @@ def _rust_toolchain_impl(ctx): llvm_cov = ctx.file.llvm_cov, llvm_profdata = ctx.file.llvm_profdata, llvm_lib = ctx.files.llvm_lib, + rust_objcopy = ctx.file.rust_objcopy, lto = lto, make_variables = make_variable_info, rust_doc = sysroot.rustdoc, @@ -780,6 +784,11 @@ rust_toolchain = rule( cfg = "exec", mandatory = True, ), + "rust_objcopy": attr.label( + doc = "The location of the `rust-objcopy` binary. Can be a direct source or a filegroup containing one item.", + allow_single_file = True, + cfg = "exec", + ), "rust_std": attr.label( doc = "The Rust standard library.", mandatory = True,