Rollup merge of #138867 - petrochenkov:linkfix, r=nnethercote

linker: Fix staticlib naming for UEFI

And one minor refactoring in the second commit.
This commit is contained in:
Jacob Pratt 2025-03-25 20:34:46 -04:00 committed by GitHub
commit a883b23ef5
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 36 additions and 24 deletions

View file

@ -670,7 +670,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);
let self_contained_components = self_contained_components(sess, crate_type, &linker_path);
// On AIX, we ship all libraries as .a big_af archive
// the expected format is lib<name>.a(libname.so) for the actual
@ -1494,7 +1494,8 @@ fn print_native_static_libs(
| NativeLibKind::Unspecified => {
let verbatim = lib.verbatim;
if sess.target.is_like_msvc {
Some(format!("{}{}", name, if verbatim { "" } else { ".lib" }))
let (prefix, suffix) = sess.staticlib_components(verbatim);
Some(format!("{prefix}{name}{suffix}"))
} else if sess.target.linker_flavor.is_gnu() {
Some(format!("-l{}{}", if verbatim { ":" } else { "" }, name))
} else {
@ -1783,8 +1784,7 @@ 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) -> bool {
let (linker, _) = linker_and_flavor(sess);
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;
@ -1792,7 +1792,7 @@ fn detect_self_contained_mingw(sess: &Session) -> bool {
let linker_with_extension = if cfg!(windows) && linker.extension().is_none() {
linker.with_extension("exe")
} else {
linker
linker.to_path_buf()
};
for dir in env::split_paths(&env::var_os("PATH").unwrap_or_default()) {
let full_path = dir.join(&linker_with_extension);
@ -1807,7 +1807,11 @@ fn detect_self_contained_mingw(sess: &Session) -> 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) -> LinkSelfContainedComponents {
fn self_contained_components(
sess: &Session,
crate_type: CrateType,
linker: &Path,
) -> LinkSelfContainedComponents {
// Turn the backwards compatible bool values for `self_contained` into fully inferred
// `LinkSelfContainedComponents`.
let self_contained =
@ -1836,7 +1840,7 @@ fn self_contained_components(sess: &Session, crate_type: CrateType) -> LinkSelfC
LinkSelfContainedDefault::InferredForMingw => {
sess.host == sess.target
&& sess.target.vendor != "uwp"
&& detect_self_contained_mingw(sess)
&& detect_self_contained_mingw(sess, linker)
}
}
};

View file

@ -450,9 +450,10 @@ impl<'a> GccLinker<'a> {
// The output filename already contains `dll_suffix` so
// the resulting import library will have a name in the
// form of libfoo.dll.a
let mut implib_name = OsString::from(&*self.sess.target.staticlib_prefix);
let (prefix, suffix) = self.sess.staticlib_components(false);
let mut implib_name = OsString::from(prefix);
implib_name.push(name);
implib_name.push(&*self.sess.target.staticlib_suffix);
implib_name.push(suffix);
let mut out_implib = OsString::from("--out-implib=");
out_implib.push(out_filename.with_file_name(implib_name));
self.link_arg(out_implib);
@ -958,9 +959,9 @@ impl<'a> Linker for MsvcLinker<'a> {
if let Some(path) = try_find_native_static_library(self.sess, name, verbatim) {
self.link_staticlib_by_path(&path, whole_archive);
} else {
let prefix = if whole_archive { "/WHOLEARCHIVE:" } else { "" };
let suffix = if verbatim { "" } else { ".lib" };
self.link_arg(format!("{prefix}{name}{suffix}"));
let opts = if whole_archive { "/WHOLEARCHIVE:" } else { "" };
let (prefix, suffix) = self.sess.staticlib_components(verbatim);
self.link_arg(format!("{opts}{prefix}{name}{suffix}"));
}
}

View file

@ -95,14 +95,14 @@ pub fn try_find_native_static_library(
name: &str,
verbatim: bool,
) -> Option<PathBuf> {
let default = sess.staticlib_components(verbatim);
let formats = if verbatim {
vec![("".into(), "".into())]
vec![default]
} else {
let os = (sess.target.staticlib_prefix.clone(), sess.target.staticlib_suffix.clone());
// On Windows, static libraries sometimes show up as libfoo.a and other
// times show up as foo.lib
let unix = ("lib".into(), ".a".into());
if os == unix { vec![os] } else { vec![os, unix] }
let unix = ("lib", ".a");
if default == unix { vec![default] } else { vec![default, unix] }
};
walk_native_lib_search_dirs(sess, None, |dir, is_framework| {
@ -124,18 +124,17 @@ pub fn try_find_native_dynamic_library(
name: &str,
verbatim: bool,
) -> Option<PathBuf> {
let default = sess.staticlib_components(verbatim);
let formats = if verbatim {
vec![("".into(), "".into())]
vec![default]
} else {
// While the official naming convention for MSVC import libraries
// is foo.lib...
let os = (sess.target.staticlib_prefix.clone(), sess.target.staticlib_suffix.clone());
// ... Meson follows the libfoo.dll.a convention to
// is foo.lib, Meson follows the libfoo.dll.a convention to
// disambiguate .a for static libraries
let meson = ("lib".into(), ".dll.a".into());
let meson = ("lib", ".dll.a");
// and MinGW uses .a altogether
let mingw = ("lib".into(), ".a".into());
vec![os, meson, mingw]
let mingw = ("lib", ".a");
vec![default, meson, mingw]
};
walk_native_lib_search_dirs(sess, None, |dir, is_framework| {

View file

@ -103,7 +103,7 @@ pub fn filename_for_input(
OutFileName::Real(outputs.out_directory.join(&format!("{prefix}{libname}{suffix}")))
}
CrateType::Staticlib => {
let (prefix, suffix) = (&sess.target.staticlib_prefix, &sess.target.staticlib_suffix);
let (prefix, suffix) = sess.staticlib_components(false);
OutFileName::Real(outputs.out_directory.join(&format!("{prefix}{libname}{suffix}")))
}
CrateType::Executable => {

View file

@ -586,6 +586,14 @@ impl Session {
.or(self.target.options.default_visibility)
.unwrap_or(SymbolVisibility::Interposable)
}
pub fn staticlib_components(&self, verbatim: bool) -> (&str, &str) {
if verbatim {
("", "")
} else {
(&*self.target.staticlib_prefix, &*self.target.staticlib_suffix)
}
}
}
// JUSTIFICATION: defn of the suggested wrapper fns