diff options
| author | Mateusz Mikuła <mati865@gmail.com> | 2020-05-07 11:52:21 +0200 |
|---|---|---|
| committer | Mateusz Mikuła <mati865@gmail.com> | 2020-07-29 14:19:57 +0200 |
| commit | db9a84a1af8bd5cea3738833c0e8cd4e1bee3f7d (patch) | |
| tree | 0ecc3a3b448b12cbc53297825fc8c7295671b337 /src/librustc_codegen_ssa/back | |
| parent | 6ee1b62c811a6eb68d6db6dfb91f66a49956749b (diff) | |
| download | rust-db9a84a1af8bd5cea3738833c0e8cd4e1bee3f7d.tar.gz rust-db9a84a1af8bd5cea3738833c0e8cd4e1bee3f7d.zip | |
MinGW: emit dllexport/dllimport by rustc
This fixes various cases where LD could not guess dllexport correctly and greatly improves compatibility with LLD which is not going to support linker scripts anytime soon
Diffstat (limited to 'src/librustc_codegen_ssa/back')
| -rw-r--r-- | src/librustc_codegen_ssa/back/linker.rs | 23 | ||||
| -rw-r--r-- | src/librustc_codegen_ssa/back/write.rs | 4 |
2 files changed, 23 insertions, 4 deletions
diff --git a/src/librustc_codegen_ssa/back/linker.rs b/src/librustc_codegen_ssa/back/linker.rs index e64aafa599f..aba4991c295 100644 --- a/src/librustc_codegen_ssa/back/linker.rs +++ b/src/librustc_codegen_ssa/back/linker.rs @@ -523,8 +523,9 @@ impl<'a> Linker for GccLinker<'a> { return; } + let is_windows = self.sess.target.target.options.is_like_windows; let mut arg = OsString::new(); - let path = tmpdir.join("list"); + let path = tmpdir.join(if is_windows { "list.def" } else { "list" }); debug!("EXPORTED SYMBOLS:"); @@ -540,6 +541,21 @@ impl<'a> Linker for GccLinker<'a> { if let Err(e) = res { self.sess.fatal(&format!("failed to write lib.def file: {}", e)); } + } else if is_windows { + let res: io::Result<()> = try { + let mut f = BufWriter::new(File::create(&path)?); + + // .def file similar to MSVC one but without LIBRARY section + // because LD doesn't like when it's empty + writeln!(f, "EXPORTS")?; + for symbol in self.info.exports[&crate_type].iter() { + debug!(" _{}", symbol); + writeln!(f, " {}", symbol)?; + } + }; + if let Err(e) = res { + self.sess.fatal(&format!("failed to write list.def file: {}", e)); + } } else { // Write an LD version script let res: io::Result<()> = try { @@ -573,7 +589,10 @@ impl<'a> Linker for GccLinker<'a> { if !self.is_ld { arg.push("-Wl,") } - arg.push("--version-script="); + // Both LD and LLD accept export list in *.def file form, there are no flags required + if !is_windows { + arg.push("--version-script=") + } } arg.push(&path); diff --git a/src/librustc_codegen_ssa/back/write.rs b/src/librustc_codegen_ssa/back/write.rs index 23e0b9344ec..b0fae566a5a 100644 --- a/src/librustc_codegen_ssa/back/write.rs +++ b/src/librustc_codegen_ssa/back/write.rs @@ -1846,11 +1846,11 @@ fn msvc_imps_needed(tcx: TyCtxt<'_>) -> bool { // something is wrong with commandline arg validation. assert!( !(tcx.sess.opts.cg.linker_plugin_lto.enabled() - && tcx.sess.target.target.options.is_like_msvc + && tcx.sess.target.target.options.is_like_windows && tcx.sess.opts.cg.prefer_dynamic) ); - tcx.sess.target.target.options.is_like_msvc && + tcx.sess.target.target.options.is_like_windows && tcx.sess.crate_types().iter().any(|ct| *ct == CrateType::Rlib) && // ThinLTO can't handle this workaround in all cases, so we don't // emit the `__imp_` symbols. Instead we make them unnecessary by disallowing |
