From 8cdf1ee2fd54c8fb20af0e7fe09fcd8d1c43f316 Mon Sep 17 00:00:00 2001 From: "L. E. Segovia" Date: Wed, 3 Apr 2024 20:08:56 -0300 Subject: [PATCH] MsvcLinker: allow linking dynamically to Meson and MinGW-style named libraries Fixes #122455 --- compiler/rustc_codegen_ssa/src/back/linker.rs | 37 ++++++++++++++++++- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/back/linker.rs b/compiler/rustc_codegen_ssa/src/back/linker.rs index 5c6a4dd929b6..918db766cb38 100644 --- a/compiler/rustc_codegen_ssa/src/back/linker.rs +++ b/compiler/rustc_codegen_ssa/src/back/linker.rs @@ -784,6 +784,38 @@ pub struct MsvcLinker<'a> { sess: &'a Session, } +impl MsvcLinker<'_> { + // FIXME this duplicates rustc_metadata::find_native_static_library, + // as the Meson/MinGW suffix for import libraries can differ + fn find_native_dynamic_library(name: &str, verbatim: bool, sess: &Session) -> OsString { + let formats = if verbatim { + vec![("".into(), "".into())] + } 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 + // disambiguate .a for static libraries + let meson = ("lib".into(), ".dll.a".into()); + // and MinGW uses .a altogether + let mingw = ("lib".into(), ".a".into()); + vec![os, meson, mingw] + }; + + for path in sess.target_filesearch(PathKind::Native).search_paths() { + for (prefix, suffix) in &formats { + let test = path.join(format!("{prefix}{name}{suffix}")); + if test.exists() { + return OsString::from(test); + } + } + } + + // Allow the linker to find CRT libs itself + OsString::from(format!("{}{}", name, if verbatim { "" } else { ".lib" })) + } +} + impl<'a> Linker for MsvcLinker<'a> { fn cmd(&mut self) -> &mut Command { &mut self.cmd @@ -807,8 +839,9 @@ impl<'a> Linker for MsvcLinker<'a> { } } - fn link_dylib_by_name(&mut self, name: &str, verbatim: bool, _search_paths: &SearchPaths, _as_needed: bool) { - self.cmd.arg(format!("{}{}", name, if verbatim { "" } else { ".lib" })); + fn link_dylib_by_name(&mut self, name: &str, verbatim: bool, _as_needed: bool) { + let path = MsvcLinker::<'a>::find_native_dynamic_library(name, verbatim, self.sess); + self.cmd.arg(path); } fn link_staticlib_by_name(