From acbad20a6865f26842a0956da87d5f077faa8d15 Mon Sep 17 00:00:00 2001 From: Quinton Miller Date: Sun, 12 Dec 2021 12:10:24 +0800 Subject: [PATCH 1/2] Add `dllimport` storage class to external lib variables on Windows --- src/compiler/crystal/codegen/codegen.cr | 3 +++ src/empty.cr | 2 +- src/lib_c.cr | 2 +- src/llvm/enums.cr | 14 ++++++++++++-- src/llvm/lib_llvm.cr | 2 ++ src/llvm/value_methods.cr | 8 ++++++++ 6 files changed, 27 insertions(+), 4 deletions(-) diff --git a/src/compiler/crystal/codegen/codegen.cr b/src/compiler/crystal/codegen/codegen.cr index c4b0d6959bf5..e881f2365e57 100644 --- a/src/compiler/crystal/codegen/codegen.cr +++ b/src/compiler/crystal/codegen/codegen.cr @@ -1450,6 +1450,9 @@ module Crystal unless var var = llvm_mod.globals.add(llvm_c_return_type(type), name) var.linkage = LLVM::Linkage::External + if @program.has_flag?("win32") && @program.has_flag?("preview_dll") + var.dll_storage_class = LLVM::DLLStorageClass::DLLImport + end var.thread_local = thread_local end var diff --git a/src/empty.cr b/src/empty.cr index 35f988afb583..22de59dcbb57 100644 --- a/src/empty.cr +++ b/src/empty.cr @@ -1,7 +1,7 @@ require "primitives" {% if flag?(:win32) %} - @[Link("libcmt")] # For `mainCRTStartup` + @[Link({{ flag?(:preview_dll) ? "msvcrt" : "libcmt" }})] # For `mainCRTStartup` {% end %} lib LibCrystalMain @[Raises] diff --git a/src/lib_c.cr b/src/lib_c.cr index 61d2fdf03b3b..343f2c56a42b 100644 --- a/src/lib_c.cr +++ b/src/lib_c.cr @@ -1,5 +1,5 @@ {% if flag?(:win32) %} - @[Link("libcmt")] + @[Link({{ flag?(:preview_dll) ? "msvcrt" : "libcmt" }})] {% end %} lib LibC alias Char = UInt8 diff --git a/src/llvm/enums.cr b/src/llvm/enums.cr index 0b6d0b035c2c..63e1c818c0e1 100644 --- a/src/llvm/enums.cr +++ b/src/llvm/enums.cr @@ -220,8 +220,8 @@ module LLVM Appending Internal Private - DLLImport - DLLExport + DLLImport # obsolete + DLLExport # obsolete ExternalWeak Ghost Common @@ -229,6 +229,16 @@ module LLVM LinkerPrivateWeak end + enum DLLStorageClass + Default + + # Function to be imported from DLL. + DLLImport + + # Function to be accessible from DLL. + DLLExport + end + enum IntPredicate EQ = 32 NE diff --git a/src/llvm/lib_llvm.cr b/src/llvm/lib_llvm.cr index 9a93274c1294..15eb86866a86 100644 --- a/src/llvm/lib_llvm.cr +++ b/src/llvm/lib_llvm.cr @@ -255,6 +255,8 @@ lib LibLLVM fun get_initializer = LLVMGetInitializer(global_var : ValueRef) : ValueRef fun set_linkage = LLVMSetLinkage(global : ValueRef, linkage : LLVM::Linkage) fun get_linkage = LLVMGetLinkage(global : ValueRef) : LLVM::Linkage + fun get_dll_storage_class = LLVMGetDLLStorageClass(global : ValueRef) : LLVM::DLLStorageClass + fun set_dll_storage_class = LLVMSetDLLStorageClass(global : ValueRef, storage_class : LLVM::DLLStorageClass) fun set_metadata = LLVMSetMetadata(value : ValueRef, kind_id : UInt32, node : ValueRef) fun set_target = LLVMSetTarget(mod : ModuleRef, triple : UInt8*) fun set_thread_local = LLVMSetThreadLocal(global_var : ValueRef, is_thread_local : Int32) diff --git a/src/llvm/value_methods.cr b/src/llvm/value_methods.cr index 30a2e2bb7df1..26f288b8dbf3 100644 --- a/src/llvm/value_methods.cr +++ b/src/llvm/value_methods.cr @@ -55,6 +55,14 @@ module LLVM::ValueMethods LibLLVM.get_linkage(self) end + def dll_storage_class=(storage_class) + LibLLVM.set_dll_storage_class(self, storage_class) + end + + def dll_storage_class + LibLLVM.get_dll_storage_class(self) + end + def call_convention=(call_convention) LibLLVM.set_instruction_call_convention(self, call_convention) end From 3c10083a89709669628827890018dba22c576d2e Mon Sep 17 00:00:00 2001 From: Quinton Miller Date: Sun, 12 Dec 2021 17:00:34 +0800 Subject: [PATCH 2/2] no need for getter --- src/llvm/lib_llvm.cr | 1 - src/llvm/value_methods.cr | 4 ---- 2 files changed, 5 deletions(-) diff --git a/src/llvm/lib_llvm.cr b/src/llvm/lib_llvm.cr index 15eb86866a86..f633a9cf8277 100644 --- a/src/llvm/lib_llvm.cr +++ b/src/llvm/lib_llvm.cr @@ -255,7 +255,6 @@ lib LibLLVM fun get_initializer = LLVMGetInitializer(global_var : ValueRef) : ValueRef fun set_linkage = LLVMSetLinkage(global : ValueRef, linkage : LLVM::Linkage) fun get_linkage = LLVMGetLinkage(global : ValueRef) : LLVM::Linkage - fun get_dll_storage_class = LLVMGetDLLStorageClass(global : ValueRef) : LLVM::DLLStorageClass fun set_dll_storage_class = LLVMSetDLLStorageClass(global : ValueRef, storage_class : LLVM::DLLStorageClass) fun set_metadata = LLVMSetMetadata(value : ValueRef, kind_id : UInt32, node : ValueRef) fun set_target = LLVMSetTarget(mod : ModuleRef, triple : UInt8*) diff --git a/src/llvm/value_methods.cr b/src/llvm/value_methods.cr index 26f288b8dbf3..9c6985ae06f7 100644 --- a/src/llvm/value_methods.cr +++ b/src/llvm/value_methods.cr @@ -59,10 +59,6 @@ module LLVM::ValueMethods LibLLVM.set_dll_storage_class(self, storage_class) end - def dll_storage_class - LibLLVM.get_dll_storage_class(self) - end - def call_convention=(call_convention) LibLLVM.set_instruction_call_convention(self, call_convention) end