Skip to content

Commit

Permalink
MsvcLinker: allow linking dynamically to Meson and MinGW-style named …
Browse files Browse the repository at this point in the history
…libraries

Fixes #122455
  • Loading branch information
amyspark committed Apr 20, 2024
1 parent 291a31d commit 4d3b7e8
Showing 1 changed file with 35 additions and 1 deletion.
36 changes: 35 additions & 1 deletion compiler/rustc_codegen_ssa/src/back/linker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ use rustc_middle::middle::exported_symbols;
use rustc_middle::middle::exported_symbols::{ExportedSymbol, SymbolExportInfo, SymbolExportKind};
use rustc_middle::ty::TyCtxt;
use rustc_session::config::{self, CrateType, DebugInfo, LinkerPluginLto, Lto, OptLevel, Strip};
use rustc_session::search_paths::PathKind;
use rustc_session::Session;
use rustc_target::spec::{Cc, LinkOutputKind, LinkerFlavor, Lld};

Expand Down Expand Up @@ -784,6 +785,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
Expand All @@ -808,7 +841,8 @@ impl<'a> Linker for MsvcLinker<'a> {
}

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

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

0 comments on commit 4d3b7e8

Please sign in to comment.