about summary refs log tree commit diff
diff options
context:
space:
mode:
authorVadim Petrochenkov <vadim.petrochenkov@gmail.com>2024-08-22 01:56:20 +0300
committerVadim Petrochenkov <vadim.petrochenkov@gmail.com>2024-08-27 22:13:31 +0300
commit05bd36de5068c8c34a404594926af268e5f4cb13 (patch)
treef25f2c997da53f2d2014232368d63d6dd653376c
parenta1c36c6ae9e6036b89e4c4b9cec2ce2e375b2a85 (diff)
downloadrust-05bd36de5068c8c34a404594926af268e5f4cb13.tar.gz
rust-05bd36de5068c8c34a404594926af268e5f4cb13.zip
linker: Better support alternative static library naming on MSVC
Previously `libname.a` naming was supported as a fallback when producing rlibs, but not when producing executables or dynamic libraries
-rw-r--r--compiler/rustc_codegen_ssa/src/back/linker.rs14
-rw-r--r--tests/run-make/native-lib-alt-naming/native.rs2
-rw-r--r--tests/run-make/native-lib-alt-naming/rmake.rs15
-rw-r--r--tests/run-make/native-lib-alt-naming/rust.rs1
4 files changed, 28 insertions, 4 deletions
diff --git a/compiler/rustc_codegen_ssa/src/back/linker.rs b/compiler/rustc_codegen_ssa/src/back/linker.rs
index fbab988a32b..cb266247e0d 100644
--- a/compiler/rustc_codegen_ssa/src/back/linker.rs
+++ b/compiler/rustc_codegen_ssa/src/back/linker.rs
@@ -7,7 +7,7 @@ use std::{env, iter, mem, str};
 
 use cc::windows_registry;
 use rustc_hir::def_id::{CrateNum, LOCAL_CRATE};
-use rustc_metadata::find_native_static_library;
+use rustc_metadata::{find_native_static_library, try_find_native_static_library};
 use rustc_middle::bug;
 use rustc_middle::middle::dependency_format::Linkage;
 use rustc_middle::middle::exported_symbols;
@@ -891,9 +891,15 @@ impl<'a> Linker for MsvcLinker<'a> {
     }
 
     fn link_staticlib_by_name(&mut self, name: &str, verbatim: bool, whole_archive: bool) {
-        let prefix = if whole_archive { "/WHOLEARCHIVE:" } else { "" };
-        let suffix = if verbatim { "" } else { ".lib" };
-        self.link_arg(format!("{prefix}{name}{suffix}"));
+        // On MSVC-like targets rustc supports static libraries using alternative naming
+        // scheme (`libfoo.a`) unsupported by linker, search for such libraries manually.
+        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}"));
+        }
     }
 
     fn link_staticlib_by_path(&mut self, path: &Path, whole_archive: bool) {
diff --git a/tests/run-make/native-lib-alt-naming/native.rs b/tests/run-make/native-lib-alt-naming/native.rs
new file mode 100644
index 00000000000..6c869e74cd2
--- /dev/null
+++ b/tests/run-make/native-lib-alt-naming/native.rs
@@ -0,0 +1,2 @@
+#[no_mangle]
+pub extern "C" fn native_lib_alt_naming() {}
diff --git a/tests/run-make/native-lib-alt-naming/rmake.rs b/tests/run-make/native-lib-alt-naming/rmake.rs
new file mode 100644
index 00000000000..d1ea0fc8687
--- /dev/null
+++ b/tests/run-make/native-lib-alt-naming/rmake.rs
@@ -0,0 +1,15 @@
+// On MSVC the alternative naming format for static libraries (`libfoo.a`) is accepted in addition
+// to the default format (`foo.lib`).
+
+//REMOVE@ only-msvc
+
+use run_make_support::rustc;
+
+fn main() {
+    // Prepare the native library.
+    rustc().input("native.rs").crate_type("staticlib").output("libnative.a").run();
+
+    // Try to link to it from both a rlib and a bin.
+    rustc().input("rust.rs").crate_type("rlib").arg("-lstatic=native").run();
+    rustc().input("rust.rs").crate_type("bin").arg("-lstatic=native").run();
+}
diff --git a/tests/run-make/native-lib-alt-naming/rust.rs b/tests/run-make/native-lib-alt-naming/rust.rs
new file mode 100644
index 00000000000..da0f5d925d1
--- /dev/null
+++ b/tests/run-make/native-lib-alt-naming/rust.rs
@@ -0,0 +1 @@
+pub fn main() {}