From 5af318bd563345c0205dfd1060e90c0368054dc6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hugo=20Beauz=C3=A9e-Luyssen?= Date: Mon, 27 May 2019 15:51:44 +0200 Subject: [PATCH] rustc: codegen: Build import library for all windows targets So far it is assumed that using a DLL as a -l parameter argument is ok, but the assumption doesn't hold when compiling the native code with llvm. In which case, an import library is required, so let's build one This also requires the cargo counterpart to add the import library in the stamp files, at least when compiling libstd. Otherwise, the files don't get uplifted --- src/bootstrap/compile.rs | 1 + src/librustc_codegen_ssa/back/linker.rs | 20 +++++++++++++++++++ .../output-type-permutations/Makefile | 6 +++--- 3 files changed, 24 insertions(+), 3 deletions(-) diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index 9ced04a5c808..60138e701bdb 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -1126,6 +1126,7 @@ pub fn run_cargo(builder: &Builder<'_>, // Skip files like executables if !filename.ends_with(".rlib") && !filename.ends_with(".lib") && + !filename.ends_with(".a") && !is_dylib(&filename) && !(is_check && filename.ends_with(".rmeta")) { continue; diff --git a/src/librustc_codegen_ssa/back/linker.rs b/src/librustc_codegen_ssa/back/linker.rs index 882963f9174e..cb8870d0be90 100644 --- a/src/librustc_codegen_ssa/back/linker.rs +++ b/src/librustc_codegen_ssa/back/linker.rs @@ -368,6 +368,26 @@ impl<'a> Linker for GccLinker<'a> { } } else { self.cmd.arg("-shared"); + if self.sess.target.target.options.is_like_windows { + // The output filename already contains `dll_suffix` so + // the resulting import library will have a name in the + // form of libfoo.dll.a + let implib_name = out_filename + .file_name() + .and_then(|file| file.to_str()) + .map(|file| format!("{}{}{}", + self.sess.target.target.options.staticlib_prefix, + file, + self.sess.target.target.options.staticlib_suffix)); + if let Some(implib_name) = implib_name { + let implib = out_filename + .parent() + .map(|dir| dir.join(&implib_name)); + if let Some(implib) = implib { + self.linker_arg(&format!("--out-implib,{}", (*implib).to_str().unwrap())); + } + } + } } } diff --git a/src/test/run-make-fulldeps/output-type-permutations/Makefile b/src/test/run-make-fulldeps/output-type-permutations/Makefile index c2715027bc1f..ffd3e6da2563 100644 --- a/src/test/run-make-fulldeps/output-type-permutations/Makefile +++ b/src/test/run-make-fulldeps/output-type-permutations/Makefile @@ -5,7 +5,7 @@ all: $(call REMOVE_RLIBS,bar) $(call REMOVE_DYLIBS,bar) rm $(call STATICLIB,bar) - rm -f $(TMPDIR)/bar.{dll.exp,dll.lib,pdb} + rm -f $(TMPDIR)/{lib,}bar.{dll.exp,dll.lib,pdb,dll.a} # Check that $(TMPDIR) is empty. [ "$$(ls -1 $(TMPDIR) | wc -l)" -eq "0" ] @@ -78,8 +78,8 @@ all: rm $(TMPDIR)/$(call BIN,foo) $(RUSTC) foo.rs --crate-type=dylib --emit=link=$(TMPDIR)/$(call BIN,foo) rm $(TMPDIR)/$(call BIN,foo) - rm -f $(TMPDIR)/foo.{dll.exp,dll.lib,pdb} - [ "$$(ls -1 $(TMPDIR) | wc -l)" -eq "0" ] + rm -f $(TMPDIR)/{lib,}foo.{dll.exp,dll.lib,pdb,dll.a,exe.lib} + [ "$$(ls -1 $(TMPDIR) | wc -l)" -eq "0" ] || (ls -1 $(TMPDIR) && exit 1) $(RUSTC) foo.rs --crate-type=staticlib -o $(TMPDIR)/foo rm $(TMPDIR)/foo