Skip to content
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 16 additions & 15 deletions compiler/rustc_codegen_ssa/src/back/link.rs
Original file line number Diff line number Diff line change
Expand Up @@ -686,7 +686,7 @@ fn link_natively(
) {
info!("preparing {:?} to {:?}", crate_type, out_filename);
let (linker_path, flavor) = linker_and_flavor(sess);
let self_contained_components = self_contained_components(sess, crate_type, &linker_path);
let self_contained_components = self_contained_components(sess, crate_type);

// On AIX, we ship all libraries as .a big_af archive
// the expected format is lib<name>.a(libname.so) for the actual
Expand Down Expand Up @@ -1761,20 +1761,25 @@ fn link_output_kind(sess: &Session, crate_type: CrateType) -> LinkOutputKind {
}
}

// Returns true if linker is located within sysroot
fn detect_self_contained_mingw(sess: &Session, linker: &Path) -> bool {
// Assume `-C linker=rust-lld` as self-contained mode
if linker == Path::new("rust-lld") {
return true;
/// Returns true if linker is shipped by Rust.
// There are currently two different solutions for self-contained mode with mingw-w64:
// using rust-lld directly (`-gnullvm` and `-gnu`) or using shipped cc to call the linker (`-gnu`).
// Eventually, `-gnu` toolchains might be moved to calling the linker directly.
fn detect_self_contained_mingw(sess: &Session) -> bool {
// Passing explicit linker other than `rust-lld` means non-self-contained mode.
if let Some(linker) = &sess.opts.cg.linker {
return linker == Path::new("rust-lld");
}
let linker_with_extension = if cfg!(windows) && linker.extension().is_none() {

// If no explicit linker was given, proceed with implicit one (if present).
let linker_with_extension = if let Some(linker) = sess.target.linker.as_deref().map(Path::new) {
linker.with_extension("exe")
} else {
linker.to_path_buf()
return false;
};
for dir in env::split_paths(&env::var_os("PATH").unwrap_or_default()) {
let full_path = dir.join(&linker_with_extension);
// If linker comes from sysroot assume self-contained mode
// If found linker doesn't come from sysroot assume non-self-contained mode.
if full_path.is_file() && !full_path.starts_with(sess.opts.sysroot.path()) {
return false;
}
Expand All @@ -1785,11 +1790,7 @@ fn detect_self_contained_mingw(sess: &Session, linker: &Path) -> bool {
/// Various toolchain components used during linking are used from rustc distribution
/// instead of being found somewhere on the host system.
/// We only provide such support for a very limited number of targets.
fn self_contained_components(
sess: &Session,
crate_type: CrateType,
linker: &Path,
) -> LinkSelfContainedComponents {
fn self_contained_components(sess: &Session, crate_type: CrateType) -> LinkSelfContainedComponents {
// Turn the backwards compatible bool values for `self_contained` into fully inferred
// `LinkSelfContainedComponents`.
let self_contained =
Expand Down Expand Up @@ -1818,7 +1819,7 @@ fn self_contained_components(
LinkSelfContainedDefault::InferredForMingw => {
sess.host == sess.target
&& sess.target.abi != Abi::Uwp
&& detect_self_contained_mingw(sess, linker)
&& detect_self_contained_mingw(sess)
}
}
};
Expand Down
Loading