diff --git a/src/Compilation.zig b/src/Compilation.zig index 84dd273947..0914685c77 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -1231,7 +1231,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { break :blk lm; } else default_link_mode; - const dll_export_fns = if (options.dll_export_fns) |explicit| explicit else is_dyn_lib or options.rdynamic; + const dll_export_fns = options.dll_export_fns orelse (is_dyn_lib or options.rdynamic); const libc_dirs = try detectLibCIncludeDirs( arena, diff --git a/src/Module.zig b/src/Module.zig index 3ae61c264f..3577115ded 100644 --- a/src/Module.zig +++ b/src/Module.zig @@ -6529,3 +6529,7 @@ pub fn addGlobalAssembly(mod: *Module, decl_index: Decl.Index, source: []const u mod.global_assembly.putAssumeCapacityNoClobber(decl_index, duped_source); } + +pub fn wantDllExports(mod: Module) bool { + return mod.comp.bin_file.options.dll_export_fns and mod.getTarget().os.tag == .windows; +} diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index 0898c8fe87..d50b463606 100644 --- a/src/codegen/llvm.zig +++ b/src/codegen/llvm.zig @@ -1103,6 +1103,7 @@ pub const Object = struct { } llvm_global.setUnnamedAddr(.False); llvm_global.setLinkage(.External); + if (module.wantDllExports()) llvm_global.setDLLStorageClass(.Default); if (self.di_map.get(decl)) |di_node| { if (try decl.isFunction()) { const di_func = @ptrCast(*llvm.DISubprogram, di_node); @@ -1128,6 +1129,7 @@ pub const Object = struct { const exp_name = exports[0].options.name; llvm_global.setValueName2(exp_name.ptr, exp_name.len); llvm_global.setUnnamedAddr(.False); + if (module.wantDllExports()) llvm_global.setDLLStorageClass(.DLLExport); if (self.di_map.get(decl)) |di_node| { if (try decl.isFunction()) { const di_func = @ptrCast(*llvm.DISubprogram, di_node); @@ -1187,6 +1189,7 @@ pub const Object = struct { defer module.gpa.free(fqn); llvm_global.setValueName2(fqn.ptr, fqn.len); llvm_global.setLinkage(.Internal); + if (module.wantDllExports()) llvm_global.setDLLStorageClass(.Default); llvm_global.setUnnamedAddr(.True); if (decl.val.castTag(.variable)) |variable| { const single_threaded = module.comp.bin_file.options.single_threaded; diff --git a/src/codegen/llvm/bindings.zig b/src/codegen/llvm/bindings.zig index 9daa96eb8f..38f794cfda 100644 --- a/src/codegen/llvm/bindings.zig +++ b/src/codegen/llvm/bindings.zig @@ -223,6 +223,9 @@ pub const Value = opaque { pub const setInitializer = LLVMSetInitializer; extern fn LLVMSetInitializer(GlobalVar: *const Value, ConstantVal: *const Value) void; + pub const setDLLStorageClass = LLVMSetDLLStorageClass; + extern fn LLVMSetDLLStorageClass(Global: *const Value, Class: DLLStorageClass) void; + pub const addCase = LLVMAddCase; extern fn LLVMAddCase(Switch: *const Value, OnVal: *const Value, Dest: *const BasicBlock) void; @@ -1482,6 +1485,12 @@ pub const CallAttr = enum(c_int) { AlwaysInline, }; +pub const DLLStorageClass = enum(c_uint) { + Default, + DLLImport, + DLLExport, +}; + pub const address_space = struct { pub const default: c_uint = 0;