diff --git a/lib/std/Build.zig b/lib/std/Build.zig index 4517ce75b0..257b7abef3 100644 --- a/lib/std/Build.zig +++ b/lib/std/Build.zig @@ -832,6 +832,8 @@ pub const LibraryOptions = struct { /// Can be set regardless of target. The `.manifest` file will be ignored /// if the target object format does not support embedded manifests. win32_manifest: ?LazyPath = null, + /// Win32 module definition file (.def). + win32_module_definition: ?LazyPath = null, }; pub fn addLibrary(b: *Build, options: LibraryOptions) *Step.Compile { @@ -846,6 +848,7 @@ pub fn addLibrary(b: *Build, options: LibraryOptions) *Step.Compile { .use_lld = options.use_lld, .zig_lib_dir = options.zig_lib_dir, .win32_manifest = options.win32_manifest, + .win32_module_definition = options.win32_module_definition, }); } diff --git a/lib/std/Build/Step/Compile.zig b/lib/std/Build/Step/Compile.zig index 8c3bb5c568..d9bbe844f6 100644 --- a/lib/std/Build/Step/Compile.zig +++ b/lib/std/Build/Step/Compile.zig @@ -79,6 +79,10 @@ rc_includes: std.zig.RcIncludes = .any, /// Set via options; intended to be read-only after that. win32_manifest: ?LazyPath = null, +/// (Windows) .def file to embed in the compilation (dll) +/// Set via options; intended to be read-only after that. +win32_module_definition: ?LazyPath = null, + installed_path: ?[]const u8, /// Base address for an executable image. @@ -284,6 +288,8 @@ pub const Options = struct { /// Can be set regardless of target. The `.manifest` file will be ignored /// if the target object format does not support embedded manifests. win32_manifest: ?LazyPath = null, + /// Win32 module definition file. + win32_module_definition: ?LazyPath = null, }; pub const Kind = enum { @@ -467,6 +473,13 @@ pub fn create(owner: *std.Build, options: Options) *Compile { compile.win32_manifest = lp.dupe(compile.step.owner); lp.addStepDependencies(&compile.step); } + if (compile.kind == .lib and compile.linkage != null and compile.linkage.? == .dynamic) { + // Building a Win32 DLL, check for win32 .def file. + if (options.win32_module_definition) |lp| { + compile.win32_module_definition = lp.dupe(compile.step.owner); + lp.addStepDependencies(&compile.step); + } + } } if (compile.kind == .lib) { @@ -1332,6 +1345,10 @@ fn getZigArgs(compile: *Compile, fuzz: bool) ![][]const u8 { try zig_args.append(manifest_file.getPath2(b, step)); } + if (compile.win32_module_definition) |module_file| { + try zig_args.append(module_file.getPath2(b, step)); + } + if (compile.image_base) |image_base| { try zig_args.append("--image-base"); try zig_args.append(b.fmt("0x{x}", .{image_base})); diff --git a/src/main.zig b/src/main.zig index a029272987..ed194b4767 100644 --- a/src/main.zig +++ b/src/main.zig @@ -1809,6 +1809,9 @@ fn buildOutputType( fatal("only one manifest file can be specified, found '{s}' after '{s}'", .{ arg, other }); } else manifest_file = arg; }, + .def => { + linker_module_definition_file = arg; + }, .assembly, .assembly_with_cpp, .c, .cpp, .h, .hpp, .hm, .hmm, .ll, .bc, .m, .mm => { dev.check(.c_compiler); try create_module.c_source_files.append(arena, .{ @@ -1834,7 +1837,7 @@ fn buildOutputType( fatal("found another zig file '{s}' after root source file '{s}'", .{ arg, other }); } else root_src_file = arg; }, - .def, .unknown => { + .unknown => { if (std.ascii.eqlIgnoreCase(".xml", fs.path.extension(arg))) { warn("embedded manifest files must have the extension '.manifest'", .{}); }