diff options
Diffstat (limited to 'src/Compilation.zig')
| -rw-r--r-- | src/Compilation.zig | 195 |
1 files changed, 97 insertions, 98 deletions
diff --git a/src/Compilation.zig b/src/Compilation.zig index d978dc5280..3f312e9956 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -4841,6 +4841,7 @@ fn updateWin32Resource(comp: *Compilation, win32_resource: *Win32Resource, win32 try argv.appendSlice(&.{ self_exe_path, "rc", + "--zig-integration", "/:no-preprocess", "/x", // ignore INCLUDE environment variable "/c65001", // UTF-8 codepage @@ -4849,31 +4850,7 @@ fn updateWin32Resource(comp: *Compilation, win32_resource: *Win32Resource, win32 }); try argv.appendSlice(&.{ "--", in_rc_path, out_res_path }); - var child = std.ChildProcess.init(argv.items, arena); - child.stdin_behavior = .Ignore; - child.stdout_behavior = .Ignore; - child.stderr_behavior = .Pipe; - - try child.spawn(); - - const stderr_reader = child.stderr.?.reader(); - const stderr = try stderr_reader.readAllAlloc(arena, 10 * 1024 * 1024); - const term = child.wait() catch |err| { - return comp.failWin32Resource(win32_resource, "unable to spawn {s}: {s}", .{ argv.items[0], @errorName(err) }); - }; - - switch (term) { - .Exited => |code| { - if (code != 0) { - log.err("zig rc failed with stderr:\n{s}", .{stderr}); - return comp.failWin32Resource(win32_resource, "zig rc exited with code {d}", .{code}); - } - }, - else => { - log.err("zig rc terminated with stderr:\n{s}", .{stderr}); - return comp.failWin32Resource(win32_resource, "zig rc terminated unexpectedly", .{}); - }, - } + try spawnZigRc(comp, win32_resource, src_basename, arena, argv.items, &child_progress_node); break :blk digest; }; @@ -4941,79 +4918,7 @@ fn updateWin32Resource(comp: *Compilation, win32_resource: *Win32Resource, win32 try argv.appendSlice(rc_src.extra_flags); try argv.appendSlice(&.{ "--", rc_src.src_path, out_res_path }); - { - var child = std.ChildProcess.init(argv.items, arena); - child.stdin_behavior = .Ignore; - child.stdout_behavior = .Pipe; - child.stderr_behavior = .Pipe; - - child.spawn() catch |err| { - return comp.failWin32Resource(win32_resource, "unable to spawn {s} rc: {s}", .{ argv.items[0], @errorName(err) }); - }; - - var poller = std.io.poll(comp.gpa, enum { stdout }, .{ - .stdout = child.stdout.?, - }); - defer poller.deinit(); - - const stdout = poller.fifo(.stdout); - - poll: while (true) { - while (stdout.readableLength() < @sizeOf(std.zig.Server.Message.Header)) { - if (!(try poller.poll())) break :poll; - } - const header = stdout.reader().readStruct(std.zig.Server.Message.Header) catch unreachable; - while (stdout.readableLength() < header.bytes_len) { - if (!(try poller.poll())) break :poll; - } - const body = stdout.readableSliceOfLen(header.bytes_len); - - switch (header.tag) { - // We expect exactly one ErrorBundle, and if any error_bundle header is - // sent then it's a fatal error. - .error_bundle => { - const EbHdr = std.zig.Server.Message.ErrorBundle; - const eb_hdr = @as(*align(1) const EbHdr, @ptrCast(body)); - const extra_bytes = - body[@sizeOf(EbHdr)..][0 .. @sizeOf(u32) * eb_hdr.extra_len]; - const string_bytes = - body[@sizeOf(EbHdr) + extra_bytes.len ..][0..eb_hdr.string_bytes_len]; - const unaligned_extra = std.mem.bytesAsSlice(u32, extra_bytes); - const extra_array = try comp.gpa.alloc(u32, unaligned_extra.len); - @memcpy(extra_array, unaligned_extra); - const error_bundle = .{ - .string_bytes = try comp.gpa.dupe(u8, string_bytes), - .extra = extra_array, - }; - return comp.failWin32ResourceWithOwnedBundle(win32_resource, error_bundle); - }, - else => {}, // ignore other messages - } - - stdout.discard(body.len); - } - - // Just in case there's a failure that didn't send an ErrorBundle (e.g. an error return trace) - const stderr_reader = child.stderr.?.reader(); - const stderr = try stderr_reader.readAllAlloc(arena, 10 * 1024 * 1024); - - const term = child.wait() catch |err| { - return comp.failWin32Resource(win32_resource, "unable to wait for {s} rc: {s}", .{ argv.items[0], @errorName(err) }); - }; - - switch (term) { - .Exited => |code| { - if (code != 0) { - log.err("zig rc failed with stderr:\n{s}", .{stderr}); - return comp.failWin32Resource(win32_resource, "zig rc exited with code {d}", .{code}); - } - }, - else => { - log.err("zig rc terminated with stderr:\n{s}", .{stderr}); - return comp.failWin32Resource(win32_resource, "zig rc terminated unexpectedly", .{}); - }, - } - } + try spawnZigRc(comp, win32_resource, src_basename, arena, argv.items, &child_progress_node); // Read depfile and update cache manifest { @@ -5079,6 +4984,100 @@ fn updateWin32Resource(comp: *Compilation, win32_resource: *Win32Resource, win32 }; } +fn spawnZigRc( + comp: *Compilation, + win32_resource: *Win32Resource, + src_basename: []const u8, + arena: Allocator, + argv: []const []const u8, + child_progress_node: *std.Progress.Node, +) !void { + var node_name: std.ArrayListUnmanaged(u8) = .{}; + defer node_name.deinit(arena); + + var child = std.ChildProcess.init(argv, arena); + child.stdin_behavior = .Ignore; + child.stdout_behavior = .Pipe; + child.stderr_behavior = .Pipe; + + child.spawn() catch |err| { + return comp.failWin32Resource(win32_resource, "unable to spawn {s} rc: {s}", .{ argv[0], @errorName(err) }); + }; + + var poller = std.io.poll(comp.gpa, enum { stdout }, .{ + .stdout = child.stdout.?, + }); + defer poller.deinit(); + + const stdout = poller.fifo(.stdout); + + poll: while (true) { + while (stdout.readableLength() < @sizeOf(std.zig.Server.Message.Header)) { + if (!(try poller.poll())) break :poll; + } + const header = stdout.reader().readStruct(std.zig.Server.Message.Header) catch unreachable; + while (stdout.readableLength() < header.bytes_len) { + if (!(try poller.poll())) break :poll; + } + const body = stdout.readableSliceOfLen(header.bytes_len); + + switch (header.tag) { + // We expect exactly one ErrorBundle, and if any error_bundle header is + // sent then it's a fatal error. + .error_bundle => { + const EbHdr = std.zig.Server.Message.ErrorBundle; + const eb_hdr = @as(*align(1) const EbHdr, @ptrCast(body)); + const extra_bytes = + body[@sizeOf(EbHdr)..][0 .. @sizeOf(u32) * eb_hdr.extra_len]; + const string_bytes = + body[@sizeOf(EbHdr) + extra_bytes.len ..][0..eb_hdr.string_bytes_len]; + const unaligned_extra = std.mem.bytesAsSlice(u32, extra_bytes); + const extra_array = try comp.gpa.alloc(u32, unaligned_extra.len); + @memcpy(extra_array, unaligned_extra); + const error_bundle = std.zig.ErrorBundle{ + .string_bytes = try comp.gpa.dupe(u8, string_bytes), + .extra = extra_array, + }; + return comp.failWin32ResourceWithOwnedBundle(win32_resource, error_bundle); + }, + .progress => { + node_name.clearRetainingCapacity(); + if (body.len > 0) { + try node_name.appendSlice(arena, "build 'zig rc'... "); + try node_name.appendSlice(arena, body); + child_progress_node.setName(node_name.items); + } else { + child_progress_node.setName(src_basename); + } + }, + else => {}, // ignore other messages + } + + stdout.discard(body.len); + } + + // Just in case there's a failure that didn't send an ErrorBundle (e.g. an error return trace) + const stderr_reader = child.stderr.?.reader(); + const stderr = try stderr_reader.readAllAlloc(arena, 10 * 1024 * 1024); + + const term = child.wait() catch |err| { + return comp.failWin32Resource(win32_resource, "unable to wait for {s} rc: {s}", .{ argv[0], @errorName(err) }); + }; + + switch (term) { + .Exited => |code| { + if (code != 0) { + log.err("zig rc failed with stderr:\n{s}", .{stderr}); + return comp.failWin32Resource(win32_resource, "zig rc exited with code {d}", .{code}); + } + }, + else => { + log.err("zig rc terminated with stderr:\n{s}", .{stderr}); + return comp.failWin32Resource(win32_resource, "zig rc terminated unexpectedly", .{}); + }, + } +} + pub fn tmpFilePath(comp: *Compilation, ally: Allocator, suffix: []const u8) error{OutOfMemory}![]const u8 { const s = std.fs.path.sep_str; const rand_int = std.crypto.random.int(u64); |
