Change:
Checked that on target, found duplicates in versions: and <strikeno duplicates</strike2 duplicates (<strikeonly</strike, ) in stable , (bisecting is kinda slow on my connection) there 3 copies of that executable, that gives ~ 187mb label +regression-from-stable-to-beta
Can be found in:
I think they were in and . I believe is also a copy of .
Assigning priority as discussed in the of the Prioritization Working Group. label -I-prioritize +P-medium
claim
Sorry, I only came across this issue just now. The copies are there for a reason, see linked issues. Multiple things to consider: The files in the directory are only used with the unstable option. So they could be removed for beta and stable. They can be replaced with small Rust executables which just exec and respectively. I will be working on that for nightly.

Discussion:
] [[package]] <ins> name = "lld-wrapper" version = "0.1.0" [[package]] </ins> name = "lock_api" version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index"

"src/tools/jsondocck", "src/tools/html-checker", "src/tools/bump-stage0", <ins> "src/tools/lld-wrapper", </ins> ] exclude = [

// for `-Z gcc-ld=lld` let gcc_ld_dir = libdir_bin.join("gcc-ld"); t!(fs::create_dir(&gcc_ld_dir)); <del> builder.copy( &lld_install.join("bin").join(&src_exe), &gcc_ld_dir.join(exe("ld", target_compiler.host)), ); builder.copy( &lld_install.join("bin").join(&src_exe), &gcc_ld_dir.join(exe("ld64", target_compiler.host)), ); </del> <ins> for flavor in ["ld", "ld64"] { let lld_wrapper_exe = builder.ensure(crate::tool::LldWrapper { compiler: build_compiler, target: target_compiler.host, flavor_feature: flavor, }); builder.copy(&lld_wrapper_exe, &gcc_ld_dir.join(exe(flavor, target_compiler.host))); } </ins> } // Similarly, copy `llvm-dwp` into libdir for Split DWARF. Only copy it when the LLVM

let rust_lld = exe("rust-lld", compiler.host); builder.copy(&src_dir.join(&rust_lld), &dst_dir.join(&rust_lld)); // for `-Z gcc-ld=lld` <del> let gcc_lld_dir = dst_dir.join("gcc-ld"); t!(fs::create_dir(&gcc_lld_dir)); builder.copy(&src_dir.join(&rust_lld), &gcc_lld_dir.join(exe("ld", compiler.host))); builder .copy(&src_dir.join(&rust_lld), &gcc_lld_dir.join(exe("ld64", compiler.host))); </del> <ins> let gcc_lld_src_dir = src_dir.join("gcc-ld"); let gcc_lld_dst_dir = dst_dir.join("gcc-ld"); t!(fs::create_dir(&gcc_lld_dst_dir)); for flavor in ["ld", "ld64"] { let exe_name = exe(flavor, compiler.host); builder .copy(&gcc_lld_src_dir.join(&exe_name), &gcc_lld_dst_dir.join(&exe_name)); } </ins> } // Copy over llvm-dwp if it's there

} } <ins> #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] pub struct LldWrapper { pub compiler: Compiler, pub target: TargetSelection, pub flavor_feature: &'static str, } impl Step for LldWrapper { type Output = PathBuf; fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { run.never() } fn run(self, builder: &Builder<'_>) -> PathBuf { let src_exe = builder .ensure(ToolBuild { compiler: self.compiler, target: self.target, tool: "lld-wrapper", mode: Mode::ToolStd, path: "src/tools/lld-wrapper", is_optional_tool: false, source_type: SourceType::InTree, extra_features: vec![self.flavor_feature.to_owned()], }) .expect("expected to build -- essential tool"); src_exe } } </ins> macro_rules! tool_extended { (($sel:ident, $builder:ident), $($name:ident,

<ins> [package] name = "lld-wrapper" version = "0.1.0" edition = "2021" license = "MIT OR Apache-2.0" [dependencies] [features] ld = [] ld64 = [] </ins>  No newline at end of file

