| ... | @@ -22,10 +22,12 @@ const Args = struct { | ... | @@ -22,10 +22,12 @@ const Args = struct { |
| 22 | src_dir: ?std.Io.Dir, | 22 | src_dir: ?std.Io.Dir, |
| 23 | targets: std.ArrayList(u32), | 23 | targets: std.ArrayList(u32), |
| 24 | target_bytes: std.ArrayList(u8), | 24 | target_bytes: std.ArrayList(u8), |
| | 25 | libc_runtimes_dir: ?std.Io.Dir, |
| | 26 | enable_darling: bool, |
| 25 | enable_qemu: bool, | 27 | enable_qemu: bool, |
| 26 | enable_wine: bool, | 28 | enable_rosetta: bool, |
| 27 | enable_wasmtime: bool, | 29 | enable_wasmtime: bool, |
| 28 | enable_darling: bool, | 30 | enable_wine: bool, |
| 29 | quiet: bool, | 31 | quiet: bool, |
| 30 | | 32 | |
| 31 | fn deinit(args: *Args, gpa: std.mem.Allocator) void { | 33 | fn deinit(args: *Args, gpa: std.mem.Allocator) void { |
| ... | @@ -73,7 +75,28 @@ pub fn runServer(runner: *Runner) ProtocolError { | ... | @@ -73,7 +75,28 @@ pub fn runServer(runner: *Runner) ProtocolError { |
| 73 | .args => { | 75 | .args => { |
| 74 | const args_body = try arena.alloc(u8, hdr.bytes_len); | 76 | const args_body = try arena.alloc(u8, hdr.bytes_len); |
| 75 | runner.server.in.readSliceAll(args_body) catch unreachable; | 77 | runner.server.in.readSliceAll(args_body) catch unreachable; |
| 76 | var state: enum { positional, zig, lib, src, target } = .positional; | 78 | const State = enum { |
| | 79 | positional, |
| | 80 | @"--zig", |
| | 81 | @"--lib", |
| | 82 | @"--src", |
| | 83 | @"--target", |
| | 84 | @"--libc-runtimes", |
| | 85 | }; |
| | 86 | var state: State = .positional; |
| | 87 | const state_expected: std.enums.EnumArray(State, enum { |
| | 88 | path, |
| | 89 | dir, |
| | 90 | file, |
| | 91 | string, |
| | 92 | }) = .init(.{ |
| | 93 | .positional = .path, |
| | 94 | .@"--zig" = .file, |
| | 95 | .@"--lib" = .dir, |
| | 96 | .@"--src" = .dir, |
| | 97 | .@"--target" = .string, |
| | 98 | .@"--libc-runtimes" = .dir, |
| | 99 | }); |
| 77 | var input_dir: std.zig.Server.Message.InputDir = .cwd; | 100 | var input_dir: std.zig.Server.Message.InputDir = .cwd; |
| 78 | var args_body_offset: usize = 0; | 101 | var args_body_offset: usize = 0; |
| 79 | while (args_body.len - args_body_offset > 0) { | 102 | while (args_body.len - args_body_offset > 0) { |
| ... | @@ -87,42 +110,56 @@ pub fn runServer(runner: *Runner) ProtocolError { | ... | @@ -87,42 +110,56 @@ pub fn runServer(runner: *Runner) ProtocolError { |
| 87 | args_body_offset = end + 1; | 110 | args_body_offset = end + 1; |
| 88 | switch (state) { | 111 | switch (state) { |
| 89 | .positional => if (std.mem.eql(u8, string, "--target")) { | 112 | .positional => if (std.mem.eql(u8, string, "--target")) { |
| 90 | state = .target; | 113 | state = .@"--target"; |
| 91 | continue; | 114 | continue; |
| 92 | } else if (std.mem.cutPrefix(u8, string, "--target=")) |target| { | 115 | } else if (std.mem.cutPrefix(u8, string, "--target=")) |target| { |
| 93 | try runner.args.addTarget(runner.gpa, target); | 116 | try runner.args.addTarget(runner.gpa, target); |
| | 117 | } else if (std.mem.eql(u8, string, "--libc-runtimes")) { |
| | 118 | state = .@"--libc-runtimes"; |
| | 119 | continue; |
| | 120 | } else if (std.mem.eql(u8, string, "-fdarling")) { |
| | 121 | runner.args.enable_darling = true; |
| 94 | } else if (std.mem.eql(u8, string, "-fqemu")) { | 122 | } else if (std.mem.eql(u8, string, "-fqemu")) { |
| 95 | runner.args.enable_qemu = true; | 123 | runner.args.enable_qemu = true; |
| 96 | } else if (std.mem.eql(u8, string, "-fwine")) { | 124 | } else if (std.mem.eql(u8, string, "-frosetta")) { |
| 97 | runner.args.enable_wine = true; | 125 | runner.args.enable_rosetta = true; |
| 98 | } else if (std.mem.eql(u8, string, "-fwasmtime")) { | 126 | } else if (std.mem.eql(u8, string, "-fwasmtime")) { |
| 99 | runner.args.enable_wasmtime = true; | 127 | runner.args.enable_wasmtime = true; |
| 100 | } else if (std.mem.eql(u8, string, "-fdarling")) { | 128 | } else if (std.mem.eql(u8, string, "-fwine")) { |
| 101 | runner.args.enable_darling = true; | 129 | runner.args.enable_wine = true; |
| 102 | } else if (std.mem.eql(u8, string, "--quiet")) { | 130 | } else if (std.mem.eql(u8, string, "--quiet")) { |
| 103 | runner.args.quiet = true; | 131 | runner.args.quiet = true; |
| 104 | }, | 132 | }, |
| 105 | .zig => unreachable, | 133 | .@"--target" => try runner.args.addTarget(runner.gpa, string), |
| 106 | .lib => unreachable, | 134 | else => return runner.fail( |
| 107 | .src => unreachable, | 135 | "\"{t}\" expected {t}, got {t}", |
| 108 | .target => try runner.args.addTarget(runner.gpa, string), | 136 | .{ state, state_expected.get(state), arg }, |
| | 137 | ), |
| 109 | } | 138 | } |
| 110 | }, | 139 | }, |
| 111 | .prefix => { | 140 | .prefix => { |
| 112 | const end = std.mem.findScalarPos(u8, args_body, args_body_offset, 0).?; | 141 | const end = std.mem.findScalarPos(u8, args_body, args_body_offset, 0).?; |
| 113 | const string = args_body[args_body_offset..end]; | 142 | const string = args_body[args_body_offset..end]; |
| 114 | args_body_offset = end + 1; | 143 | args_body_offset = end + 1; |
| | 144 | assert(state == .positional); |
| 115 | state = if (std.mem.eql(u8, string, "--zig=")) | 145 | state = if (std.mem.eql(u8, string, "--zig=")) |
| 116 | .zig | 146 | .@"--zig" |
| 117 | else if (std.mem.eql(u8, string, "--lib=")) | 147 | else if (std.mem.eql(u8, string, "--lib=")) |
| 118 | .lib | 148 | .@"--lib" |
| 119 | else if (std.mem.eql(u8, string, "--src=")) | 149 | else if (std.mem.eql(u8, string, "--src=")) |
| 120 | .src | 150 | .@"--src" |
| | 151 | else if (std.mem.eql(u8, string, "--libc-runtimes=")) |
| | 152 | .@"--libc-runtimes" |
| 121 | else | 153 | else |
| 122 | unreachable; | 154 | return runner.fail("unsupported arg prefix: {q}", .{string}); |
| 123 | continue; | 155 | continue; |
| 124 | }, | 156 | }, |
| 125 | .suffix => unreachable, | 157 | .suffix => { |
| | 158 | const end = std.mem.findScalarPos(u8, args_body, args_body_offset, 0).?; |
| | 159 | const string = args_body[args_body_offset..end]; |
| | 160 | args_body_offset = end + 1; |
| | 161 | return runner.fail("unsupported arg suffix: {q}", .{string}); |
| | 162 | }, |
| 126 | .input_dir => { | 163 | .input_dir => { |
| 127 | input_dir = @fromBackingInt(@backingInt(input_dir) + 1); | 164 | input_dir = @fromBackingInt(@backingInt(input_dir) + 1); |
| 128 | continue :arg .output_dir; | 165 | continue :arg .output_dir; |
| ... | @@ -137,16 +174,19 @@ pub fn runServer(runner: *Runner) ProtocolError { | ... | @@ -137,16 +174,19 @@ pub fn runServer(runner: *Runner) ProtocolError { |
| 137 | dir_handle.*, | 174 | dir_handle.*, |
| 138 | ) catch |err| switch (err) { | 175 | ) catch |err| switch (err) { |
| 139 | error.Canceled => |e| return e, | 176 | error.Canceled => |e| return e, |
| 140 | error.Unexpected => |e| return runner.fail( | 177 | else => |e| return runner.fail( |
| 141 | "unable to inherit parent dir: {t}", | 178 | "unable to inherit parent dir: {t}", |
| 142 | .{e}, | 179 | .{e}, |
| 143 | ), | 180 | ), |
| 144 | }; | 181 | }; |
| 145 | switch (state) { | 182 | switch (state) { |
| 146 | .positional => { | 183 | .positional => { |
| 147 | assert(runner.args.@"test" == null); | 184 | if (runner.args.@"test" != null or |
| | 185 | runner.args.manifest_file != null) return runner.fail( |
| | 186 | "{t} specified multiple times", |
| | 187 | .{state}, |
| | 188 | ); |
| 148 | runner.args.@"test" = .{ .input_dir = input_dir, .dir = dir }; | 189 | runner.args.@"test" = .{ .input_dir = input_dir, .dir = dir }; |
| 149 | assert(runner.args.manifest_file == null); | | |
| 150 | const manifest_path = "manifest"; | 190 | const manifest_path = "manifest"; |
| 151 | runner.args.manifest_file = dir.openFile( | 191 | runner.args.manifest_file = dir.openFile( |
| 152 | runner.io, | 192 | runner.io, |
| ... | @@ -161,16 +201,31 @@ pub fn runServer(runner: *Runner) ProtocolError { | ... | @@ -161,16 +201,31 @@ pub fn runServer(runner: *Runner) ProtocolError { |
| 161 | }; | 201 | }; |
| 162 | try runner.discoverInput(input_dir, manifest_path); | 202 | try runner.discoverInput(input_dir, manifest_path); |
| 163 | }, | 203 | }, |
| 164 | .zig => unreachable, | 204 | .@"--lib" => { |
| 165 | .lib => { | 205 | if (runner.args.lib_dir != null) return runner.fail( |
| 166 | assert(runner.args.lib_dir == null); | 206 | "\"{t}\" specified multiple times", |
| | 207 | .{state}, |
| | 208 | ); |
| 167 | runner.args.lib_dir = dir; | 209 | runner.args.lib_dir = dir; |
| 168 | }, | 210 | }, |
| 169 | .src => { | 211 | .@"--src" => { |
| 170 | assert(runner.args.src_dir == null); | 212 | if (runner.args.src_dir != null) return runner.fail( |
| | 213 | "\"{t}\" specified multiple times", |
| | 214 | .{state}, |
| | 215 | ); |
| 171 | runner.args.src_dir = dir; | 216 | runner.args.src_dir = dir; |
| 172 | }, | 217 | }, |
| 173 | .target => unreachable, | 218 | .@"--libc-runtimes" => { |
| | 219 | if (runner.args.libc_runtimes_dir != null) return runner.fail( |
| | 220 | "\"{t}\" specified multiple times", |
| | 221 | .{state}, |
| | 222 | ); |
| | 223 | runner.args.libc_runtimes_dir = dir; |
| | 224 | }, |
| | 225 | else => return runner.fail( |
| | 226 | "\"{t}\" expected {t}, got {t}", |
| | 227 | .{ state, state_expected.get(state), arg }, |
| | 228 | ), |
| 174 | } | 229 | } |
| 175 | }, | 230 | }, |
| 176 | .input_file, .input_file_content, .output_file => { | 231 | .input_file, .input_file_content, .output_file => { |
| ... | @@ -184,23 +239,31 @@ pub fn runServer(runner: *Runner) ProtocolError { | ... | @@ -184,23 +239,31 @@ pub fn runServer(runner: *Runner) ProtocolError { |
| 184 | .{ .nonblocking = false }, | 239 | .{ .nonblocking = false }, |
| 185 | ) catch |err| switch (err) { | 240 | ) catch |err| switch (err) { |
| 186 | error.Canceled => |e| return e, | 241 | error.Canceled => |e| return e, |
| 187 | error.Unexpected => |e| return runner.fail( | 242 | else => |e| return runner.fail( |
| 188 | "unable to inherit parent file: {t}", | 243 | "unable to inherit parent file: {t}", |
| 189 | .{e}, | 244 | .{e}, |
| 190 | ), | 245 | ), |
| 191 | }; | 246 | }; |
| 192 | switch (state) { | 247 | switch (state) { |
| 193 | .positional => { | 248 | .positional => { |
| 194 | assert(runner.args.manifest_file == null); | 249 | if (runner.args.@"test" != null or |
| | 250 | runner.args.manifest_file != null) return runner.fail( |
| | 251 | "{t} specified multiple times", |
| | 252 | .{state}, |
| | 253 | ); |
| 195 | runner.args.manifest_file = file; | 254 | runner.args.manifest_file = file; |
| 196 | }, | 255 | }, |
| 197 | .zig => { | 256 | .@"--zig" => { |
| 198 | assert(runner.args.zig_exe == null); | 257 | if (runner.args.zig_exe != null) return runner.fail( |
| | 258 | "\"{t}\" specified multiple times", |
| | 259 | .{state}, |
| | 260 | ); |
| 199 | runner.args.zig_exe = file; | 261 | runner.args.zig_exe = file; |
| 200 | }, | 262 | }, |
| 201 | .lib => unreachable, | 263 | else => return runner.fail( |
| 202 | .src => unreachable, | 264 | "\"{t}\" expected {t}, got {t}", |
| 203 | .target => unreachable, | 265 | .{ state, state_expected.get(state), arg }, |
| | 266 | ), |
| 204 | } | 267 | } |
| 205 | }, | 268 | }, |
| 206 | } | 269 | } |
| ... | @@ -480,7 +543,6 @@ fn testOne(runner: *Runner, test_index: u32) TestError!void { | ... | @@ -480,7 +543,6 @@ fn testOne(runner: *Runner, test_index: u32) TestError!void { |
| 480 | .target_query = target_query, | 543 | .target_query = target_query, |
| 481 | .manifest_sr = .init(&manifest_fr.interface, runner.gpa, &runner.eb_wip, src_path_string: { | 544 | .manifest_sr = .init(&manifest_fr.interface, runner.gpa, &runner.eb_wip, src_path_string: { |
| 482 | var path_buffer: [std.Io.Dir.max_path_bytes]u8 = undefined; | 545 | var path_buffer: [std.Io.Dir.max_path_bytes]u8 = undefined; |
| 483 | | | |
| 484 | const src_path = src_path: { | 546 | const src_path = src_path: { |
| 485 | break :src_path path_buffer[0 .. manifest_file.realPath( | 547 | break :src_path path_buffer[0 .. manifest_file.realPath( |
| 486 | runner.io, | 548 | runner.io, |
| ... | @@ -1022,6 +1084,7 @@ const Compiler = struct { | ... | @@ -1022,6 +1084,7 @@ const Compiler = struct { |
| 1022 | const gpa = runner.gpa; | 1084 | const gpa = runner.gpa; |
| 1023 | const arena = runner.arena.allocator(); | 1085 | const arena = runner.arena.allocator(); |
| 1024 | const io = runner.io; | 1086 | const io = runner.io; |
| | 1087 | const target = &comp.target.resolved; |
| 1025 | const config = &comp.config.?; | 1088 | const config = &comp.config.?; |
| 1026 | const out_dir = ".zig-cache" ++ std.Io.Dir.path.sep_str ++ | 1089 | const out_dir = ".zig-cache" ++ std.Io.Dir.path.sep_str ++ |
| 1027 | "o" ++ std.Io.Dir.path.sep_str ++ std.Build.Cache.binToHex(digest.*); | 1090 | "o" ++ std.Io.Dir.path.sep_str ++ std.Build.Cache.binToHex(digest.*); |
| ... | @@ -1036,16 +1099,18 @@ const Compiler = struct { | ... | @@ -1036,16 +1099,18 @@ const Compiler = struct { |
| 1036 | .stdout, .exit, .lldb => {}, | 1099 | .stdout, .exit, .lldb => {}, |
| 1037 | } | 1100 | } |
| 1038 | | 1101 | |
| 1039 | const executor = executor: switch (std.zig.system.getExternalExecutor( | 1102 | var argv: std.ArrayList([]const u8) = .initBuffer(try arena.alloc([]const u8, 4)); |
| 1040 | io, | 1103 | var environ_map: std.process.Environ.Map = .init(gpa); |
| 1041 | &comp.target.resolved, | 1104 | defer environ_map.deinit(); |
| 1042 | .{ | 1105 | const need_cross_libc = |
| 1043 | .host_cpu_arch = runner.host.cpu.arch, | 1106 | target.os.tag == .linux and config.flags.link_libc and config.flags.link_mode == .dynamic; |
| 1044 | .host_os_tag = runner.host.os.tag, | 1107 | const use_executor = use_executor: switch (std.zig.system.getExternalExecutor(io, target, .{ |
| 1045 | .link_mode = config.flags.link_mode, | 1108 | .host_cpu_arch = runner.host.cpu.arch, |
| 1046 | .link_libc = config.flags.link_libc, | 1109 | .host_os_tag = runner.host.os.tag, |
| 1047 | }, | 1110 | .qemu_fixes_dl = need_cross_libc and runner.args.libc_runtimes_dir != null, |
| 1048 | )) { | 1111 | .link_mode = config.flags.link_mode, |
| | 1112 | .link_libc = config.flags.link_libc, |
| | 1113 | })) { |
| 1049 | .bad_dl, .bad_os_or_cpu => { | 1114 | .bad_dl, .bad_os_or_cpu => { |
| 1050 | // This binary cannot be executed on this host. | 1115 | // This binary cannot be executed on this host. |
| 1051 | if (!runner.args.quiet) std.log.warn("skipping execution because host {q} cannot " ++ | 1116 | if (!runner.args.quiet) std.log.warn("skipping execution because host {q} cannot " ++ |
| ... | @@ -1054,24 +1119,57 @@ const Compiler = struct { | ... | @@ -1054,24 +1119,57 @@ const Compiler = struct { |
| 1054 | }); | 1119 | }); |
| 1055 | return; | 1120 | return; |
| 1056 | }, | 1121 | }, |
| 1057 | .native, .rosetta => null, | 1122 | .native => false, |
| 1058 | .qemu => |executor| if (runner.args.enable_qemu) | 1123 | .darling => |executor| if (runner.args.enable_darling) { |
| 1059 | executor | 1124 | argv.appendAssumeCapacity(executor); |
| 1060 | else | 1125 | break :use_executor true; |
| 1061 | continue :executor .bad_os_or_cpu, | 1126 | } else continue :use_executor .bad_os_or_cpu, |
| 1062 | .wine => |executor| if (runner.args.enable_wine) | 1127 | .qemu => |executor| if (runner.args.enable_qemu) { |
| 1063 | executor | 1128 | argv.appendAssumeCapacity(executor); |
| 1064 | else | 1129 | if (need_cross_libc) { |
| 1065 | continue :executor .bad_os_or_cpu, | 1130 | const libc_runtimes_dir = runner.args.libc_runtimes_dir orelse |
| 1066 | .wasmtime => |executor| if (runner.args.enable_wasmtime) | 1131 | continue :use_executor .bad_os_or_cpu; |
| 1067 | executor | 1132 | var path_buffer: [std.Io.Dir.max_path_bytes]u8 = undefined; |
| 1068 | else | 1133 | const libc_runtimes_path = path_buffer[0 .. libc_runtimes_dir.realPath( |
| 1069 | continue :executor .bad_os_or_cpu, | 1134 | runner.io, |
| 1070 | .darling => |executor| if (runner.args.enable_darling) | 1135 | &path_buffer, |
| 1071 | executor | 1136 | ) catch |err| switch (err) { |
| | 1137 | error.Canceled => |e| return e, |
| | 1138 | else => |e| return runner.fail("unable to get libc runtimes path: {t}", .{e}), |
| | 1139 | }]; |
| | 1140 | argv.appendSliceAssumeCapacity(&.{ "-L", try std.Io.Dir.path.join(arena, &.{ |
| | 1141 | libc_runtimes_path, |
| | 1142 | try if (target.isGnuLibC()) std.zig.target.glibcRuntimeTriple( |
| | 1143 | arena, |
| | 1144 | target.cpu.arch, |
| | 1145 | target.os.tag, |
| | 1146 | target.abi, |
| | 1147 | ) else if (target.isMuslLibC()) std.zig.target.muslRuntimeTriple( |
| | 1148 | arena, |
| | 1149 | target.cpu.arch, |
| | 1150 | target.abi, |
| | 1151 | ) else unreachable, |
| | 1152 | }) }); |
| | 1153 | } |
| | 1154 | break :use_executor true; |
| | 1155 | } else continue :use_executor .bad_os_or_cpu, |
| | 1156 | .rosetta => if (runner.args.enable_rosetta) |
| | 1157 | true |
| 1072 | else | 1158 | else |
| 1073 | continue :executor .bad_os_or_cpu, | 1159 | continue :use_executor .bad_os_or_cpu, |
| | 1160 | .wine => |executor| if (runner.args.enable_wine) { |
| | 1161 | if (!environ_map.contains("WINEDEBUG")) try environ_map.put("WINEDEBUG", "-all"); |
| | 1162 | argv.appendAssumeCapacity(executor); |
| | 1163 | break :use_executor true; |
| | 1164 | } else continue :use_executor .bad_os_or_cpu, |
| | 1165 | .wasmtime => |executor| if (runner.args.enable_wasmtime) { |
| | 1166 | if (!environ_map.contains("WASMTIME_BACKTRACE_DETAILS")) |
| | 1167 | try environ_map.put("WASMTIME_BACKTRACE_DETAILS", "1"); |
| | 1168 | argv.appendSliceAssumeCapacity(&.{ executor, "--dir=.", "-Sinherit-env" }); |
| | 1169 | break :use_executor true; |
| | 1170 | } else continue :use_executor .bad_os_or_cpu, |
| 1074 | }; | 1171 | }; |
| | 1172 | argv.appendAssumeCapacity(bin_path); |
| 1075 | | 1173 | |
| 1076 | var name_buffer: [std.Progress.Node.max_name_len]u8 = undefined; | 1174 | var name_buffer: [std.Progress.Node.max_name_len]u8 = undefined; |
| 1077 | const run_prog_node = runner.prog_node.start(std.mem.print(&name_buffer, "run {s}", .{ | 1175 | const run_prog_node = runner.prog_node.start(std.mem.print(&name_buffer, "run {s}", .{ |
| ... | @@ -1088,11 +1186,12 @@ const Compiler = struct { | ... | @@ -1088,11 +1186,12 @@ const Compiler = struct { |
| 1088 | .errors => unreachable, | 1186 | .errors => unreachable, |
| 1089 | .stdout, .exit => { | 1187 | .stdout, .exit => { |
| 1090 | const result = std.process.run(gpa, io, .{ | 1188 | const result = std.process.run(gpa, io, .{ |
| 1091 | .exe = if (executor) |_| .search else .{ .file = bin_file }, | 1189 | .exe = if (use_executor) .search else .{ .file = bin_file }, |
| 1092 | .argv = if (executor) |e| &.{ e, bin_path } else &.{bin_path}, | 1190 | .argv = argv.items, |
| 1093 | .cwd = .{ .dir = src_dir }, | 1191 | .cwd = .{ .dir = src_dir }, |
| | 1192 | .environ_map = &environ_map, |
| 1094 | .progress_node = run_prog_node, | 1193 | .progress_node = run_prog_node, |
| 1095 | }) catch |err| if (executor) |_| { | 1194 | }) catch |err| if (use_executor) { |
| 1096 | // Chances are the foreign executor isn't available. Skip this evaluation. | 1195 | // Chances are the foreign executor isn't available. Skip this evaluation. |
| 1097 | if (!runner.args.quiet) std.log.warn( | 1196 | if (!runner.args.quiet) std.log.warn( |
| 1098 | "skipping execution of {q} via executor for foreign target {q}: {t}", | 1197 | "skipping execution of {q} via executor for foreign target {q}: {t}", |
| ... | @@ -1151,7 +1250,7 @@ const Compiler = struct { | ... | @@ -1151,7 +1250,7 @@ const Compiler = struct { |
| 1151 | .{bin_path}, | 1250 | .{bin_path}, |
| 1152 | ), | 1251 | ), |
| 1153 | } | 1252 | } |
| 1154 | if (executor == null and result.stderr.len > 0) { | 1253 | if (!use_executor and result.stderr.len > 0) { |
| 1155 | std.log.err("generated executable {q} had unexpected stderr:\n{s}", .{ | 1254 | std.log.err("generated executable {q} had unexpected stderr:\n{s}", .{ |
| 1156 | bin_path, result.stderr, | 1255 | bin_path, result.stderr, |
| 1157 | }); | 1256 | }); |
| ... | @@ -1257,10 +1356,12 @@ const ClientArgs = struct { | ... | @@ -1257,10 +1356,12 @@ const ClientArgs = struct { |
| 1257 | src_dir: std.Io.Dir, | 1356 | src_dir: std.Io.Dir, |
| 1258 | targets: std.ArrayList([]const u8), | 1357 | targets: std.ArrayList([]const u8), |
| 1259 | keep_src: bool, | 1358 | keep_src: bool, |
| | 1359 | libc_runtimes_dir: ?std.Io.Dir, |
| | 1360 | enable_darling: bool, |
| 1260 | enable_qemu: bool, | 1361 | enable_qemu: bool, |
| | 1362 | enable_rosetta: bool, |
| 1261 | enable_wine: bool, | 1363 | enable_wine: bool, |
| 1262 | enable_wasmtime: bool, | 1364 | enable_wasmtime: bool, |
| 1263 | enable_darling: bool, | | |
| 1264 | quiet: bool, | 1365 | quiet: bool, |
| 1265 | }; | 1366 | }; |
| 1266 | pub fn main(init: std.process.Init) (std.mem.Allocator.Error || std.Io.Cancelable)!u8 { | 1367 | pub fn main(init: std.process.Init) (std.mem.Allocator.Error || std.Io.Cancelable)!u8 { |
| ... | @@ -1275,6 +1376,7 @@ pub fn main(init: std.process.Init) (std.mem.Allocator.Error || std.Io.Cancelabl | ... | @@ -1275,6 +1376,7 @@ pub fn main(init: std.process.Init) (std.mem.Allocator.Error || std.Io.Cancelabl |
| 1275 | var test_path_arg: ?[]const u8 = null; | 1376 | var test_path_arg: ?[]const u8 = null; |
| 1276 | var zig_path_arg: ?[]const u8 = null; | 1377 | var zig_path_arg: ?[]const u8 = null; |
| 1277 | var lib_path_arg: ?[]const u8 = null; | 1378 | var lib_path_arg: ?[]const u8 = null; |
| | 1379 | var libc_runtimes_path_arg: ?[]const u8 = null; |
| 1278 | var args: ClientArgs = .{ | 1380 | var args: ClientArgs = .{ |
| 1279 | .test_file = undefined, | 1381 | .test_file = undefined, |
| 1280 | .test_kind = undefined, | 1382 | .test_kind = undefined, |
| ... | @@ -1283,10 +1385,12 @@ pub fn main(init: std.process.Init) (std.mem.Allocator.Error || std.Io.Cancelabl | ... | @@ -1283,10 +1385,12 @@ pub fn main(init: std.process.Init) (std.mem.Allocator.Error || std.Io.Cancelabl |
| 1283 | .src_dir = undefined, | 1385 | .src_dir = undefined, |
| 1284 | .targets = .empty, | 1386 | .targets = .empty, |
| 1285 | .keep_src = false, | 1387 | .keep_src = false, |
| | 1388 | .libc_runtimes_dir = null, |
| | 1389 | .enable_darling = false, |
| 1286 | .enable_qemu = false, | 1390 | .enable_qemu = false, |
| | 1391 | .enable_rosetta = false, |
| 1287 | .enable_wine = false, | 1392 | .enable_wine = false, |
| 1288 | .enable_wasmtime = false, | 1393 | .enable_wasmtime = false, |
| 1289 | .enable_darling = false, | | |
| 1290 | .quiet = false, | 1394 | .quiet = false, |
| 1291 | }; | 1395 | }; |
| 1292 | defer args.targets.deinit(init.gpa); | 1396 | defer args.targets.deinit(init.gpa); |
| ... | @@ -1312,10 +1416,12 @@ pub fn main(init: std.process.Init) (std.mem.Allocator.Error || std.Io.Cancelabl | ... | @@ -1312,10 +1416,12 @@ pub fn main(init: std.process.Init) (std.mem.Allocator.Error || std.Io.Cancelabl |
| 1312 | .src_dir = null, | 1416 | .src_dir = null, |
| 1313 | .targets = .empty, | 1417 | .targets = .empty, |
| 1314 | .target_bytes = .empty, | 1418 | .target_bytes = .empty, |
| | 1419 | .libc_runtimes_dir = null, |
| | 1420 | .enable_darling = false, |
| 1315 | .enable_qemu = false, | 1421 | .enable_qemu = false, |
| 1316 | .enable_wine = false, | 1422 | .enable_rosetta = false, |
| 1317 | .enable_wasmtime = false, | 1423 | .enable_wasmtime = false, |
| 1318 | .enable_darling = false, | 1424 | .enable_wine = false, |
| 1319 | .quiet = false, | 1425 | .quiet = false, |
| 1320 | }, | 1426 | }, |
| 1321 | .host = std.zig.system.resolveTargetQuery(init.io, .{}) catch |err| switch (err) { | 1427 | .host = std.zig.system.resolveTargetQuery(init.io, .{}) catch |err| switch (err) { |
| ... | @@ -1361,18 +1467,24 @@ pub fn main(init: std.process.Init) (std.mem.Allocator.Error || std.Io.Cancelabl | ... | @@ -1361,18 +1467,24 @@ pub fn main(init: std.process.Init) (std.mem.Allocator.Error || std.Io.Cancelabl |
| 1361 | try args.targets.append(init.gpa, try arena.dupe(u8, target)); | 1467 | try args.targets.append(init.gpa, try arena.dupe(u8, target)); |
| 1362 | } else if (std.mem.eql(u8, arg, "--keep-src")) { | 1468 | } else if (std.mem.eql(u8, arg, "--keep-src")) { |
| 1363 | args.keep_src = true; | 1469 | args.keep_src = true; |
| | 1470 | } else if (std.mem.eql(u8, arg, "--libc-runtimes")) { |
| | 1471 | libc_runtimes_path_arg = arg_it.next() orelse fatal("missing arg after {q}", .{arg}); |
| | 1472 | } else if (std.mem.cutPrefix(u8, arg, "--libc-runtimes=")) |libc_runtimes_path| { |
| | 1473 | libc_runtimes_path_arg = libc_runtimes_path; |
| | 1474 | } else if (std.mem.eql(u8, arg, "-fdarling")) { |
| | 1475 | args.enable_darling = true; |
| 1364 | } else if (std.mem.eql(u8, arg, "-fqemu")) { | 1476 | } else if (std.mem.eql(u8, arg, "-fqemu")) { |
| 1365 | args.enable_qemu = true; | 1477 | args.enable_qemu = true; |
| | 1478 | } else if (std.mem.eql(u8, arg, "-frosetta")) { |
| | 1479 | args.enable_rosetta = true; |
| 1366 | } else if (std.mem.eql(u8, arg, "-fwine")) { | 1480 | } else if (std.mem.eql(u8, arg, "-fwine")) { |
| 1367 | args.enable_wine = true; | 1481 | args.enable_wine = true; |
| 1368 | } else if (std.mem.eql(u8, arg, "-fwasmtime")) { | 1482 | } else if (std.mem.eql(u8, arg, "-fwasmtime")) { |
| 1369 | args.enable_wasmtime = true; | 1483 | args.enable_wasmtime = true; |
| 1370 | } else if (std.mem.eql(u8, arg, "-fdarling")) { | | |
| 1371 | args.enable_darling = true; | | |
| 1372 | } else if (std.mem.eql(u8, arg, "--quiet")) { | 1484 | } else if (std.mem.eql(u8, arg, "--quiet")) { |
| 1373 | args.quiet = true; | 1485 | args.quiet = true; |
| 1374 | } else { | 1486 | } else { |
| 1375 | if (test_path_arg) |_| fatal("unknown arg {q}", .{arg}); | 1487 | if (test_path_arg) |_| fatal("unexpected arg {q}", .{arg}); |
| 1376 | test_path_arg = arg; | 1488 | test_path_arg = arg; |
| 1377 | } | 1489 | } |
| 1378 | } | 1490 | } |
| ... | @@ -1403,6 +1515,15 @@ pub fn main(init: std.process.Init) (std.mem.Allocator.Error || std.Io.Cancelabl | ... | @@ -1403,6 +1515,15 @@ pub fn main(init: std.process.Init) (std.mem.Allocator.Error || std.Io.Cancelabl |
| 1403 | else => |e| fatal("unable to open {q}: {t}", .{ lib_path, e }), | 1515 | else => |e| fatal("unable to open {q}: {t}", .{ lib_path, e }), |
| 1404 | }; | 1516 | }; |
| 1405 | defer args.lib_dir.close(init.io); | 1517 | defer args.lib_dir.close(init.io); |
| | 1518 | if (libc_runtimes_path_arg) |libc_runtimes_path| args.libc_runtimes_dir = cwd.openDir( |
| | 1519 | init.io, |
| | 1520 | libc_runtimes_path, |
| | 1521 | .{}, |
| | 1522 | ) catch |err| switch (err) { |
| | 1523 | error.Canceled => |e| return e, |
| | 1524 | else => |e| fatal("unable to open {q}: {t}", .{ lib_path, e }), |
| | 1525 | }; |
| | 1526 | defer if (args.libc_runtimes_dir) |libc_runtimes_dir| libc_runtimes_dir.close(init.io); |
| 1406 | | 1527 | |
| 1407 | const src_dir_path = "src_" ++ std.fmt.hex(rand_int: { | 1528 | const src_dir_path = "src_" ++ std.fmt.hex(rand_int: { |
| 1408 | var rand_int: u64 = undefined; | 1529 | var rand_int: u64 = undefined; |
| ... | @@ -1479,21 +1600,18 @@ fn runClient( | ... | @@ -1479,21 +1600,18 @@ fn runClient( |
| 1479 | try argv.append(gpa, @backingInt(Arg.prefix)); | 1600 | try argv.append(gpa, @backingInt(Arg.prefix)); |
| 1480 | try argv.appendSlice(gpa, "--zig="); | 1601 | try argv.appendSlice(gpa, "--zig="); |
| 1481 | try argv.append(gpa, 0); | 1602 | try argv.append(gpa, 0); |
| 1482 | | | |
| 1483 | try argv.append(gpa, @backingInt(Arg.input_file)); | 1603 | try argv.append(gpa, @backingInt(Arg.input_file)); |
| 1484 | try argv.appendSlice(gpa, @ptrCast(&args.zig_exe.handle)); | 1604 | try argv.appendSlice(gpa, @ptrCast(&args.zig_exe.handle)); |
| 1485 | | 1605 | |
| 1486 | try argv.append(gpa, @backingInt(Arg.prefix)); | 1606 | try argv.append(gpa, @backingInt(Arg.prefix)); |
| 1487 | try argv.appendSlice(gpa, "--lib="); | 1607 | try argv.appendSlice(gpa, "--lib="); |
| 1488 | try argv.append(gpa, 0); | 1608 | try argv.append(gpa, 0); |
| 1489 | | | |
| 1490 | try argv.append(gpa, @backingInt(Arg.input_dir)); | 1609 | try argv.append(gpa, @backingInt(Arg.input_dir)); |
| 1491 | try argv.appendSlice(gpa, @ptrCast(&args.lib_dir.handle)); | 1610 | try argv.appendSlice(gpa, @ptrCast(&args.lib_dir.handle)); |
| 1492 | | 1611 | |
| 1493 | try argv.append(gpa, @backingInt(Arg.prefix)); | 1612 | try argv.append(gpa, @backingInt(Arg.prefix)); |
| 1494 | try argv.appendSlice(gpa, "--src="); | 1613 | try argv.appendSlice(gpa, "--src="); |
| 1495 | try argv.append(gpa, 0); | 1614 | try argv.append(gpa, 0); |
| 1496 | | | |
| 1497 | try argv.append(gpa, @backingInt(Arg.output_dir)); | 1615 | try argv.append(gpa, @backingInt(Arg.output_dir)); |
| 1498 | try argv.appendSlice(gpa, @ptrCast(&args.src_dir.handle)); | 1616 | try argv.appendSlice(gpa, @ptrCast(&args.src_dir.handle)); |
| 1499 | | 1617 | |
| ... | @@ -1507,11 +1625,28 @@ fn runClient( | ... | @@ -1507,11 +1625,28 @@ fn runClient( |
| 1507 | try argv.append(gpa, 0); | 1625 | try argv.append(gpa, 0); |
| 1508 | } | 1626 | } |
| 1509 | | 1627 | |
| | 1628 | if (args.libc_runtimes_dir) |libc_runtimes_dir| { |
| | 1629 | try argv.append(gpa, @backingInt(Arg.prefix)); |
| | 1630 | try argv.appendSlice(gpa, "--libc-runtimes="); |
| | 1631 | try argv.append(gpa, 0); |
| | 1632 | try argv.append(gpa, @backingInt(Arg.input_dir)); |
| | 1633 | try argv.appendSlice(gpa, @ptrCast(&libc_runtimes_dir.handle)); |
| | 1634 | } |
| | 1635 | if (args.enable_darling) { |
| | 1636 | try argv.append(gpa, @backingInt(Arg.string)); |
| | 1637 | try argv.appendSlice(gpa, "-fdarling"); |
| | 1638 | try argv.append(gpa, 0); |
| | 1639 | } |
| 1510 | if (args.enable_qemu) { | 1640 | if (args.enable_qemu) { |
| 1511 | try argv.append(gpa, @backingInt(Arg.string)); | 1641 | try argv.append(gpa, @backingInt(Arg.string)); |
| 1512 | try argv.appendSlice(gpa, "-fqemu"); | 1642 | try argv.appendSlice(gpa, "-fqemu"); |
| 1513 | try argv.append(gpa, 0); | 1643 | try argv.append(gpa, 0); |
| 1514 | } | 1644 | } |
| | 1645 | if (args.enable_rosetta) { |
| | 1646 | try argv.append(gpa, @backingInt(Arg.string)); |
| | 1647 | try argv.appendSlice(gpa, "-frosetta"); |
| | 1648 | try argv.append(gpa, 0); |
| | 1649 | } |
| 1515 | if (args.enable_wine) { | 1650 | if (args.enable_wine) { |
| 1516 | try argv.append(gpa, @backingInt(Arg.string)); | 1651 | try argv.append(gpa, @backingInt(Arg.string)); |
| 1517 | try argv.appendSlice(gpa, "-fwine"); | 1652 | try argv.appendSlice(gpa, "-fwine"); |
| ... | @@ -1522,11 +1657,6 @@ fn runClient( | ... | @@ -1522,11 +1657,6 @@ fn runClient( |
| 1522 | try argv.appendSlice(gpa, "-fwasmtime"); | 1657 | try argv.appendSlice(gpa, "-fwasmtime"); |
| 1523 | try argv.append(gpa, 0); | 1658 | try argv.append(gpa, 0); |
| 1524 | } | 1659 | } |
| 1525 | if (args.enable_darling) { | | |
| 1526 | try argv.append(gpa, @backingInt(Arg.string)); | | |
| 1527 | try argv.appendSlice(gpa, "-fdarling"); | | |
| 1528 | try argv.append(gpa, 0); | | |
| 1529 | } | | |
| 1530 | | 1660 | |
| 1531 | if (args.quiet) { | 1661 | if (args.quiet) { |
| 1532 | try argv.append(gpa, @backingInt(Arg.string)); | 1662 | try argv.append(gpa, @backingInt(Arg.string)); |