Skip to content

Commit 4d3b7e8

Browse files
committed
MsvcLinker: allow linking dynamically to Meson and MinGW-style named libraries
Fixes #122455
1 parent 291a31d commit 4d3b7e8

File tree

1 file changed

+35
-1
lines changed

1 file changed

+35
-1
lines changed

compiler/rustc_codegen_ssa/src/back/linker.rs

+35-1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ use rustc_middle::middle::exported_symbols;
1717
use rustc_middle::middle::exported_symbols::{ExportedSymbol, SymbolExportInfo, SymbolExportKind};
1818
use rustc_middle::ty::TyCtxt;
1919
use rustc_session::config::{self, CrateType, DebugInfo, LinkerPluginLto, Lto, OptLevel, Strip};
20+
use rustc_session::search_paths::PathKind;
2021
use rustc_session::Session;
2122
use rustc_target::spec::{Cc, LinkOutputKind, LinkerFlavor, Lld};
2223

@@ -784,6 +785,38 @@ pub struct MsvcLinker<'a> {
784785
sess: &'a Session,
785786
}
786787

788+
impl MsvcLinker<'_> {
789+
// FIXME this duplicates rustc_metadata::find_native_static_library,
790+
// as the Meson/MinGW suffix for import libraries can differ
791+
fn find_native_dynamic_library(name: &str, verbatim: bool, sess: &Session) -> OsString {
792+
let formats = if verbatim {
793+
vec![("".into(), "".into())]
794+
} else {
795+
// While the official naming convention for MSVC import libraries
796+
// is foo.lib...
797+
let os = (sess.target.staticlib_prefix.clone(), sess.target.staticlib_suffix.clone());
798+
// ... Meson follows the libfoo.dll.a convention to
799+
// disambiguate .a for static libraries
800+
let meson = ("lib".into(), ".dll.a".into());
801+
// and MinGW uses .a altogether
802+
let mingw = ("lib".into(), ".a".into());
803+
vec![os, meson, mingw]
804+
};
805+
806+
for path in sess.target_filesearch(PathKind::Native).search_paths() {
807+
for (prefix, suffix) in &formats {
808+
let test = path.join(format!("{prefix}{name}{suffix}"));
809+
if test.exists() {
810+
return OsString::from(test);
811+
}
812+
}
813+
}
814+
815+
// Allow the linker to find CRT libs itself
816+
OsString::from(format!("{}{}", name, if verbatim { "" } else { ".lib" }))
817+
}
818+
}
819+
787820
impl<'a> Linker for MsvcLinker<'a> {
788821
fn cmd(&mut self) -> &mut Command {
789822
&mut self.cmd
@@ -808,7 +841,8 @@ impl<'a> Linker for MsvcLinker<'a> {
808841
}
809842

810843
fn link_dylib_by_name(&mut self, name: &str, verbatim: bool, _as_needed: bool) {
811-
self.cmd.arg(format!("{}{}", name, if verbatim { "" } else { ".lib" }));
844+
let path = MsvcLinker::<'a>::find_native_dynamic_library(name, verbatim, self.sess);
845+
self.cmd.arg(path);
812846
}
813847

814848
fn link_staticlib_by_name(&mut self, name: &str, verbatim: bool, whole_archive: bool) {

0 commit comments

Comments
 (0)