authorgravatar for squeek502@hotmail.comRyan Liptak <squeek502@hotmail.com> 2024-05-02 18:57:34-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-05-22 06:58:09-07:00
logddde99bdfa5b2fa9b49c39a0f00a8c232a9576b6
tree953639ad4c64f00dd7560227f999dfb055cc38be
parentf2110b0c0d225eba414ee235519d790c5c2922d7

Build system: Allow specifying Win32 resource include paths using LazyPath

Adds an `include_paths` field to RcSourceFile that takes a slice of LazyPaths. The paths are resolved and subsequently appended to the -rcflags as `/I <resolved path>`. This fixes an accidental regression from https://github.com/ziglang/zig/pull/19174. Before that PR, all Win32 resource compilation would inherit the CC flags (via `addCCArgs`), which included things like include directories. After that PR, though, that is no longer the case. However, this commit intentionally does not restore the previous behavior (inheriting the C include paths). Instead, each .rc file will need to have its include paths specified directly and the include paths only apply to one particular resource script. This allows more fine-grained control and has less potentially surprising behavior (at the cost of some convenience). Closes #19605

4 files changed, 29 insertions(+), 5 deletions(-)

lib/std/Build/Module.zig+10
...@@ -110,11 +110,18 @@ pub const RcSourceFile = struct {...@@ -110,11 +110,18 @@ pub const RcSourceFile = struct {
110 /// /x (ignore the INCLUDE environment variable)110 /// /x (ignore the INCLUDE environment variable)
111 /// /D_DEBUG or /DNDEBUG depending on the optimization mode111 /// /D_DEBUG or /DNDEBUG depending on the optimization mode
112 flags: []const []const u8 = &.{},112 flags: []const []const u8 = &.{},
113 /// Include paths that may or may not exist yet and therefore need to be
114 /// specified as a LazyPath. Each path will be appended to the flags
115 /// as `/I <resolved path>`.
116 include_paths: []const LazyPath = &.{},
113117
114 pub fn dupe(self: RcSourceFile, b: *std.Build) RcSourceFile {118 pub fn dupe(self: RcSourceFile, b: *std.Build) RcSourceFile {
119 const include_paths = b.allocator.alloc(LazyPath, self.include_paths.len) catch @panic("OOM");
120 for (include_paths, self.include_paths) |*dest, lazy_path| dest.* = lazy_path.dupe(b);
115 return .{121 return .{
116 .file = self.file.dupe(b),122 .file = self.file.dupe(b),
117 .flags = b.dupeStrings(self.flags),123 .flags = b.dupeStrings(self.flags),
124 .include_paths = include_paths,
118 };125 };
119 }126 }
120};127};
...@@ -503,6 +510,9 @@ pub fn addWin32ResourceFile(m: *Module, source: RcSourceFile) void {...@@ -503,6 +510,9 @@ pub fn addWin32ResourceFile(m: *Module, source: RcSourceFile) void {
503 rc_source_file.* = source.dupe(b);510 rc_source_file.* = source.dupe(b);
504 m.link_objects.append(allocator, .{ .win32_resource_file = rc_source_file }) catch @panic("OOM");511 m.link_objects.append(allocator, .{ .win32_resource_file = rc_source_file }) catch @panic("OOM");
505 addLazyPathDependenciesOnly(m, source.file);512 addLazyPathDependenciesOnly(m, source.file);
513 for (source.include_paths) |include_path| {
514 addLazyPathDependenciesOnly(m, include_path);
515 }
506}516}
507517
508pub fn addAssemblyFile(m: *Module, source: LazyPath) void {518pub fn addAssemblyFile(m: *Module, source: LazyPath) void {
lib/std/Build/Step/Compile.zig+5-1
...@@ -1277,7 +1277,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {...@@ -1277,7 +1277,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
1277 .win32_resource_file => |rc_source_file| l: {1277 .win32_resource_file => |rc_source_file| l: {
1278 if (!my_responsibility) break :l;1278 if (!my_responsibility) break :l;
12791279
1280 if (rc_source_file.flags.len == 0) {1280 if (rc_source_file.flags.len == 0 and rc_source_file.include_paths.len == 0) {
1281 if (prev_has_rcflags) {1281 if (prev_has_rcflags) {
1282 try zig_args.append("-rcflags");1282 try zig_args.append("-rcflags");
1283 try zig_args.append("--");1283 try zig_args.append("--");
...@@ -1288,6 +1288,10 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {...@@ -1288,6 +1288,10 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
1288 for (rc_source_file.flags) |arg| {1288 for (rc_source_file.flags) |arg| {
1289 try zig_args.append(arg);1289 try zig_args.append(arg);
1290 }1290 }
1291 for (rc_source_file.include_paths) |include_path| {
1292 try zig_args.append("/I");
1293 try zig_args.append(include_path.getPath2(module.owner, step));
1294 }
1291 try zig_args.append("--");1295 try zig_args.append("--");
1292 prev_has_rcflags = true;1296 prev_has_rcflags = true;
1293 }1297 }
test/standalone/windows_resources/build.zig+10-4
...@@ -10,11 +10,13 @@ pub fn build(b: *std.Build) void {...@@ -10,11 +10,13 @@ pub fn build(b: *std.Build) void {
10 .abi = .gnu,10 .abi = .gnu,
11 });11 });
1212
13 add(b, b.host, .any, test_step);13 const generated_h_step = b.addWriteFile("generated.h", "#define GENERATED_DEFINE \"foo\"");
14 add(b, target, .any, test_step);
1514
16 add(b, b.host, .gnu, test_step);15 add(b, b.host, .any, test_step, generated_h_step);
17 add(b, target, .gnu, test_step);16 add(b, target, .any, test_step, generated_h_step);
17
18 add(b, b.host, .gnu, test_step, generated_h_step);
19 add(b, target, .gnu, test_step, generated_h_step);
18}20}
1921
20fn add(22fn add(
...@@ -22,6 +24,7 @@ fn add(...@@ -22,6 +24,7 @@ fn add(
22 target: std.Build.ResolvedTarget,24 target: std.Build.ResolvedTarget,
23 rc_includes: enum { any, gnu },25 rc_includes: enum { any, gnu },
24 test_step: *std.Build.Step,26 test_step: *std.Build.Step,
27 generated_h_step: *std.Build.Step.WriteFile,
25) void {28) void {
26 const exe = b.addExecutable(.{29 const exe = b.addExecutable(.{
27 .name = "zig_resource_test",30 .name = "zig_resource_test",
...@@ -32,6 +35,9 @@ fn add(...@@ -32,6 +35,9 @@ fn add(
32 exe.addWin32ResourceFile(.{35 exe.addWin32ResourceFile(.{
33 .file = b.path("res/zig.rc"),36 .file = b.path("res/zig.rc"),
34 .flags = &.{"/c65001"}, // UTF-8 code page37 .flags = &.{"/c65001"}, // UTF-8 code page
38 .include_paths = &.{
39 .{ .generated = &generated_h_step.generated_directory },
40 },
35 });41 });
36 exe.rc_includes = switch (rc_includes) {42 exe.rc_includes = switch (rc_includes) {
37 .any => .any,43 .any => .any,
test/standalone/windows_resources/res/zig.rc+4
...@@ -1,3 +1,7 @@...@@ -1,3 +1,7 @@
1// This include file is generated via build.zig, and it #defines GENERATED_DEFINE
2#include "generated.h"
3FOO RCDATA { GENERATED_DEFINE }
4
1#define ICO_ID 15#define ICO_ID 1
26
3// Nothing from windows.h is used in this .rc file,7// Nothing from windows.h is used in this .rc file,