| ... | ... | @@ -4841,6 +4841,7 @@ fn updateWin32Resource(comp: *Compilation, win32_resource: *Win32Resource, win32 |
| 4841 | 4841 | try argv.appendSlice(&.{ |
| 4842 | 4842 | self_exe_path, |
| 4843 | 4843 | "rc", |
| 4844 | "--zig-integration", |
| 4844 | 4845 | "/:no-preprocess", |
| 4845 | 4846 | "/x", // ignore INCLUDE environment variable |
| 4846 | 4847 | "/c65001", // UTF-8 codepage |
| ... | ... | @@ -4849,31 +4850,7 @@ fn updateWin32Resource(comp: *Compilation, win32_resource: *Win32Resource, win32 |
| 4849 | 4850 | }); |
| 4850 | 4851 | try argv.appendSlice(&.{ "--", in_rc_path, out_res_path }); |
| 4851 | 4852 | |
| 4852 | | var child = std.ChildProcess.init(argv.items, arena); |
| 4853 | | child.stdin_behavior = .Ignore; |
| 4854 | | child.stdout_behavior = .Ignore; |
| 4855 | | child.stderr_behavior = .Pipe; |
| 4856 | | |
| 4857 | | try child.spawn(); |
| 4858 | | |
| 4859 | | const stderr_reader = child.stderr.?.reader(); |
| 4860 | | const stderr = try stderr_reader.readAllAlloc(arena, 10 * 1024 * 1024); |
| 4861 | | const term = child.wait() catch |err| { |
| 4862 | | return comp.failWin32Resource(win32_resource, "unable to spawn {s}: {s}", .{ argv.items[0], @errorName(err) }); |
| 4863 | | }; |
| 4864 | | |
| 4865 | | switch (term) { |
| 4866 | | .Exited => |code| { |
| 4867 | | if (code != 0) { |
| 4868 | | log.err("zig rc failed with stderr:\n{s}", .{stderr}); |
| 4869 | | return comp.failWin32Resource(win32_resource, "zig rc exited with code {d}", .{code}); |
| 4870 | | } |
| 4871 | | }, |
| 4872 | | else => { |
| 4873 | | log.err("zig rc terminated with stderr:\n{s}", .{stderr}); |
| 4874 | | return comp.failWin32Resource(win32_resource, "zig rc terminated unexpectedly", .{}); |
| 4875 | | }, |
| 4876 | | } |
| 4853 | try spawnZigRc(comp, win32_resource, src_basename, arena, argv.items, &child_progress_node); |
| 4877 | 4854 | |
| 4878 | 4855 | break :blk digest; |
| 4879 | 4856 | }; |
| ... | ... | @@ -4941,79 +4918,7 @@ fn updateWin32Resource(comp: *Compilation, win32_resource: *Win32Resource, win32 |
| 4941 | 4918 | try argv.appendSlice(rc_src.extra_flags); |
| 4942 | 4919 | try argv.appendSlice(&.{ "--", rc_src.src_path, out_res_path }); |
| 4943 | 4920 | |
| 4944 | | { |
| 4945 | | var child = std.ChildProcess.init(argv.items, arena); |
| 4946 | | child.stdin_behavior = .Ignore; |
| 4947 | | child.stdout_behavior = .Pipe; |
| 4948 | | child.stderr_behavior = .Pipe; |
| 4949 | | |
| 4950 | | child.spawn() catch |err| { |
| 4951 | | return comp.failWin32Resource(win32_resource, "unable to spawn {s} rc: {s}", .{ argv.items[0], @errorName(err) }); |
| 4952 | | }; |
| 4953 | | |
| 4954 | | var poller = std.io.poll(comp.gpa, enum { stdout }, .{ |
| 4955 | | .stdout = child.stdout.?, |
| 4956 | | }); |
| 4957 | | defer poller.deinit(); |
| 4958 | | |
| 4959 | | const stdout = poller.fifo(.stdout); |
| 4960 | | |
| 4961 | | poll: while (true) { |
| 4962 | | while (stdout.readableLength() < @sizeOf(std.zig.Server.Message.Header)) { |
| 4963 | | if (!(try poller.poll())) break :poll; |
| 4964 | | } |
| 4965 | | const header = stdout.reader().readStruct(std.zig.Server.Message.Header) catch unreachable; |
| 4966 | | while (stdout.readableLength() < header.bytes_len) { |
| 4967 | | if (!(try poller.poll())) break :poll; |
| 4968 | | } |
| 4969 | | const body = stdout.readableSliceOfLen(header.bytes_len); |
| 4970 | | |
| 4971 | | switch (header.tag) { |
| 4972 | | // We expect exactly one ErrorBundle, and if any error_bundle header is |
| 4973 | | // sent then it's a fatal error. |
| 4974 | | .error_bundle => { |
| 4975 | | const EbHdr = std.zig.Server.Message.ErrorBundle; |
| 4976 | | const eb_hdr = @as(*align(1) const EbHdr, @ptrCast(body)); |
| 4977 | | const extra_bytes = |
| 4978 | | body[@sizeOf(EbHdr)..][0 .. @sizeOf(u32) * eb_hdr.extra_len]; |
| 4979 | | const string_bytes = |
| 4980 | | body[@sizeOf(EbHdr) + extra_bytes.len ..][0..eb_hdr.string_bytes_len]; |
| 4981 | | const unaligned_extra = std.mem.bytesAsSlice(u32, extra_bytes); |
| 4982 | | const extra_array = try comp.gpa.alloc(u32, unaligned_extra.len); |
| 4983 | | @memcpy(extra_array, unaligned_extra); |
| 4984 | | const error_bundle = .{ |
| 4985 | | .string_bytes = try comp.gpa.dupe(u8, string_bytes), |
| 4986 | | .extra = extra_array, |
| 4987 | | }; |
| 4988 | | return comp.failWin32ResourceWithOwnedBundle(win32_resource, error_bundle); |
| 4989 | | }, |
| 4990 | | else => {}, // ignore other messages |
| 4991 | | } |
| 4992 | | |
| 4993 | | stdout.discard(body.len); |
| 4994 | | } |
| 4995 | | |
| 4996 | | // Just in case there's a failure that didn't send an ErrorBundle (e.g. an error return trace) |
| 4997 | | const stderr_reader = child.stderr.?.reader(); |
| 4998 | | const stderr = try stderr_reader.readAllAlloc(arena, 10 * 1024 * 1024); |
| 4999 | | |
| 5000 | | const term = child.wait() catch |err| { |
| 5001 | | return comp.failWin32Resource(win32_resource, "unable to wait for {s} rc: {s}", .{ argv.items[0], @errorName(err) }); |
| 5002 | | }; |
| 5003 | | |
| 5004 | | switch (term) { |
| 5005 | | .Exited => |code| { |
| 5006 | | if (code != 0) { |
| 5007 | | log.err("zig rc failed with stderr:\n{s}", .{stderr}); |
| 5008 | | return comp.failWin32Resource(win32_resource, "zig rc exited with code {d}", .{code}); |
| 5009 | | } |
| 5010 | | }, |
| 5011 | | else => { |
| 5012 | | log.err("zig rc terminated with stderr:\n{s}", .{stderr}); |
| 5013 | | return comp.failWin32Resource(win32_resource, "zig rc terminated unexpectedly", .{}); |
| 5014 | | }, |
| 5015 | | } |
| 5016 | | } |
| 4921 | try spawnZigRc(comp, win32_resource, src_basename, arena, argv.items, &child_progress_node); |
| 5017 | 4922 | |
| 5018 | 4923 | // Read depfile and update cache manifest |
| 5019 | 4924 | { |
| ... | ... | @@ -5079,6 +4984,100 @@ fn updateWin32Resource(comp: *Compilation, win32_resource: *Win32Resource, win32 |
| 5079 | 4984 | }; |
| 5080 | 4985 | } |
| 5081 | 4986 | |
| 4987 | fn spawnZigRc( |
| 4988 | comp: *Compilation, |
| 4989 | win32_resource: *Win32Resource, |
| 4990 | src_basename: []const u8, |
| 4991 | arena: Allocator, |
| 4992 | argv: []const []const u8, |
| 4993 | child_progress_node: *std.Progress.Node, |
| 4994 | ) !void { |
| 4995 | var node_name: std.ArrayListUnmanaged(u8) = .{}; |
| 4996 | defer node_name.deinit(arena); |
| 4997 | |
| 4998 | var child = std.ChildProcess.init(argv, arena); |
| 4999 | child.stdin_behavior = .Ignore; |
| 5000 | child.stdout_behavior = .Pipe; |
| 5001 | child.stderr_behavior = .Pipe; |
| 5002 | |
| 5003 | child.spawn() catch |err| { |
| 5004 | return comp.failWin32Resource(win32_resource, "unable to spawn {s} rc: {s}", .{ argv[0], @errorName(err) }); |
| 5005 | }; |
| 5006 | |
| 5007 | var poller = std.io.poll(comp.gpa, enum { stdout }, .{ |
| 5008 | .stdout = child.stdout.?, |
| 5009 | }); |
| 5010 | defer poller.deinit(); |
| 5011 | |
| 5012 | const stdout = poller.fifo(.stdout); |
| 5013 | |
| 5014 | poll: while (true) { |
| 5015 | while (stdout.readableLength() < @sizeOf(std.zig.Server.Message.Header)) { |
| 5016 | if (!(try poller.poll())) break :poll; |
| 5017 | } |
| 5018 | const header = stdout.reader().readStruct(std.zig.Server.Message.Header) catch unreachable; |
| 5019 | while (stdout.readableLength() < header.bytes_len) { |
| 5020 | if (!(try poller.poll())) break :poll; |
| 5021 | } |
| 5022 | const body = stdout.readableSliceOfLen(header.bytes_len); |
| 5023 | |
| 5024 | switch (header.tag) { |
| 5025 | // We expect exactly one ErrorBundle, and if any error_bundle header is |
| 5026 | // sent then it's a fatal error. |
| 5027 | .error_bundle => { |
| 5028 | const EbHdr = std.zig.Server.Message.ErrorBundle; |
| 5029 | const eb_hdr = @as(*align(1) const EbHdr, @ptrCast(body)); |
| 5030 | const extra_bytes = |
| 5031 | body[@sizeOf(EbHdr)..][0 .. @sizeOf(u32) * eb_hdr.extra_len]; |
| 5032 | const string_bytes = |
| 5033 | body[@sizeOf(EbHdr) + extra_bytes.len ..][0..eb_hdr.string_bytes_len]; |
| 5034 | const unaligned_extra = std.mem.bytesAsSlice(u32, extra_bytes); |
| 5035 | const extra_array = try comp.gpa.alloc(u32, unaligned_extra.len); |
| 5036 | @memcpy(extra_array, unaligned_extra); |
| 5037 | const error_bundle = std.zig.ErrorBundle{ |
| 5038 | .string_bytes = try comp.gpa.dupe(u8, string_bytes), |
| 5039 | .extra = extra_array, |
| 5040 | }; |
| 5041 | return comp.failWin32ResourceWithOwnedBundle(win32_resource, error_bundle); |
| 5042 | }, |
| 5043 | .progress => { |
| 5044 | node_name.clearRetainingCapacity(); |
| 5045 | if (body.len > 0) { |
| 5046 | try node_name.appendSlice(arena, "build 'zig rc'... "); |
| 5047 | try node_name.appendSlice(arena, body); |
| 5048 | child_progress_node.setName(node_name.items); |
| 5049 | } else { |
| 5050 | child_progress_node.setName(src_basename); |
| 5051 | } |
| 5052 | }, |
| 5053 | else => {}, // ignore other messages |
| 5054 | } |
| 5055 | |
| 5056 | stdout.discard(body.len); |
| 5057 | } |
| 5058 | |
| 5059 | // Just in case there's a failure that didn't send an ErrorBundle (e.g. an error return trace) |
| 5060 | const stderr_reader = child.stderr.?.reader(); |
| 5061 | const stderr = try stderr_reader.readAllAlloc(arena, 10 * 1024 * 1024); |
| 5062 | |
| 5063 | const term = child.wait() catch |err| { |
| 5064 | return comp.failWin32Resource(win32_resource, "unable to wait for {s} rc: {s}", .{ argv[0], @errorName(err) }); |
| 5065 | }; |
| 5066 | |
| 5067 | switch (term) { |
| 5068 | .Exited => |code| { |
| 5069 | if (code != 0) { |
| 5070 | log.err("zig rc failed with stderr:\n{s}", .{stderr}); |
| 5071 | return comp.failWin32Resource(win32_resource, "zig rc exited with code {d}", .{code}); |
| 5072 | } |
| 5073 | }, |
| 5074 | else => { |
| 5075 | log.err("zig rc terminated with stderr:\n{s}", .{stderr}); |
| 5076 | return comp.failWin32Resource(win32_resource, "zig rc terminated unexpectedly", .{}); |
| 5077 | }, |
| 5078 | } |
| 5079 | } |
| 5080 | |
| 5082 | 5081 | pub fn tmpFilePath(comp: *Compilation, ally: Allocator, suffix: []const u8) error{OutOfMemory}![]const u8 { |
| 5083 | 5082 | const s = std.fs.path.sep_str; |
| 5084 | 5083 | const rand_int = std.crypto.random.int(u64); |