authorgravatar for anthonyem@gmail.comantme0 <anthonyem@gmail.com> 2026-02-08 18:48:54+01:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-02-09 07:58:13+01:00
logfb18f2096aaff3a26c309da635472a2fb8b303cd
tree83957d3a1926e44f14b6351b6338dd032500f39c
parentf061c0dc2851e5fab34dca1991ebe64cfd156bd5

Allow build.zig scripts to define module definition files (.def) when building win32 dlls.


3 files changed, 24 insertions(+), 1 deletions(-)

lib/std/Build.zig+3
...@@ -832,6 +832,8 @@ pub const LibraryOptions = struct {...@@ -832,6 +832,8 @@ pub const LibraryOptions = struct {
832 /// Can be set regardless of target. The `.manifest` file will be ignored832 /// Can be set regardless of target. The `.manifest` file will be ignored
833 /// if the target object format does not support embedded manifests.833 /// if the target object format does not support embedded manifests.
834 win32_manifest: ?LazyPath = null,834 win32_manifest: ?LazyPath = null,
835 /// Win32 module definition file (.def).
836 win32_module_definition: ?LazyPath = null,
835};837};
836838
837pub fn addLibrary(b: *Build, options: LibraryOptions) *Step.Compile {839pub fn addLibrary(b: *Build, options: LibraryOptions) *Step.Compile {
...@@ -846,6 +848,7 @@ pub fn addLibrary(b: *Build, options: LibraryOptions) *Step.Compile {...@@ -846,6 +848,7 @@ pub fn addLibrary(b: *Build, options: LibraryOptions) *Step.Compile {
846 .use_lld = options.use_lld,848 .use_lld = options.use_lld,
847 .zig_lib_dir = options.zig_lib_dir,849 .zig_lib_dir = options.zig_lib_dir,
848 .win32_manifest = options.win32_manifest,850 .win32_manifest = options.win32_manifest,
851 .win32_module_definition = options.win32_module_definition,
849 });852 });
850}853}
851854
lib/std/Build/Step/Compile.zig+17
...@@ -79,6 +79,10 @@ rc_includes: std.zig.RcIncludes = .any,...@@ -79,6 +79,10 @@ rc_includes: std.zig.RcIncludes = .any,
79/// Set via options; intended to be read-only after that.79/// Set via options; intended to be read-only after that.
80win32_manifest: ?LazyPath = null,80win32_manifest: ?LazyPath = null,
8181
82/// (Windows) .def file to embed in the compilation (dll)
83/// Set via options; intended to be read-only after that.
84win32_module_definition: ?LazyPath = null,
85
82installed_path: ?[]const u8,86installed_path: ?[]const u8,
8387
84/// Base address for an executable image.88/// Base address for an executable image.
...@@ -284,6 +288,8 @@ pub const Options = struct {...@@ -284,6 +288,8 @@ pub const Options = struct {
284 /// Can be set regardless of target. The `.manifest` file will be ignored288 /// Can be set regardless of target. The `.manifest` file will be ignored
285 /// if the target object format does not support embedded manifests.289 /// if the target object format does not support embedded manifests.
286 win32_manifest: ?LazyPath = null,290 win32_manifest: ?LazyPath = null,
291 /// Win32 module definition file.
292 win32_module_definition: ?LazyPath = null,
287};293};
288294
289pub const Kind = enum {295pub const Kind = enum {
...@@ -467,6 +473,13 @@ pub fn create(owner: *std.Build, options: Options) *Compile {...@@ -467,6 +473,13 @@ pub fn create(owner: *std.Build, options: Options) *Compile {
467 compile.win32_manifest = lp.dupe(compile.step.owner);473 compile.win32_manifest = lp.dupe(compile.step.owner);
468 lp.addStepDependencies(&compile.step);474 lp.addStepDependencies(&compile.step);
469 }475 }
476 if (compile.kind == .lib and compile.linkage != null and compile.linkage.? == .dynamic) {
477 // Building a Win32 DLL, check for win32 .def file.
478 if (options.win32_module_definition) |lp| {
479 compile.win32_module_definition = lp.dupe(compile.step.owner);
480 lp.addStepDependencies(&compile.step);
481 }
482 }
470 }483 }
471484
472 if (compile.kind == .lib) {485 if (compile.kind == .lib) {
...@@ -1332,6 +1345,10 @@ fn getZigArgs(compile: *Compile, fuzz: bool) ![][]const u8 {...@@ -1332,6 +1345,10 @@ fn getZigArgs(compile: *Compile, fuzz: bool) ![][]const u8 {
1332 try zig_args.append(manifest_file.getPath2(b, step));1345 try zig_args.append(manifest_file.getPath2(b, step));
1333 }1346 }
13341347
1348 if (compile.win32_module_definition) |module_file| {
1349 try zig_args.append(module_file.getPath2(b, step));
1350 }
1351
1335 if (compile.image_base) |image_base| {1352 if (compile.image_base) |image_base| {
1336 try zig_args.append("--image-base");1353 try zig_args.append("--image-base");
1337 try zig_args.append(b.fmt("0x{x}", .{image_base}));1354 try zig_args.append(b.fmt("0x{x}", .{image_base}));
src/main.zig+4-1
...@@ -1809,6 +1809,9 @@ fn buildOutputType(...@@ -1809,6 +1809,9 @@ fn buildOutputType(
1809 fatal("only one manifest file can be specified, found '{s}' after '{s}'", .{ arg, other });1809 fatal("only one manifest file can be specified, found '{s}' after '{s}'", .{ arg, other });
1810 } else manifest_file = arg;1810 } else manifest_file = arg;
1811 },1811 },
1812 .def => {
1813 linker_module_definition_file = arg;
1814 },
1812 .assembly, .assembly_with_cpp, .c, .cpp, .h, .hpp, .hm, .hmm, .ll, .bc, .m, .mm => {1815 .assembly, .assembly_with_cpp, .c, .cpp, .h, .hpp, .hm, .hmm, .ll, .bc, .m, .mm => {
1813 dev.check(.c_compiler);1816 dev.check(.c_compiler);
1814 try create_module.c_source_files.append(arena, .{1817 try create_module.c_source_files.append(arena, .{
...@@ -1834,7 +1837,7 @@ fn buildOutputType(...@@ -1834,7 +1837,7 @@ fn buildOutputType(
1834 fatal("found another zig file '{s}' after root source file '{s}'", .{ arg, other });1837 fatal("found another zig file '{s}' after root source file '{s}'", .{ arg, other });
1835 } else root_src_file = arg;1838 } else root_src_file = arg;
1836 },1839 },
1837 .def, .unknown => {1840 .unknown => {
1838 if (std.ascii.eqlIgnoreCase(".xml", fs.path.extension(arg))) {1841 if (std.ascii.eqlIgnoreCase(".xml", fs.path.extension(arg))) {
1839 warn("embedded manifest files must have the extension '.manifest'", .{});1842 warn("embedded manifest files must have the extension '.manifest'", .{});
1840 }1843 }