diff options
| author | bors <bors@rust-lang.org> | 2021-08-29 04:51:14 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2021-08-29 04:51:14 +0000 |
| commit | 757a65bfdf504f6c9177514abb385618e784f0a5 (patch) | |
| tree | f43495c342123f37da31319b13a5bb8fc85def55 | |
| parent | 3a21a5b324963e18f00106b611460a5a83a53ace (diff) | |
| parent | 0f7702efa1cbff1ae0552664dc814e9ac682c09c (diff) | |
| download | rust-757a65bfdf504f6c9177514abb385618e784f0a5.tar.gz rust-757a65bfdf504f6c9177514abb385618e784f0a5.zip | |
Auto merge of #88250 - rusticstuff:macos-lld, r=nagisa
Make `-Z gcc-ld=lld` work for Apple targets `-Z gcc-ld=lld` was introduced in #85961. It does not work on Macos because lld needs be either named `ld64` or passed `-flavor darwin` as the first two arguments in order to select the Mach-O flavor. Rust invokes cc (=clang) on Macos for linking which calls `ld` as linker binary and not `ld64`, so just creating an `ld64` binary and modifying the search path with `-B` does not work. In order to solve this patch does: * Set the `lld_flavor` for all Apple-derived targets to `LldFlavor::Ld64`. As far as I can see this actually works towards fixing `-Xlinker=rust-lld` as all those targets use the Mach-O object format. * Copy/hardlink rust-lld to the gcc-ld subdirectory as ld64 next to ld. * If `-Z gcc-ld=lld` is used and the target lld flavor is Ld64 add `-fuse-ld=/path/to/ld64` to the linker invocation. Fixes #86945.
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/back/link.rs | 47 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/apple_base.rs | 3 | ||||
| -rw-r--r-- | src/bootstrap/compile.rs | 4 | ||||
| -rw-r--r-- | src/bootstrap/dist.rs | 2 |
4 files changed, 41 insertions, 15 deletions
diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index e51d6fff788..f5463bca338 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -2482,20 +2482,39 @@ fn add_gcc_ld_path(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) { if let LinkerFlavor::Gcc = flavor { match ld_impl { LdImpl::Lld => { - let tools_path = - sess.host_filesearch(PathKind::All).get_tools_search_paths(false); - let lld_path = tools_path - .into_iter() - .map(|p| p.join("gcc-ld")) - .find(|p| { - p.join(if sess.host.is_like_windows { "ld.exe" } else { "ld" }).exists() - }) - .unwrap_or_else(|| sess.fatal("rust-lld (as ld) not found")); - cmd.cmd().arg({ - let mut arg = OsString::from("-B"); - arg.push(lld_path); - arg - }); + if sess.target.lld_flavor == LldFlavor::Ld64 { + let tools_path = + sess.host_filesearch(PathKind::All).get_tools_search_paths(false); + let ld64_exe = tools_path + .into_iter() + .map(|p| p.join("gcc-ld")) + .map(|p| { + p.join(if sess.host.is_like_windows { "ld64.exe" } else { "ld64" }) + }) + .find(|p| p.exists()) + .unwrap_or_else(|| sess.fatal("rust-lld (as ld64) not found")); + cmd.cmd().arg({ + let mut arg = OsString::from("-fuse-ld="); + arg.push(ld64_exe); + arg + }); + } else { + let tools_path = + sess.host_filesearch(PathKind::All).get_tools_search_paths(false); + let lld_path = tools_path + .into_iter() + .map(|p| p.join("gcc-ld")) + .find(|p| { + p.join(if sess.host.is_like_windows { "ld.exe" } else { "ld" }) + .exists() + }) + .unwrap_or_else(|| sess.fatal("rust-lld (as ld) not found")); + cmd.cmd().arg({ + let mut arg = OsString::from("-B"); + arg.push(lld_path); + arg + }); + } } } } else { diff --git a/compiler/rustc_target/src/spec/apple_base.rs b/compiler/rustc_target/src/spec/apple_base.rs index 5d75f6ab39c..a21b784e11b 100644 --- a/compiler/rustc_target/src/spec/apple_base.rs +++ b/compiler/rustc_target/src/spec/apple_base.rs @@ -1,6 +1,6 @@ use std::env; -use crate::spec::{FramePointer, SplitDebuginfo, TargetOptions}; +use crate::spec::{FramePointer, LldFlavor, SplitDebuginfo, TargetOptions}; pub fn opts(os: &str) -> TargetOptions { // ELF TLS is only available in macOS 10.7+. If you try to compile for 10.6 @@ -35,6 +35,7 @@ pub fn opts(os: &str) -> TargetOptions { abi_return_struct_as_int: true, emit_debug_gdb_scripts: false, eh_frame_header: false, + lld_flavor: LldFlavor::Ld64, // The historical default for macOS targets is to run `dsymutil` which // generates a packed version of debuginfo split from the main file. diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index afddbc1da9e..8f27adaed84 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -1133,6 +1133,10 @@ impl Step for Assemble { &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)), + ); } // Similarly, copy `llvm-dwp` into libdir for Split DWARF. Only copy it when the LLVM diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index d7d511c1c92..7c1bb1a9148 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -412,6 +412,8 @@ impl Step for Rustc { 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))); } // Copy over llvm-dwp if it's there |
