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_llvm | |
| 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_llvm')
| -rw-r--r-- | src/librustc_codegen_llvm/callee.rs | 7 | ||||
| -rw-r--r-- | src/librustc_codegen_llvm/consts.rs | 2 | ||||
| -rw-r--r-- | src/librustc_codegen_llvm/context.rs | 15 |
3 files changed, 19 insertions, 5 deletions
diff --git a/src/librustc_codegen_llvm/callee.rs b/src/librustc_codegen_llvm/callee.rs index 7b341651adf..ee6b28b3d1b 100644 --- a/src/librustc_codegen_llvm/callee.rs +++ b/src/librustc_codegen_llvm/callee.rs @@ -168,7 +168,12 @@ pub fn get_fn(cx: &CodegenCx<'ll, 'tcx>, instance: Instance<'tcx>) -> &'ll Value } } - if cx.use_dll_storage_attrs && tcx.is_dllimport_foreign_item(instance_def_id) { + // MinGW: For backward compatibility we rely on the linker to decide whether it + // should use dllimport for functions. + if cx.use_dll_storage_attrs + && tcx.is_dllimport_foreign_item(instance_def_id) + && tcx.sess.target.target.target_env != "gnu" + { unsafe { llvm::LLVMSetDLLStorageClass(llfn, llvm::DLLStorageClass::DllImport); } diff --git a/src/librustc_codegen_llvm/consts.rs b/src/librustc_codegen_llvm/consts.rs index 90887b760fb..5b9f131115b 100644 --- a/src/librustc_codegen_llvm/consts.rs +++ b/src/librustc_codegen_llvm/consts.rs @@ -281,7 +281,7 @@ impl CodegenCx<'ll, 'tcx> { // argument validation. debug_assert!( !(self.tcx.sess.opts.cg.linker_plugin_lto.enabled() - && self.tcx.sess.target.target.options.is_like_msvc + && self.tcx.sess.target.target.options.is_like_windows && self.tcx.sess.opts.cg.prefer_dynamic) ); diff --git a/src/librustc_codegen_llvm/context.rs b/src/librustc_codegen_llvm/context.rs index 21ba97d15a4..191a337cd56 100644 --- a/src/librustc_codegen_llvm/context.rs +++ b/src/librustc_codegen_llvm/context.rs @@ -217,7 +217,16 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> { // attributes in LLVM IR as well as native dependencies (in C these // correspond to `__declspec(dllimport)`). // - // Whenever a dynamic library is built by MSVC it must have its public + // LD (BFD) in MinGW mode can often correctly guess `dllexport` but + // relying on that can result in issues like #50176. + // LLD won't support that and expects symbols with proper attributes. + // Because of that we make MinGW target emit dllexport just like MSVC. + // When it comes to dllimport we use it for constants but for functions + // rely on the linker to do the right thing. Opposed to dllexport this + // task is easy for them (both LD and LLD) and allows us to easily use + // symbols from static libraries in shared libraries. + // + // Whenever a dynamic library is built on Windows it must have its public // interface specified by functions tagged with `dllexport` or otherwise // they're not available to be linked against. This poses a few problems // for the compiler, some of which are somewhat fundamental, but we use @@ -254,8 +263,8 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> { // this effect) by marking very little as `dllimport` and praying the // linker will take care of everything. Fixing this problem will likely // require adding a few attributes to Rust itself (feature gated at the - // start) and then strongly recommending static linkage on MSVC! - let use_dll_storage_attrs = tcx.sess.target.target.options.is_like_msvc; + // start) and then strongly recommending static linkage on Windows! + let use_dll_storage_attrs = tcx.sess.target.target.options.is_like_windows; let check_overflow = tcx.sess.overflow_checks(); |
