about summary refs log tree commit diff
path: root/src/librustc_codegen_ssa/back
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2020-07-29 13:58:19 +0000
committerbors <bors@rust-lang.org>2020-07-29 13:58:19 +0000
commit584e83dd5ae7a75b8214560c22eafbcfe153caa6 (patch)
treeeb24aacddc69ffba99306c244094deaaee69aef6 /src/librustc_codegen_ssa/back
parent06e7b93f6a2a3eeaf80fd6a9a3ef7b180bb5d778 (diff)
parent87abd656dabdb97758413b7f4be5bda9be71e26e (diff)
downloadrust-584e83dd5ae7a75b8214560c22eafbcfe153caa6.tar.gz
rust-584e83dd5ae7a75b8214560c22eafbcfe153caa6.zip
Auto merge of #72049 - mati865:mingw-lld, r=petrochenkov
MinGW: enable dllexport/dllimport

Fixes (only when using LLD) https://github.com/rust-lang/rust/issues/50176
Fixes https://github.com/rust-lang/rust/issues/72319

This makes `windows-gnu` on pair with `windows-msvc` when it comes to symbol exporting.
For MinGW it means both good things like correctly working dllimport/dllexport, ability to link with LLD and bad things like https://github.com/rust-lang/rust/issues/27438.

Not sure but maybe this should land behind unstable compiler option (`-Z`) or environment variable?
Diffstat (limited to 'src/librustc_codegen_ssa/back')
-rw-r--r--src/librustc_codegen_ssa/back/linker.rs23
-rw-r--r--src/librustc_codegen_ssa/back/write.rs4
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 d1ae9e37269..f9a782af24c 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