<ins> //! Script to invoke the bundled rust-lld with the correct flavor. The flavor is selected by //! feature. //! //! lld supports multiple command line interfaces. If `-flavor <flavor>` are passed as the first //! two arguments the `<flavor>` command line interface is used to process the remaining arguments. //! If no `-flavor` argument is present the flavor is determined by the executable name. //! //! In Rust with `-Z gcc-ld=lld` we have gcc or clang invoke rust-lld. Since there is no way to //! make gcc/clang pass `-flavor <flavor>` as the first two arguments in the linker invocation //! and since Windows does not support symbolic links for files this wrapper is used in place of a //! symblic link. It execs `../rust-lld -flavor ld` if the feature `ld` is enabled and //! `../rust-lld -flavor ld64` if `ld64` is enabled. On Windows it spawns a `..rust-lld.exe` //! child process. #[cfg(not(any(feature = "ld", feature = "ld64")))] compile_error!("One of the features ld and ld64 must be enabled."); #[cfg(all(feature = "ld", feature = "ld64"))] compile_error!("Only one of the feature ld or ld64 can be enabled."); #[cfg(feature = "ld")] const FLAVOR: &str = "ld"; #[cfg(feature = "ld64")] const FLAVOR: &str = "ld64"; use std::env; use std::fmt::Display; use std::path::{Path, PathBuf}; use std::process; trait ResultExt<T, E> { fn unwrap_or_exit_with(self, context: &str) -> T; } impl<T, E> ResultExt<T, E> for Result<T, E> where E: Display, { fn unwrap_or_exit_with(self, context: &str) -> T { match self { Ok(t) => t, Err(e) => { eprintln!("lld-wrapper: {}: {}", context, e); process::exit(1); } } } } trait OptionExt<T> { fn unwrap_or_exit_with(self, context: &str) -> T; } impl<T> OptionExt<T> for Option<T> { fn unwrap_or_exit_with(self, context: &str) -> T { match self { Some(t) => t, None => { eprintln!("lld-wrapper: {}", context); process::exit(1); } } } } /// Returns the path to rust-lld in the parent directory. /// /// Exits if the parent directory cannot be determined. fn get_rust_lld_path(current_exe_path: &Path) -> PathBuf { let mut rust_lld_exe_name = "rust-lld".to_owned(); rust_lld_exe_name.push_str(env::consts::EXE_SUFFIX); let mut rust_lld_path = current_exe_path .parent() .unwrap_or_exit_with("directory containing current executable could not be determined") .parent() .unwrap_or_exit_with("parent directory could not be determined") .to_owned(); rust_lld_path.push(rust_lld_exe_name); rust_lld_path } /// Returns the command for invoking rust-lld with the correct flavor. /// /// Exits on error. fn get_rust_lld_command(current_exe_path: &Path) -> process::Command { let rust_lld_path = get_rust_lld_path(current_exe_path); let mut command = process::Command::new(rust_lld_path); command.arg("-flavor"); command.arg(FLAVOR); command.args(env::args_os().skip(1)); command } #[cfg(unix)] fn exec_lld(mut command: process::Command) { use std::os::unix::prelude::CommandExt; Result::<(), _>::Err(command.exec()).unwrap_or_exit_with("could not exec rust-lld"); unreachable!("lld-wrapper: after exec without error"); } #[cfg(not(unix))] fn exec_lld(mut command: process::Command) { // Windows has no exec(), spawn a child process and wait for it let exit_status = command.status().unwrap_or_exit_with("error running rust-lld child process"); if !exit_status.success() { match exit_status.code() { Some(code) => { // return the original lld exit code process::exit(code) } None => { eprintln!("lld-wrapper: rust-lld child process exited with error: {}", exit_status,); process::exit(1); } } } } fn main() { let current_exe_path = env::current_exe().unwrap_or_exit_with("could not get the path of the current executable"); exec_lld(get_rust_lld_command(current_exe_path.as_ref())); } </ins>