diff --git a/compiler/rustc_codegen_ssa/src/back/linker.rs b/compiler/rustc_codegen_ssa/src/back/linker.rs index e505543b27ca7..e0bd7a33f7373 100644 --- a/compiler/rustc_codegen_ssa/src/back/linker.rs +++ b/compiler/rustc_codegen_ssa/src/back/linker.rs @@ -439,7 +439,10 @@ impl<'a> Linker for GccLinker<'a> { } } self.hint_dynamic(); - self.cmd.arg(format!("-l{}{}", if verbatim { ":" } else { "" }, lib)); + self.cmd.arg(format!( + "-l{}{lib}", + if verbatim && self.sess.target.linker_is_gnu { ":" } else { "" }, + )); if !as_needed { if self.sess.target.is_like_osx { // See above FIXME comment @@ -450,7 +453,10 @@ impl<'a> Linker for GccLinker<'a> { } fn link_staticlib(&mut self, lib: &str, verbatim: bool) { self.hint_static(); - self.cmd.arg(format!("-l{}{}", if verbatim { ":" } else { "" }, lib)); + self.cmd.arg(format!( + "-l{}{lib}", + if verbatim && self.sess.target.linker_is_gnu { ":" } else { "" }, + )); } fn link_rlib(&mut self, lib: &Path) { self.hint_static(); @@ -504,10 +510,10 @@ impl<'a> Linker for GccLinker<'a> { self.hint_static(); let target = &self.sess.target; if !target.is_like_osx { - self.linker_arg("--whole-archive").cmd.arg(format!( - "-l{}{}", - if verbatim { ":" } else { "" }, - lib + self.linker_arg("--whole-archive"); + self.cmd.arg(format!( + "-l{}{lib}", + if verbatim && self.sess.target.linker_is_gnu { ":" } else { "" }, )); self.linker_arg("--no-whole-archive"); } else { diff --git a/compiler/rustc_metadata/src/native_libs.rs b/compiler/rustc_metadata/src/native_libs.rs index cc33ad07db605..963ebe0d0b9f2 100644 --- a/compiler/rustc_metadata/src/native_libs.rs +++ b/compiler/rustc_metadata/src/native_libs.rs @@ -33,28 +33,25 @@ pub fn find_native_static_library( search_paths: &[PathBuf], sess: &Session, ) -> PathBuf { - let verbatim = verbatim.unwrap_or(false); - // On Windows, static libraries sometimes show up as libfoo.a and other - // times show up as foo.lib - let oslibname = if verbatim { - name.to_string() + let formats = if verbatim.unwrap_or(false) { + vec![("".into(), "".into())] } else { - format!("{}{}{}", sess.target.staticlib_prefix, name, sess.target.staticlib_suffix) + 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 unixlibname = format!("lib{}.a", name); for path in search_paths { - let test = path.join(&oslibname); - if test.exists() { - return test; - } - if oslibname != unixlibname { - let test = path.join(&unixlibname); + for (prefix, suffix) in &formats { + let test = path.join(format!("{}{}{}", prefix, name, suffix)); if test.exists() { return test; } } } + sess.emit_fatal(MissingNativeLibrary { libname: name }); } diff --git a/src/test/run-make/native-link-modifier-verbatim-linker/Makefile b/src/test/run-make/native-link-modifier-verbatim-linker/Makefile new file mode 100644 index 0000000000000..e56e1e94ec5b1 --- /dev/null +++ b/src/test/run-make/native-link-modifier-verbatim-linker/Makefile @@ -0,0 +1,15 @@ +# ignore-cross-compile +# ignore-macos + +include ../../run-make-fulldeps/tools.mk + +all: + # Verbatim allows specify precise name. + $(RUSTC) local_native_dep.rs --crate-type=staticlib -o $(TMPDIR)/local_some_strange_name.ext + $(RUSTC) main.rs -Zunstable-options -l static:+verbatim=local_some_strange_name.ext + + # With verbatim any other name cannot be used (local). + $(RUSTC) local_native_dep.rs --crate-type=staticlib -o $(TMPDIR)/liblocal_native_dep.a + $(RUSTC) local_native_dep.rs --crate-type=staticlib -o $(TMPDIR)/local_native_dep.a + $(RUSTC) local_native_dep.rs --crate-type=staticlib -o $(TMPDIR)/local_native_dep.lib + $(RUSTC) main.rs -Zunstable-options -l static:+verbatim=local_native_dep 2>&1 | $(CGREP) "local_native_dep" diff --git a/src/test/run-make/native-link-modifier-verbatim-linker/local_native_dep.rs b/src/test/run-make/native-link-modifier-verbatim-linker/local_native_dep.rs new file mode 100644 index 0000000000000..59b6c92d29363 --- /dev/null +++ b/src/test/run-make/native-link-modifier-verbatim-linker/local_native_dep.rs @@ -0,0 +1,4 @@ +#[no_mangle] +pub fn local_native_f() -> i32 { + return 0; +} diff --git a/src/test/run-make/native-link-modifier-verbatim-linker/main.rs b/src/test/run-make/native-link-modifier-verbatim-linker/main.rs new file mode 100644 index 0000000000000..71b73a489c767 --- /dev/null +++ b/src/test/run-make/native-link-modifier-verbatim-linker/main.rs @@ -0,0 +1,9 @@ +extern "C" { + fn local_native_f() -> i32; +} + +pub fn main() { + unsafe { + assert!(local_native_f() == 0); + }; +} diff --git a/src/test/run-make/native-link-modifier-verbatim-rustc/Makefile b/src/test/run-make/native-link-modifier-verbatim-rustc/Makefile new file mode 100644 index 0000000000000..1093b1cd3694d --- /dev/null +++ b/src/test/run-make/native-link-modifier-verbatim-rustc/Makefile @@ -0,0 +1,12 @@ +include ../../run-make-fulldeps/tools.mk + +all: + # Verbatim allows specify precise name. + $(RUSTC) upstream_native_dep.rs --crate-type=staticlib -o $(TMPDIR)/upstream_some_strange_name.ext + $(RUSTC) rust_dep.rs -Zunstable-options -l static:+verbatim=upstream_some_strange_name.ext --crate-type rlib + + # With verbatim any other name cannot be used (upstream). + $(RUSTC) upstream_native_dep.rs --crate-type=staticlib -o $(TMPDIR)/libupstream_native_dep.a + $(RUSTC) upstream_native_dep.rs --crate-type=staticlib -o $(TMPDIR)/upstream_native_dep.a + $(RUSTC) upstream_native_dep.rs --crate-type=staticlib -o $(TMPDIR)/upstream_native_dep.lib + $(RUSTC) rust_dep.rs -Zunstable-options -l static:+verbatim=upstream_native_dep --crate-type rlib 2>&1 | $(CGREP) "upstream_native_dep" diff --git a/src/test/run-make/native-link-modifier-verbatim-rustc/rust_dep.rs b/src/test/run-make/native-link-modifier-verbatim-rustc/rust_dep.rs new file mode 100644 index 0000000000000..e9517218e0dbe --- /dev/null +++ b/src/test/run-make/native-link-modifier-verbatim-rustc/rust_dep.rs @@ -0,0 +1,9 @@ +extern "C" { + fn upstream_native_f() -> i32; +} + +pub fn rust_dep() { + unsafe { + assert!(upstream_native_f() == 0); + } +} diff --git a/src/test/run-make/native-link-modifier-verbatim-rustc/upstream_native_dep.rs b/src/test/run-make/native-link-modifier-verbatim-rustc/upstream_native_dep.rs new file mode 100644 index 0000000000000..8396862333dc0 --- /dev/null +++ b/src/test/run-make/native-link-modifier-verbatim-rustc/upstream_native_dep.rs @@ -0,0 +1,4 @@ +#[no_mangle] +pub fn upstream_native_f() -> i32 { + return 0; +}