diff --git a/compiler/rustc_codegen_ssa/messages.ftl b/compiler/rustc_codegen_ssa/messages.ftl index 3b34eb063ec..94216ce63ba 100644 --- a/compiler/rustc_codegen_ssa/messages.ftl +++ b/compiler/rustc_codegen_ssa/messages.ftl @@ -2,6 +2,8 @@ codegen_ssa_L4Bender_exporting_symbols_unimplemented = exporting symbols not imp codegen_ssa_add_native_library = failed to add native library {$library_path}: {$error} +codegen_ssa_aix_strip_not_used = using host's `strip` binary to cross-compile to AIX which is not guaranteed to work + codegen_ssa_apple_deployment_target_invalid = failed to parse deployment target specified in {$env_var}: {$error} diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index 39ff00baf6d..44581cfa64b 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -1085,9 +1085,7 @@ fn is_illegal_instruction(_status: &ExitStatus) -> bool { let strip = sess.opts.cg.strip; if sess.target.is_like_osx { - // Use system `strip` when running on host macOS. - // - let stripcmd = if cfg!(target_os = "macos") { "/usr/bin/strip" } else { "strip" }; + let stripcmd = "rust-objcopy"; match (strip, crate_type) { (Strip::Debuginfo, _) => { strip_symbols_with_external_utility(sess, stripcmd, out_filename, Some("-S")) @@ -1103,11 +1101,14 @@ fn is_illegal_instruction(_status: &ExitStatus) -> bool { } } - if sess.target.os == "illumos" { + if sess.target.is_like_solaris { // Many illumos systems will have both the native 'strip' utility and // the GNU one. Use the native version explicitly and do not rely on // what's in the path. - let stripcmd = "/usr/bin/strip"; + // + // If cross-compiling and there is not a native version, then use + // `llvm-strip` and hope. + let stripcmd = if !sess.host.is_like_solaris { "rust-objcopy" } else { "/usr/bin/strip" }; match strip { // Always preserve the symbol table (-x). Strip::Debuginfo => { @@ -1120,6 +1121,10 @@ fn is_illegal_instruction(_status: &ExitStatus) -> bool { } if sess.target.is_like_aix { + // `llvm-strip` doesn't work for AIX - their strip must be used. + if !sess.host.is_like_aix { + sess.dcx().emit_warn(errors::AixStripNotUsed); + } let stripcmd = "/usr/bin/strip"; match strip { Strip::Debuginfo => { @@ -1147,6 +1152,13 @@ fn strip_symbols_with_external_utility( if let Some(option) = option { cmd.arg(option); } + + let mut new_path = sess.get_tools_search_paths(false); + if let Some(path) = env::var_os("PATH") { + new_path.extend(env::split_paths(&path)); + } + cmd.env("PATH", env::join_paths(new_path).unwrap()); + let prog = cmd.arg(out_filename).output(); match prog { Ok(prog) => { diff --git a/compiler/rustc_codegen_ssa/src/errors.rs b/compiler/rustc_codegen_ssa/src/errors.rs index cf8d1cfa0d1..936e09f58c3 100644 --- a/compiler/rustc_codegen_ssa/src/errors.rs +++ b/compiler/rustc_codegen_ssa/src/errors.rs @@ -1101,3 +1101,7 @@ fn into_diag(self, dcx: DiagCtxtHandle<'_>, level: Level) -> Diag<'_, G> { diag } } + +#[derive(Diagnostic)] +#[diag(codegen_ssa_aix_strip_not_used)] +pub(crate) struct AixStripNotUsed;