| ... | ... | @@ -55,531 +55,564 @@ pub fn make( |
| 55 | 55 | var man = graph.cache.obtain(); |
| 56 | 56 | defer man.deinit(); |
| 57 | 57 | |
| 58 | | if (conf_run.environ_map.value) |environ_map_index| { |
| 59 | | const environ_map = environ_map_index.get(conf); |
| 60 | | for (environ_map.keys.slice(conf), environ_map.values.slice(conf)) |key, value| { |
| 61 | | man.hash.addBytesZ(key.slice(conf)); |
| 62 | | man.hash.addBytesZ(value.slice(conf)); |
| 58 | var tmp_dir_path: ["tmp".len + Dir.path.sep_str.len + std.fmt.hex(@as(u64, 0)).len]u8 = undefined; |
| 59 | |
| 60 | const has_side_effects = has_side_effects: { |
| 61 | if (conf_run.environ_map.value) |environ_map_index| { |
| 62 | const environ_map = environ_map_index.get(conf); |
| 63 | for (environ_map.keys.slice(conf), environ_map.values.slice(conf)) |key, value| { |
| 64 | man.hash.addBytesZ(key.slice(conf)); |
| 65 | man.hash.addBytesZ(value.slice(conf)); |
| 66 | } |
| 63 | 67 | } |
| 64 | | } |
| 65 | 68 | |
| 66 | | for (conf_run.preopens.slice) |preopen| { |
| 67 | | man.hash.addBytesZ(preopen.name.slice(conf)); |
| 68 | | const cwd_path = try maker.resolveLazyPathIndex(arena, preopen.path, run_index); |
| 69 | | man.hash.addBytes(try cwd_path.toString(arena)); |
| 70 | | } |
| 69 | for (conf_run.preopens.slice) |preopen| { |
| 70 | man.hash.addBytesZ(preopen.name.slice(conf)); |
| 71 | const cwd_path = try maker.resolveLazyPathIndex(arena, preopen.path, run_index); |
| 72 | man.hash.addBytes(try cwd_path.toString(arena)); |
| 73 | } |
| 71 | 74 | |
| 72 | | man.hash.add(graph.fuzzing); |
| 73 | | man.hash.add(conf_run.flags.color); |
| 74 | | man.hash.add(conf_run.flags.disable_zig_progress); |
| 75 | man.hash.add(graph.fuzzing); |
| 76 | man.hash.add(conf_run.flags.color); |
| 77 | man.hash.add(conf_run.flags.disable_zig_progress); |
| 75 | 78 | |
| 76 | | var any_discovered_inputs = switch (conf_run.flags.stdio) { |
| 77 | | .infer_from_args, .inherit, .check, .zig_test => false, |
| 78 | | .protocol => true, |
| 79 | | }; |
| 80 | | var any_output_args = false; |
| 81 | | var any_cli_positionals = false; |
| 79 | var any_discovered_inputs = switch (conf_run.flags.stdio) { |
| 80 | .infer_from_args, .inherit, .check, .zig_test => false, |
| 81 | .protocol => true, |
| 82 | }; |
| 83 | var any_output_args = false; |
| 84 | var any_cli_positionals = false; |
| 85 | |
| 86 | for (switch (conf_run.flags.stdio) { |
| 87 | .infer_from_args, .inherit, .check, .zig_test => conf_run.args.slice, |
| 88 | .protocol => conf_run.args.slice[0..1], // arguments communicated over protocol |
| 89 | }) |arg_index| { |
| 90 | const arg = arg_index.get(conf); |
| 91 | try argv_list.ensureUnusedCapacity(gpa, 1); |
| 92 | switch (arg.flags.tag) { |
| 93 | .string => { |
| 94 | const string = arg.prefix.value.?.slice(conf); |
| 95 | argv_list.appendAssumeCapacity(string); |
| 96 | man.hash.addBytesZ(string); |
| 97 | }, |
| 98 | .path_file => { |
| 99 | const prefix = if (arg.prefix.value) |p| p.slice(conf) else ""; |
| 100 | const suffix = if (arg.suffix.value) |p| p.slice(conf) else ""; |
| 101 | const file_path = try maker.resolveLazyPathIndex(arena, arg.path.value.?, run_index); |
| 102 | argv_list.appendAssumeCapacity(try mem.concat(arena, u8, &.{ |
| 103 | prefix, try convertPathArg(arena, run_index, maker, file_path, arg.flags.make_absolute), suffix, |
| 104 | })); |
| 105 | man.hash.add(arg.flags.make_absolute); |
| 106 | man.hash.addBytesZ(prefix); |
| 107 | man.hash.addBytesZ(suffix); |
| 108 | _ = try man.addInputPath(file_path, .{}); |
| 109 | }, |
| 110 | .path_directory => { |
| 111 | const prefix = if (arg.prefix.value) |p| p.slice(conf) else ""; |
| 112 | const suffix = if (arg.suffix.value) |p| p.slice(conf) else ""; |
| 113 | const file_path = try maker.resolveLazyPathIndex(arena, arg.path.value.?, run_index); |
| 114 | const resolved_arg = try mem.concat(arena, u8, &.{ |
| 115 | prefix, try convertPathArg(arena, run_index, maker, file_path, arg.flags.make_absolute), suffix, |
| 116 | }); |
| 117 | argv_list.appendAssumeCapacity(resolved_arg); |
| 118 | man.hash.add(arg.flags.make_absolute); |
| 119 | man.hash.addBytes(resolved_arg); |
| 120 | }, |
| 121 | .file_content => { |
| 122 | const prefix = if (arg.prefix.value) |p| p.slice(conf) else ""; |
| 123 | const suffix = if (arg.suffix.value) |p| p.slice(conf) else ""; |
| 124 | const file_path = try maker.resolveLazyPathIndex(arena, arg.path.value.?, run_index); |
| 125 | |
| 126 | var result: std.Io.Writer.Allocating = .init(arena); |
| 127 | result.writer.writeAll(prefix) catch return error.OutOfMemory; |
| 128 | |
| 129 | const file = file_path.root_dir.handle.openFile(io, file_path.sub_path, .{}) catch |err| |
| 130 | return step.fail(maker, "unable to open input file {qf}: {t}", .{ file_path, err }); |
| 131 | defer file.close(io); |
| 132 | |
| 133 | var file_reader = file.reader(io, &.{}); |
| 134 | _ = file_reader.interface.streamRemaining(&result.writer) catch |err| switch (err) { |
| 135 | error.ReadFailed => switch (file_reader.err.?) { |
| 136 | error.Canceled => |e| return e, |
| 137 | else => |e| return step.fail(maker, "failed to read from {qf}: {t}", .{ file_path, e }), |
| 138 | }, |
| 139 | error.WriteFailed => return error.OutOfMemory, |
| 140 | }; |
| 141 | result.writer.writeAll(suffix) catch return error.OutOfMemory; |
| 82 | 142 | |
| 83 | | for (switch (conf_run.flags.stdio) { |
| 84 | | .infer_from_args, .inherit, .check, .zig_test => conf_run.args.slice, |
| 85 | | .protocol => conf_run.args.slice[0..1], // arguments communicated over protocol |
| 86 | | }) |arg_index| { |
| 87 | | const arg = arg_index.get(conf); |
| 88 | | try argv_list.ensureUnusedCapacity(gpa, 1); |
| 89 | | switch (arg.flags.tag) { |
| 90 | | .string => { |
| 91 | | const string = arg.prefix.value.?.slice(conf); |
| 92 | | argv_list.appendAssumeCapacity(string); |
| 93 | | man.hash.addBytesZ(string); |
| 94 | | }, |
| 95 | | .path_file => { |
| 96 | | const prefix = if (arg.prefix.value) |p| p.slice(conf) else ""; |
| 97 | | const suffix = if (arg.suffix.value) |p| p.slice(conf) else ""; |
| 98 | | const file_path = try maker.resolveLazyPathIndex(arena, arg.path.value.?, run_index); |
| 99 | | argv_list.appendAssumeCapacity(try mem.concat(arena, u8, &.{ |
| 100 | | prefix, try convertPathArg(arena, run_index, maker, file_path, arg.flags.make_absolute), suffix, |
| 101 | | })); |
| 102 | | man.hash.add(arg.flags.make_absolute); |
| 103 | | man.hash.addBytesZ(prefix); |
| 104 | | man.hash.addBytesZ(suffix); |
| 105 | | _ = try man.addInputPath(file_path, .{}); |
| 106 | | }, |
| 107 | | .path_directory => { |
| 108 | | const prefix = if (arg.prefix.value) |p| p.slice(conf) else ""; |
| 109 | | const suffix = if (arg.suffix.value) |p| p.slice(conf) else ""; |
| 110 | | const file_path = try maker.resolveLazyPathIndex(arena, arg.path.value.?, run_index); |
| 111 | | const resolved_arg = try mem.concat(arena, u8, &.{ |
| 112 | | prefix, try convertPathArg(arena, run_index, maker, file_path, arg.flags.make_absolute), suffix, |
| 113 | | }); |
| 114 | | argv_list.appendAssumeCapacity(resolved_arg); |
| 115 | | man.hash.add(arg.flags.make_absolute); |
| 116 | | man.hash.addBytes(resolved_arg); |
| 143 | argv_list.appendAssumeCapacity(result.written()); |
| 144 | man.hash.addBytesZ(prefix); |
| 145 | _ = try man.addInputPath(file_path, .{}); |
| 146 | man.hash.addBytesZ(suffix); |
| 147 | }, |
| 148 | .artifact => { |
| 149 | const prefix = if (arg.prefix.value) |p| p.slice(conf) else ""; |
| 150 | const suffix = if (arg.suffix.value) |p| p.slice(conf) else ""; |
| 151 | const producer_index = arg.producer.value.?; |
| 152 | const producer_step = producer_index.ptr(conf); |
| 153 | const producer = producer_step.extended.get(conf.extra).compile; |
| 154 | const producer_make_comp_step = maker.stepByIndex(producer_index); |
| 155 | const producer_make_comp = &producer_make_comp_step.extended.compile; |
| 156 | |
| 157 | const file_path = producer_make_comp.installed_path orelse |
| 158 | maker.generatedPath(producer.generated_bin.value.?); |
| 159 | |
| 160 | argv_list.appendAssumeCapacity(try mem.concat(arena, u8, &.{ |
| 161 | prefix, try convertPathArg(arena, run_index, maker, file_path, arg.flags.make_absolute), suffix, |
| 162 | })); |
| 163 | |
| 164 | man.hash.add(arg.flags.make_absolute); |
| 165 | man.hash.addBytesZ(prefix); |
| 166 | man.hash.addBytesZ(suffix); |
| 167 | _ = try man.addInputPath(file_path, .{}); |
| 168 | }, |
| 169 | .output_file, .output_directory => { |
| 170 | const prefix = if (arg.prefix.value) |p| p.slice(conf) else ""; |
| 171 | const suffix = if (arg.suffix.value) |p| p.slice(conf) else ""; |
| 172 | const basename = arg.basename.value.?.slice(conf); |
| 173 | |
| 174 | man.hash.add(arg.flags.make_absolute); |
| 175 | man.hash.addBytesZ(prefix); |
| 176 | man.hash.addBytesZ(basename); |
| 177 | man.hash.addBytesZ(suffix); |
| 178 | man.hash.add(arg.flags.dep_file); |
| 179 | |
| 180 | if (arg.flags.dep_file) any_discovered_inputs = true; |
| 181 | any_output_args = true; |
| 182 | |
| 183 | // Add a placeholder into the argument list because we need the |
| 184 | // manifest hash to be updated with all arguments before the |
| 185 | // object directory is computed. |
| 186 | try output_placeholders.append(gpa, .{ |
| 187 | .index = @intCast(argv_list.items.len), |
| 188 | .offset = 0, |
| 189 | .arg_index = arg_index, |
| 190 | }); |
| 191 | _ = argv_list.addOneAssumeCapacity(); |
| 192 | }, |
| 193 | .passthru => { |
| 194 | any_cli_positionals = true; |
| 195 | if (maker.run_args) |run_args| { |
| 196 | try argv_list.appendSlice(gpa, run_args); |
| 197 | man.hash.addListOfBytes(run_args); |
| 198 | } |
| 199 | }, |
| 200 | .enable_darling => thirdPartyToggle(&man.hash, &argv_list, conf, graph.enable_darling, arg.prefix.value, arg.suffix.value), |
| 201 | .enable_qemu => thirdPartyToggle(&man.hash, &argv_list, conf, graph.enable_qemu, arg.prefix.value, arg.suffix.value), |
| 202 | .enable_rosetta => thirdPartyToggle(&man.hash, &argv_list, conf, graph.enable_rosetta, arg.prefix.value, arg.suffix.value), |
| 203 | .enable_wasmtime => thirdPartyToggle(&man.hash, &argv_list, conf, graph.enable_wasmtime, arg.prefix.value, arg.suffix.value), |
| 204 | .enable_wine => thirdPartyToggle(&man.hash, &argv_list, conf, graph.enable_wine, arg.prefix.value, arg.suffix.value), |
| 205 | } |
| 206 | } |
| 207 | |
| 208 | var owned_dirs: std.bit_set.Dynamic = .{}; |
| 209 | var inherit_dirs: std.ArrayList(Io.Dir) = .empty; |
| 210 | var owned_files: std.bit_set.Dynamic = .{}; |
| 211 | var inherit_files: std.ArrayList(Io.File) = .empty; |
| 212 | var protocol_args: std.ArrayList(u8) = .empty; |
| 213 | var input_dirs: std.ArrayList(Cache.Path) = .empty; |
| 214 | defer { |
| 215 | for (inherit_dirs.items, 0..) |inherit_dir, inherit_dir_index| |
| 216 | if (owned_dirs.isSet(inherit_dir_index)) inherit_dir.close(io); |
| 217 | for (inherit_files.items, 0..) |inherit_file, inherit_file_index| |
| 218 | if (owned_files.isSet(inherit_file_index)) inherit_file.close(io); |
| 219 | owned_dirs.deinit(gpa); |
| 220 | inherit_dirs.deinit(gpa); |
| 221 | owned_files.deinit(gpa); |
| 222 | inherit_files.deinit(gpa); |
| 223 | protocol_args.deinit(gpa); |
| 224 | input_dirs.deinit(gpa); |
| 225 | } |
| 226 | switch (conf_run.flags.stdio) { |
| 227 | .infer_from_args, .inherit, .check => {}, |
| 228 | .zig_test => { |
| 229 | const cache_dir_string = try convertPathArg(arena, run_index, maker, .{ .root_dir = cache_root }, false); |
| 230 | |
| 231 | try argv_list.ensureUnusedCapacity(gpa, 3); |
| 232 | argv_list.appendAssumeCapacity(try arena.print("--cache-dir={s}", .{cache_dir_string})); |
| 233 | argv_list.appendAssumeCapacity(try arena.print("--seed=0x{x}", .{graph.random_seed})); |
| 234 | argv_list.appendAssumeCapacity("--listen=-"); |
| 117 | 235 | }, |
| 118 | | .file_content => { |
| 119 | | const prefix = if (arg.prefix.value) |p| p.slice(conf) else ""; |
| 120 | | const suffix = if (arg.suffix.value) |p| p.slice(conf) else ""; |
| 121 | | const file_path = try maker.resolveLazyPathIndex(arena, arg.path.value.?, run_index); |
| 236 | .protocol => { |
| 237 | argv_list.appendAssumeCapacity("--listen=-"); |
| 238 | try input_dirs.append(gpa, if (conf_run.cwd.value) |lazy_cwd| |
| 239 | try maker.resolveLazyPathIndex(arena, lazy_cwd, run_index) |
| 240 | else |
| 241 | .cwd()); |
| 242 | for (conf_run.args.slice[1..]) |arg_index| { |
| 243 | const arg = arg_index.get(conf); |
| 244 | switch (arg.flags.tag) { |
| 245 | .string => { |
| 246 | const string = arg.prefix.value.?.slice(conf); |
| 122 | 247 | |
| 123 | | var result: std.Io.Writer.Allocating = .init(arena); |
| 124 | | result.writer.writeAll(prefix) catch return error.OutOfMemory; |
| 248 | man.hash.addBytesZ(string); |
| 125 | 249 | |
| 126 | | const file = file_path.root_dir.handle.openFile(io, file_path.sub_path, .{}) catch |err| |
| 127 | | return step.fail(maker, "unable to open input file {qf}: {t}", .{ file_path, err }); |
| 128 | | defer file.close(io); |
| 250 | try protocol_args.ensureUnusedCapacity(gpa, 1 + string.len + 1); |
| 251 | protocol_args.appendAssumeCapacity(@backingInt(std.zig.Client.Message.Arg.string)); |
| 252 | protocol_args.appendSliceAssumeCapacity(string); |
| 253 | protocol_args.appendAssumeCapacity(0); |
| 254 | }, |
| 255 | .path_file => { |
| 256 | const lazy_path = arg.path.value.?.get(conf); |
| 257 | switch (lazy_path) { |
| 258 | else => {}, |
| 259 | .relative => |relative| switch (relative.flags.base) { |
| 260 | else => {}, |
| 261 | .libc_runtimes => if (graph.libc_runtimes_dir == null) continue, |
| 262 | }, |
| 263 | } |
| 129 | 264 | |
| 130 | | var file_reader = file.reader(io, &.{}); |
| 131 | | _ = file_reader.interface.streamRemaining(&result.writer) catch |err| switch (err) { |
| 132 | | error.ReadFailed => switch (file_reader.err.?) { |
| 133 | | error.Canceled => |e| return e, |
| 134 | | else => |e| return step.fail(maker, "failed to read from {qf}: {t}", .{ file_path, e }), |
| 135 | | }, |
| 136 | | error.WriteFailed => return error.OutOfMemory, |
| 137 | | }; |
| 138 | | result.writer.writeAll(suffix) catch return error.OutOfMemory; |
| 265 | const prefix = if (arg.prefix.value) |p| p.slice(conf) else ""; |
| 266 | const suffix = if (arg.suffix.value) |p| p.slice(conf) else ""; |
| 267 | const file_path = try maker.resolveLazyPath(arena, lazy_path, run_index); |
| 268 | |
| 269 | try owned_files.resize(gpa, owned_files.bit_length + 1, true); |
| 270 | try inherit_files.ensureUnusedCapacity(gpa, 1); |
| 271 | const file = file_path.root_dir.handle.openFile(io, file_path.sub_path, .{}) catch |err| |
| 272 | return step.fail(maker, "unable to open input file {qf}: {t}", .{ file_path, err }); |
| 273 | inherit_files.appendAssumeCapacity(file); |
| 274 | |
| 275 | man.hash.addBytesZ(prefix); |
| 276 | _ = try man.addInputPath(file_path, .{}); |
| 277 | man.hash.addBytesZ(suffix); |
| 278 | |
| 279 | try protocol_args.ensureUnusedCapacity(gpa, 1 + prefix.len + 1 + |
| 280 | 1 + @sizeOf(Io.File.Handle) + |
| 281 | 1 + suffix.len + 1); |
| 282 | if (prefix.len > 0) { |
| 283 | protocol_args.appendAssumeCapacity(@backingInt(std.zig.Client.Message.Arg.prefix)); |
| 284 | protocol_args.appendSliceAssumeCapacity(prefix); |
| 285 | protocol_args.appendAssumeCapacity(0); |
| 286 | } |
| 287 | protocol_args.appendAssumeCapacity(@backingInt(std.zig.Client.Message.Arg.input_file)); |
| 288 | const file_handle: *align(1) Io.File.Handle = |
| 289 | @ptrCast(protocol_args.addManyAsArrayAssumeCapacity(@sizeOf(Io.File.Handle))); |
| 290 | file_handle.* = file.handle; |
| 291 | if (suffix.len > 0) { |
| 292 | protocol_args.appendAssumeCapacity(@backingInt(std.zig.Client.Message.Arg.suffix)); |
| 293 | protocol_args.appendSliceAssumeCapacity(prefix); |
| 294 | protocol_args.appendAssumeCapacity(0); |
| 295 | } |
| 296 | }, |
| 297 | .path_directory => { |
| 298 | const lazy_path = arg.path.value.?.get(conf); |
| 299 | switch (lazy_path) { |
| 300 | else => {}, |
| 301 | .relative => |relative| switch (relative.flags.base) { |
| 302 | else => {}, |
| 303 | .libc_runtimes => if (graph.libc_runtimes_dir == null) continue, |
| 304 | }, |
| 305 | } |
| 139 | 306 | |
| 140 | | argv_list.appendAssumeCapacity(result.written()); |
| 141 | | man.hash.addBytesZ(prefix); |
| 142 | | _ = try man.addInputPath(file_path, .{}); |
| 143 | | man.hash.addBytesZ(suffix); |
| 307 | const prefix = if (arg.prefix.value) |p| p.slice(conf) else ""; |
| 308 | const suffix = if (arg.suffix.value) |p| p.slice(conf) else ""; |
| 309 | const dir_path = try maker.resolveLazyPath(arena, lazy_path, run_index); |
| 310 | try input_dirs.append(gpa, dir_path); |
| 311 | |
| 312 | const has_sub_path = dir_path.sub_path.len > 0; |
| 313 | try owned_dirs.resize(gpa, owned_dirs.bit_length + 1, has_sub_path); |
| 314 | try inherit_dirs.ensureUnusedCapacity(gpa, 1); |
| 315 | const dir = if (has_sub_path) |
| 316 | dir_path.root_dir.handle.openDir(io, dir_path.sub_path, .{ |
| 317 | .iterate = true, |
| 318 | }) catch |err| return step.fail(maker, "unable to open input dir {qf}: {t}", .{ dir_path, err }) |
| 319 | else |
| 320 | dir_path.root_dir.handle; |
| 321 | inherit_dirs.appendAssumeCapacity(dir); |
| 322 | |
| 323 | man.hash.addBytesZ(prefix); |
| 324 | man.hash.addOptionalBytes(dir_path.root_dir.path); |
| 325 | man.hash.addBytes(dir_path.sub_path); |
| 326 | man.hash.addBytesZ(suffix); |
| 327 | |
| 328 | try protocol_args.ensureUnusedCapacity(gpa, 1 + prefix.len + 1 + |
| 329 | 1 + @sizeOf(Io.Dir.Handle) + |
| 330 | 1 + suffix.len + 1); |
| 331 | if (prefix.len > 0) { |
| 332 | protocol_args.appendAssumeCapacity(@backingInt(std.zig.Client.Message.Arg.prefix)); |
| 333 | protocol_args.appendSliceAssumeCapacity(prefix); |
| 334 | protocol_args.appendAssumeCapacity(0); |
| 335 | } |
| 336 | protocol_args.appendAssumeCapacity(@backingInt(std.zig.Client.Message.Arg.input_dir)); |
| 337 | const dir_handle: *align(1) Io.Dir.Handle = |
| 338 | @ptrCast(protocol_args.addManyAsArrayAssumeCapacity(@sizeOf(Io.Dir.Handle))); |
| 339 | dir_handle.* = dir.handle; |
| 340 | if (suffix.len > 0) { |
| 341 | protocol_args.appendAssumeCapacity(@backingInt(std.zig.Client.Message.Arg.suffix)); |
| 342 | protocol_args.appendSliceAssumeCapacity(prefix); |
| 343 | protocol_args.appendAssumeCapacity(0); |
| 344 | } |
| 345 | }, |
| 346 | .file_content => { |
| 347 | const prefix = if (arg.prefix.value) |p| p.slice(conf) else ""; |
| 348 | const suffix = if (arg.suffix.value) |p| p.slice(conf) else ""; |
| 349 | const file_path = try maker.resolveLazyPathIndex(arena, arg.path.value.?, run_index); |
| 350 | |
| 351 | try owned_files.resize(gpa, owned_files.bit_length + 1, true); |
| 352 | try inherit_files.ensureUnusedCapacity(gpa, 1); |
| 353 | const file = file_path.root_dir.handle.openFile(io, file_path.sub_path, .{}) catch |err| |
| 354 | return step.fail(maker, "unable to open input file {qf}: {t}", .{ file_path, err }); |
| 355 | inherit_files.appendAssumeCapacity(file); |
| 356 | |
| 357 | man.hash.addBytesZ(prefix); |
| 358 | _ = try man.addInputPath(file_path, .{}); |
| 359 | man.hash.addBytesZ(suffix); |
| 360 | |
| 361 | try protocol_args.ensureUnusedCapacity(gpa, 1 + prefix.len + 1 + |
| 362 | 1 + @sizeOf(Io.File.Handle) + |
| 363 | 1 + suffix.len + 1); |
| 364 | if (prefix.len > 0) { |
| 365 | protocol_args.appendAssumeCapacity(@backingInt(std.zig.Client.Message.Arg.prefix)); |
| 366 | protocol_args.appendSliceAssumeCapacity(prefix); |
| 367 | protocol_args.appendAssumeCapacity(0); |
| 368 | } |
| 369 | protocol_args.appendAssumeCapacity(@backingInt(std.zig.Client.Message.Arg.input_file_content)); |
| 370 | const file_handle: *align(1) Io.File.Handle = |
| 371 | @ptrCast(protocol_args.addManyAsArrayAssumeCapacity(@sizeOf(Io.File.Handle))); |
| 372 | file_handle.* = file.handle; |
| 373 | if (suffix.len > 0) { |
| 374 | protocol_args.appendAssumeCapacity(@backingInt(std.zig.Client.Message.Arg.suffix)); |
| 375 | protocol_args.appendSliceAssumeCapacity(prefix); |
| 376 | protocol_args.appendAssumeCapacity(0); |
| 377 | } |
| 378 | }, |
| 379 | .artifact => { |
| 380 | const prefix = if (arg.prefix.value) |p| p.slice(conf) else ""; |
| 381 | const suffix = if (arg.suffix.value) |p| p.slice(conf) else ""; |
| 382 | const producer_index = arg.producer.value.?; |
| 383 | const producer_step = producer_index.ptr(conf); |
| 384 | const producer = producer_step.extended.get(conf.extra).compile; |
| 385 | const producer_make_comp_step = maker.stepByIndex(producer_index); |
| 386 | const producer_make_comp = &producer_make_comp_step.extended.compile; |
| 387 | |
| 388 | const file_path = producer_make_comp.installed_path orelse |
| 389 | maker.generatedPath(producer.generated_bin.value.?); |
| 390 | |
| 391 | try owned_files.resize(gpa, owned_files.bit_length + 1, true); |
| 392 | try inherit_files.ensureUnusedCapacity(gpa, 1); |
| 393 | const file = file_path.root_dir.handle.openFile(io, file_path.sub_path, .{}) catch |err| |
| 394 | return step.fail(maker, "unable to open input artifact {qf}: {t}", .{ file_path, err }); |
| 395 | inherit_files.appendAssumeCapacity(file); |
| 396 | |
| 397 | man.hash.addBytesZ(prefix); |
| 398 | _ = try man.addInputPath(file_path, .{}); |
| 399 | man.hash.addBytesZ(suffix); |
| 400 | |
| 401 | try protocol_args.ensureUnusedCapacity(gpa, 1 + prefix.len + 1 + |
| 402 | 1 + @sizeOf(Io.File.Handle) + |
| 403 | 1 + suffix.len + 1); |
| 404 | if (prefix.len > 0) { |
| 405 | protocol_args.appendAssumeCapacity(@backingInt(std.zig.Client.Message.Arg.prefix)); |
| 406 | protocol_args.appendSliceAssumeCapacity(prefix); |
| 407 | protocol_args.appendAssumeCapacity(0); |
| 408 | } |
| 409 | protocol_args.appendAssumeCapacity(@backingInt(std.zig.Client.Message.Arg.input_file)); |
| 410 | const file_handle: *align(1) Io.File.Handle = |
| 411 | @ptrCast(protocol_args.addManyAsArrayAssumeCapacity(@sizeOf(Io.File.Handle))); |
| 412 | file_handle.* = file.handle; |
| 413 | if (suffix.len > 0) { |
| 414 | protocol_args.appendAssumeCapacity(@backingInt(std.zig.Client.Message.Arg.suffix)); |
| 415 | protocol_args.appendSliceAssumeCapacity(prefix); |
| 416 | protocol_args.appendAssumeCapacity(0); |
| 417 | } |
| 418 | }, |
| 419 | .output_file => { |
| 420 | const prefix = if (arg.prefix.value) |p| p.slice(conf) else ""; |
| 421 | const suffix = if (arg.suffix.value) |p| p.slice(conf) else ""; |
| 422 | const basename = arg.basename.value.?.slice(conf); |
| 423 | |
| 424 | man.hash.addBytesZ(prefix); |
| 425 | man.hash.addBytesZ(basename); |
| 426 | man.hash.addBytesZ(suffix); |
| 427 | assert(!arg.flags.dep_file); |
| 428 | |
| 429 | try protocol_args.ensureUnusedCapacity(gpa, 1 + prefix.len + 1 + |
| 430 | 1 + @sizeOf(Io.File.Handle) + |
| 431 | 1 + suffix.len + 1); |
| 432 | if (prefix.len > 0) { |
| 433 | protocol_args.appendAssumeCapacity(@backingInt(std.zig.Client.Message.Arg.prefix)); |
| 434 | protocol_args.appendSliceAssumeCapacity(prefix); |
| 435 | protocol_args.appendAssumeCapacity(0); |
| 436 | } |
| 437 | protocol_args.appendAssumeCapacity(@backingInt(std.zig.Client.Message.Arg.output_file)); |
| 438 | |
| 439 | // Add a placeholder into the argument list because we need the |
| 440 | // manifest hash to be updated with all arguments before the |
| 441 | // object directory is computed. |
| 442 | try owned_files.resize(gpa, owned_files.bit_length + 1, false); |
| 443 | try inherit_files.ensureUnusedCapacity(gpa, 1); |
| 444 | try output_placeholders.append(gpa, .{ |
| 445 | .index = @intCast(inherit_files.items.len), |
| 446 | .offset = @intCast(protocol_args.items.len), |
| 447 | .arg_index = arg_index, |
| 448 | }); |
| 449 | _ = inherit_files.addOneAssumeCapacity(); |
| 450 | |
| 451 | _ = protocol_args.addManyAsArrayAssumeCapacity(@sizeOf(Io.File.Handle)); |
| 452 | if (suffix.len > 0) { |
| 453 | protocol_args.appendAssumeCapacity(@backingInt(std.zig.Client.Message.Arg.suffix)); |
| 454 | protocol_args.appendSliceAssumeCapacity(prefix); |
| 455 | protocol_args.appendAssumeCapacity(0); |
| 456 | } |
| 457 | }, |
| 458 | .output_directory => { |
| 459 | const prefix = if (arg.prefix.value) |p| p.slice(conf) else ""; |
| 460 | const suffix = if (arg.suffix.value) |p| p.slice(conf) else ""; |
| 461 | const basename = arg.basename.value.?.slice(conf); |
| 462 | |
| 463 | man.hash.addBytesZ(prefix); |
| 464 | man.hash.addBytesZ(basename); |
| 465 | man.hash.addBytesZ(suffix); |
| 466 | assert(!arg.flags.dep_file); |
| 467 | |
| 468 | try protocol_args.ensureUnusedCapacity(gpa, 1 + prefix.len + 1 + |
| 469 | 1 + @sizeOf(Io.Dir.Handle) + |
| 470 | 1 + suffix.len + 1); |
| 471 | if (prefix.len > 0) { |
| 472 | protocol_args.appendAssumeCapacity(@backingInt(std.zig.Client.Message.Arg.prefix)); |
| 473 | protocol_args.appendSliceAssumeCapacity(prefix); |
| 474 | protocol_args.appendAssumeCapacity(0); |
| 475 | } |
| 476 | protocol_args.appendAssumeCapacity(@backingInt(std.zig.Client.Message.Arg.output_dir)); |
| 477 | |
| 478 | // Add a placeholder into the argument list because we need the |
| 479 | // manifest hash to be updated with all arguments before the |
| 480 | // object directory is computed. |
| 481 | try owned_dirs.resize(gpa, owned_dirs.bit_length + 1, false); |
| 482 | try inherit_dirs.ensureUnusedCapacity(gpa, 1); |
| 483 | try output_placeholders.append(gpa, .{ |
| 484 | .index = @intCast(inherit_dirs.items.len), |
| 485 | .offset = @intCast(protocol_args.items.len), |
| 486 | .arg_index = arg_index, |
| 487 | }); |
| 488 | _ = inherit_dirs.addOneAssumeCapacity(); |
| 489 | |
| 490 | _ = protocol_args.addManyAsArrayAssumeCapacity(@sizeOf(Io.Dir.Handle)); |
| 491 | if (suffix.len > 0) { |
| 492 | protocol_args.appendAssumeCapacity(@backingInt(std.zig.Client.Message.Arg.suffix)); |
| 493 | protocol_args.appendSliceAssumeCapacity(prefix); |
| 494 | protocol_args.appendAssumeCapacity(0); |
| 495 | } |
| 496 | }, |
| 497 | .passthru => if (maker.run_args) |run_args| { |
| 498 | man.hash.addListOfBytes(run_args); |
| 499 | |
| 500 | for (run_args) |run_arg| { |
| 501 | try protocol_args.ensureUnusedCapacity(gpa, 1 + run_arg.len + 1); |
| 502 | protocol_args.appendAssumeCapacity(@backingInt(std.zig.Client.Message.Arg.string)); |
| 503 | protocol_args.appendSliceAssumeCapacity(run_arg); |
| 504 | protocol_args.appendAssumeCapacity(0); |
| 505 | } |
| 506 | }, |
| 507 | .enable_darling => try thirdPartyToggleProtocol(gpa, &man.hash, &protocol_args, conf, graph.enable_darling, arg.prefix.value, arg.suffix.value), |
| 508 | .enable_qemu => try thirdPartyToggleProtocol(gpa, &man.hash, &protocol_args, conf, graph.enable_qemu, arg.prefix.value, arg.suffix.value), |
| 509 | .enable_rosetta => try thirdPartyToggleProtocol(gpa, &man.hash, &protocol_args, conf, graph.enable_rosetta, arg.prefix.value, arg.suffix.value), |
| 510 | .enable_wasmtime => try thirdPartyToggleProtocol(gpa, &man.hash, &protocol_args, conf, graph.enable_wasmtime, arg.prefix.value, arg.suffix.value), |
| 511 | .enable_wine => try thirdPartyToggleProtocol(gpa, &man.hash, &protocol_args, conf, graph.enable_wine, arg.prefix.value, arg.suffix.value), |
| 512 | } |
| 513 | } |
| 144 | 514 | }, |
| 145 | | .artifact => { |
| 146 | | const prefix = if (arg.prefix.value) |p| p.slice(conf) else ""; |
| 147 | | const suffix = if (arg.suffix.value) |p| p.slice(conf) else ""; |
| 148 | | const producer_index = arg.producer.value.?; |
| 149 | | const producer_step = producer_index.ptr(conf); |
| 150 | | const producer = producer_step.extended.get(conf.extra).compile; |
| 151 | | const producer_make_comp_step = maker.stepByIndex(producer_index); |
| 152 | | const producer_make_comp = &producer_make_comp_step.extended.compile; |
| 153 | | |
| 154 | | const file_path = producer_make_comp.installed_path orelse |
| 155 | | maker.generatedPath(producer.generated_bin.value.?); |
| 156 | | |
| 157 | | argv_list.appendAssumeCapacity(try mem.concat(arena, u8, &.{ |
| 158 | | prefix, try convertPathArg(arena, run_index, maker, file_path, arg.flags.make_absolute), suffix, |
| 159 | | })); |
| 515 | } |
| 160 | 516 | |
| 161 | | man.hash.add(arg.flags.make_absolute); |
| 162 | | man.hash.addBytesZ(prefix); |
| 163 | | man.hash.addBytesZ(suffix); |
| 164 | | _ = try man.addInputPath(file_path, .{}); |
| 165 | | }, |
| 166 | | .output_file, .output_directory => { |
| 167 | | const prefix = if (arg.prefix.value) |p| p.slice(conf) else ""; |
| 168 | | const suffix = if (arg.suffix.value) |p| p.slice(conf) else ""; |
| 169 | | const basename = arg.basename.value.?.slice(conf); |
| 170 | | |
| 171 | | man.hash.add(arg.flags.make_absolute); |
| 172 | | man.hash.addBytesZ(prefix); |
| 173 | | man.hash.addBytesZ(basename); |
| 174 | | man.hash.addBytesZ(suffix); |
| 175 | | man.hash.add(arg.flags.dep_file); |
| 176 | | |
| 177 | | if (arg.flags.dep_file) any_discovered_inputs = true; |
| 178 | | any_output_args = true; |
| 179 | | |
| 180 | | // Add a placeholder into the argument list because we need the |
| 181 | | // manifest hash to be updated with all arguments before the |
| 182 | | // object directory is computed. |
| 183 | | try output_placeholders.append(gpa, .{ |
| 184 | | .index = @intCast(argv_list.items.len), |
| 185 | | .offset = 0, |
| 186 | | .arg_index = arg_index, |
| 187 | | }); |
| 188 | | _ = argv_list.addOneAssumeCapacity(); |
| 517 | switch (conf_run.stdin.u) { |
| 518 | .bytes => |bytes| { |
| 519 | man.hash.addBytes(bytes.slice(conf)); |
| 189 | 520 | }, |
| 190 | | .passthru => { |
| 191 | | any_cli_positionals = true; |
| 192 | | if (maker.run_args) |run_args| { |
| 193 | | try argv_list.appendSlice(gpa, run_args); |
| 194 | | man.hash.addListOfBytes(run_args); |
| 195 | | } |
| 521 | .lazy_path => |lazy_path| { |
| 522 | const file_path = try maker.resolveLazyPathIndex(arena, lazy_path, run_index); |
| 523 | _ = try man.addInputPath(file_path, .{}); |
| 196 | 524 | }, |
| 197 | | .enable_darling => thirdPartyToggle(&man.hash, &argv_list, conf, graph.enable_darling, arg.prefix.value, arg.suffix.value), |
| 198 | | .enable_qemu => thirdPartyToggle(&man.hash, &argv_list, conf, graph.enable_qemu, arg.prefix.value, arg.suffix.value), |
| 199 | | .enable_rosetta => thirdPartyToggle(&man.hash, &argv_list, conf, graph.enable_rosetta, arg.prefix.value, arg.suffix.value), |
| 200 | | .enable_wasmtime => thirdPartyToggle(&man.hash, &argv_list, conf, graph.enable_wasmtime, arg.prefix.value, arg.suffix.value), |
| 201 | | .enable_wine => thirdPartyToggle(&man.hash, &argv_list, conf, graph.enable_wine, arg.prefix.value, arg.suffix.value), |
| 525 | .none => {}, |
| 202 | 526 | } |
| 203 | | } |
| 204 | | |
| 205 | | var owned_dirs: std.bit_set.Dynamic = .{}; |
| 206 | | var inherit_dirs: std.ArrayList(Io.Dir) = .empty; |
| 207 | | var owned_files: std.bit_set.Dynamic = .{}; |
| 208 | | var inherit_files: std.ArrayList(Io.File) = .empty; |
| 209 | | var protocol_args: std.ArrayList(u8) = .empty; |
| 210 | | var input_dirs: std.ArrayList(Cache.Path) = .empty; |
| 211 | | defer { |
| 212 | | for (inherit_dirs.items, 0..) |inherit_dir, inherit_dir_index| |
| 213 | | if (owned_dirs.isSet(inherit_dir_index)) inherit_dir.close(io); |
| 214 | | for (inherit_files.items, 0..) |inherit_file, inherit_file_index| |
| 215 | | if (owned_files.isSet(inherit_file_index)) inherit_file.close(io); |
| 216 | | owned_dirs.deinit(gpa); |
| 217 | | inherit_dirs.deinit(gpa); |
| 218 | | owned_files.deinit(gpa); |
| 219 | | inherit_files.deinit(gpa); |
| 220 | | protocol_args.deinit(gpa); |
| 221 | | input_dirs.deinit(gpa); |
| 222 | | } |
| 223 | | switch (conf_run.flags.stdio) { |
| 224 | | .infer_from_args, .inherit, .check => {}, |
| 225 | | .zig_test => { |
| 226 | | const cache_dir_string = try convertPathArg(arena, run_index, maker, .{ .root_dir = cache_root }, false); |
| 227 | 527 | |
| 228 | | try argv_list.ensureUnusedCapacity(gpa, 3); |
| 229 | | argv_list.appendAssumeCapacity(try arena.print("--cache-dir={s}", .{cache_dir_string})); |
| 230 | | argv_list.appendAssumeCapacity(try arena.print("--seed=0x{x}", .{graph.random_seed})); |
| 231 | | argv_list.appendAssumeCapacity("--listen=-"); |
| 232 | | }, |
| 233 | | .protocol => { |
| 234 | | argv_list.appendAssumeCapacity("--listen=-"); |
| 235 | | try input_dirs.append(gpa, if (conf_run.cwd.value) |lazy_cwd| |
| 236 | | try maker.resolveLazyPathIndex(arena, lazy_cwd, run_index) |
| 237 | | else |
| 238 | | .cwd()); |
| 239 | | for (conf_run.args.slice[1..]) |arg_index| { |
| 240 | | const arg = arg_index.get(conf); |
| 241 | | switch (arg.flags.tag) { |
| 242 | | .string => { |
| 243 | | const string = arg.prefix.value.?.slice(conf); |
| 244 | | |
| 245 | | man.hash.addBytesZ(string); |
| 246 | | |
| 247 | | try protocol_args.ensureUnusedCapacity(gpa, 1 + string.len + 1); |
| 248 | | protocol_args.appendAssumeCapacity(@backingInt(std.zig.Client.Message.Arg.string)); |
| 249 | | protocol_args.appendSliceAssumeCapacity(string); |
| 250 | | protocol_args.appendAssumeCapacity(0); |
| 251 | | }, |
| 252 | | .path_file => { |
| 253 | | const lazy_path = arg.path.value.?.get(conf); |
| 254 | | switch (lazy_path) { |
| 255 | | else => {}, |
| 256 | | .relative => |relative| switch (relative.flags.base) { |
| 257 | | else => {}, |
| 258 | | .libc_runtimes => if (graph.libc_runtimes_dir == null) continue, |
| 259 | | }, |
| 260 | | } |
| 261 | | |
| 262 | | const prefix = if (arg.prefix.value) |p| p.slice(conf) else ""; |
| 263 | | const suffix = if (arg.suffix.value) |p| p.slice(conf) else ""; |
| 264 | | const file_path = try maker.resolveLazyPath(arena, lazy_path, run_index); |
| 265 | | |
| 266 | | try owned_files.resize(gpa, owned_files.bit_length + 1, true); |
| 267 | | try inherit_files.ensureUnusedCapacity(gpa, 1); |
| 268 | | const file = file_path.root_dir.handle.openFile(io, file_path.sub_path, .{}) catch |err| |
| 269 | | return step.fail(maker, "unable to open input file {qf}: {t}", .{ file_path, err }); |
| 270 | | inherit_files.appendAssumeCapacity(file); |
| 271 | | |
| 272 | | man.hash.addBytesZ(prefix); |
| 273 | | _ = try man.addInputPath(file_path, .{}); |
| 274 | | man.hash.addBytesZ(suffix); |
| 275 | | |
| 276 | | try protocol_args.ensureUnusedCapacity(gpa, 1 + prefix.len + 1 + |
| 277 | | 1 + @sizeOf(Io.File.Handle) + |
| 278 | | 1 + suffix.len + 1); |
| 279 | | if (prefix.len > 0) { |
| 280 | | protocol_args.appendAssumeCapacity(@backingInt(std.zig.Client.Message.Arg.prefix)); |
| 281 | | protocol_args.appendSliceAssumeCapacity(prefix); |
| 282 | | protocol_args.appendAssumeCapacity(0); |
| 283 | | } |
| 284 | | protocol_args.appendAssumeCapacity(@backingInt(std.zig.Client.Message.Arg.input_file)); |
| 285 | | const file_handle: *align(1) Io.File.Handle = |
| 286 | | @ptrCast(protocol_args.addManyAsArrayAssumeCapacity(@sizeOf(Io.File.Handle))); |
| 287 | | file_handle.* = file.handle; |
| 288 | | if (suffix.len > 0) { |
| 289 | | protocol_args.appendAssumeCapacity(@backingInt(std.zig.Client.Message.Arg.suffix)); |
| 290 | | protocol_args.appendSliceAssumeCapacity(prefix); |
| 291 | | protocol_args.appendAssumeCapacity(0); |
| 292 | | } |
| 293 | | }, |
| 294 | | .path_directory => { |
| 295 | | const lazy_path = arg.path.value.?.get(conf); |
| 296 | | switch (lazy_path) { |
| 297 | | else => {}, |
| 298 | | .relative => |relative| switch (relative.flags.base) { |
| 299 | | else => {}, |
| 300 | | .libc_runtimes => if (graph.libc_runtimes_dir == null) continue, |
| 301 | | }, |
| 302 | | } |
| 303 | | |
| 304 | | const prefix = if (arg.prefix.value) |p| p.slice(conf) else ""; |
| 305 | | const suffix = if (arg.suffix.value) |p| p.slice(conf) else ""; |
| 306 | | const dir_path = try maker.resolveLazyPath(arena, lazy_path, run_index); |
| 307 | | try input_dirs.append(gpa, dir_path); |
| 308 | | |
| 309 | | const has_sub_path = dir_path.sub_path.len > 0; |
| 310 | | try owned_dirs.resize(gpa, owned_dirs.bit_length + 1, has_sub_path); |
| 311 | | try inherit_dirs.ensureUnusedCapacity(gpa, 1); |
| 312 | | const dir = if (has_sub_path) |
| 313 | | dir_path.root_dir.handle.openDir(io, dir_path.sub_path, .{ |
| 314 | | .iterate = true, |
| 315 | | }) catch |err| return step.fail(maker, "unable to open input dir {qf}: {t}", .{ dir_path, err }) |
| 316 | | else |
| 317 | | dir_path.root_dir.handle; |
| 318 | | inherit_dirs.appendAssumeCapacity(dir); |
| 319 | | |
| 320 | | man.hash.addBytesZ(prefix); |
| 321 | | man.hash.addOptionalBytes(dir_path.root_dir.path); |
| 322 | | man.hash.addBytes(dir_path.sub_path); |
| 323 | | man.hash.addBytesZ(suffix); |
| 324 | | |
| 325 | | try protocol_args.ensureUnusedCapacity(gpa, 1 + prefix.len + 1 + |
| 326 | | 1 + @sizeOf(Io.Dir.Handle) + |
| 327 | | 1 + suffix.len + 1); |
| 328 | | if (prefix.len > 0) { |
| 329 | | protocol_args.appendAssumeCapacity(@backingInt(std.zig.Client.Message.Arg.prefix)); |
| 330 | | protocol_args.appendSliceAssumeCapacity(prefix); |
| 331 | | protocol_args.appendAssumeCapacity(0); |
| 332 | | } |
| 333 | | protocol_args.appendAssumeCapacity(@backingInt(std.zig.Client.Message.Arg.input_dir)); |
| 334 | | const dir_handle: *align(1) Io.Dir.Handle = |
| 335 | | @ptrCast(protocol_args.addManyAsArrayAssumeCapacity(@sizeOf(Io.Dir.Handle))); |
| 336 | | dir_handle.* = dir.handle; |
| 337 | | if (suffix.len > 0) { |
| 338 | | protocol_args.appendAssumeCapacity(@backingInt(std.zig.Client.Message.Arg.suffix)); |
| 339 | | protocol_args.appendSliceAssumeCapacity(prefix); |
| 340 | | protocol_args.appendAssumeCapacity(0); |
| 341 | | } |
| 342 | | }, |
| 343 | | .file_content => { |
| 344 | | const prefix = if (arg.prefix.value) |p| p.slice(conf) else ""; |
| 345 | | const suffix = if (arg.suffix.value) |p| p.slice(conf) else ""; |
| 346 | | const file_path = try maker.resolveLazyPathIndex(arena, arg.path.value.?, run_index); |
| 347 | | |
| 348 | | try owned_files.resize(gpa, owned_files.bit_length + 1, true); |
| 349 | | try inherit_files.ensureUnusedCapacity(gpa, 1); |
| 350 | | const file = file_path.root_dir.handle.openFile(io, file_path.sub_path, .{}) catch |err| |
| 351 | | return step.fail(maker, "unable to open input file {qf}: {t}", .{ file_path, err }); |
| 352 | | inherit_files.appendAssumeCapacity(file); |
| 353 | | |
| 354 | | man.hash.addBytesZ(prefix); |
| 355 | | _ = try man.addInputPath(file_path, .{}); |
| 356 | | man.hash.addBytesZ(suffix); |
| 357 | | |
| 358 | | try protocol_args.ensureUnusedCapacity(gpa, 1 + prefix.len + 1 + |
| 359 | | 1 + @sizeOf(Io.File.Handle) + |
| 360 | | 1 + suffix.len + 1); |
| 361 | | if (prefix.len > 0) { |
| 362 | | protocol_args.appendAssumeCapacity(@backingInt(std.zig.Client.Message.Arg.prefix)); |
| 363 | | protocol_args.appendSliceAssumeCapacity(prefix); |
| 364 | | protocol_args.appendAssumeCapacity(0); |
| 365 | | } |
| 366 | | protocol_args.appendAssumeCapacity(@backingInt(std.zig.Client.Message.Arg.input_file_content)); |
| 367 | | const file_handle: *align(1) Io.File.Handle = |
| 368 | | @ptrCast(protocol_args.addManyAsArrayAssumeCapacity(@sizeOf(Io.File.Handle))); |
| 369 | | file_handle.* = file.handle; |
| 370 | | if (suffix.len > 0) { |
| 371 | | protocol_args.appendAssumeCapacity(@backingInt(std.zig.Client.Message.Arg.suffix)); |
| 372 | | protocol_args.appendSliceAssumeCapacity(prefix); |
| 373 | | protocol_args.appendAssumeCapacity(0); |
| 374 | | } |
| 375 | | }, |
| 376 | | .artifact => { |
| 377 | | const prefix = if (arg.prefix.value) |p| p.slice(conf) else ""; |
| 378 | | const suffix = if (arg.suffix.value) |p| p.slice(conf) else ""; |
| 379 | | const producer_index = arg.producer.value.?; |
| 380 | | const producer_step = producer_index.ptr(conf); |
| 381 | | const producer = producer_step.extended.get(conf.extra).compile; |
| 382 | | const producer_make_comp_step = maker.stepByIndex(producer_index); |
| 383 | | const producer_make_comp = &producer_make_comp_step.extended.compile; |
| 384 | | |
| 385 | | const file_path = producer_make_comp.installed_path orelse |
| 386 | | maker.generatedPath(producer.generated_bin.value.?); |
| 387 | | |
| 388 | | try owned_files.resize(gpa, owned_files.bit_length + 1, true); |
| 389 | | try inherit_files.ensureUnusedCapacity(gpa, 1); |
| 390 | | const file = file_path.root_dir.handle.openFile(io, file_path.sub_path, .{}) catch |err| |
| 391 | | return step.fail(maker, "unable to open input artifact {qf}: {t}", .{ file_path, err }); |
| 392 | | inherit_files.appendAssumeCapacity(file); |
| 393 | | |
| 394 | | man.hash.addBytesZ(prefix); |
| 395 | | _ = try man.addInputPath(file_path, .{}); |
| 396 | | man.hash.addBytesZ(suffix); |
| 397 | | |
| 398 | | try protocol_args.ensureUnusedCapacity(gpa, 1 + prefix.len + 1 + |
| 399 | | 1 + @sizeOf(Io.File.Handle) + |
| 400 | | 1 + suffix.len + 1); |
| 401 | | if (prefix.len > 0) { |
| 402 | | protocol_args.appendAssumeCapacity(@backingInt(std.zig.Client.Message.Arg.prefix)); |
| 403 | | protocol_args.appendSliceAssumeCapacity(prefix); |
| 404 | | protocol_args.appendAssumeCapacity(0); |
| 405 | | } |
| 406 | | protocol_args.appendAssumeCapacity(@backingInt(std.zig.Client.Message.Arg.input_file)); |
| 407 | | const file_handle: *align(1) Io.File.Handle = |
| 408 | | @ptrCast(protocol_args.addManyAsArrayAssumeCapacity(@sizeOf(Io.File.Handle))); |
| 409 | | file_handle.* = file.handle; |
| 410 | | if (suffix.len > 0) { |
| 411 | | protocol_args.appendAssumeCapacity(@backingInt(std.zig.Client.Message.Arg.suffix)); |
| 412 | | protocol_args.appendSliceAssumeCapacity(prefix); |
| 413 | | protocol_args.appendAssumeCapacity(0); |
| 414 | | } |
| 415 | | }, |
| 416 | | .output_file => { |
| 417 | | const prefix = if (arg.prefix.value) |p| p.slice(conf) else ""; |
| 418 | | const suffix = if (arg.suffix.value) |p| p.slice(conf) else ""; |
| 419 | | const basename = arg.basename.value.?.slice(conf); |
| 420 | | |
| 421 | | man.hash.addBytesZ(prefix); |
| 422 | | man.hash.addBytesZ(basename); |
| 423 | | man.hash.addBytesZ(suffix); |
| 424 | | assert(!arg.flags.dep_file); |
| 425 | | |
| 426 | | try protocol_args.ensureUnusedCapacity(gpa, 1 + prefix.len + 1 + |
| 427 | | 1 + @sizeOf(Io.File.Handle) + |
| 428 | | 1 + suffix.len + 1); |
| 429 | | if (prefix.len > 0) { |
| 430 | | protocol_args.appendAssumeCapacity(@backingInt(std.zig.Client.Message.Arg.prefix)); |
| 431 | | protocol_args.appendSliceAssumeCapacity(prefix); |
| 432 | | protocol_args.appendAssumeCapacity(0); |
| 433 | | } |
| 434 | | protocol_args.appendAssumeCapacity(@backingInt(std.zig.Client.Message.Arg.output_file)); |
| 435 | | |
| 436 | | // Add a placeholder into the argument list because we need the |
| 437 | | // manifest hash to be updated with all arguments before the |
| 438 | | // object directory is computed. |
| 439 | | try owned_files.resize(gpa, owned_files.bit_length + 1, false); |
| 440 | | try inherit_files.ensureUnusedCapacity(gpa, 1); |
| 441 | | try output_placeholders.append(gpa, .{ |
| 442 | | .index = @intCast(inherit_files.items.len), |
| 443 | | .offset = @intCast(protocol_args.items.len), |
| 444 | | .arg_index = arg_index, |
| 445 | | }); |
| 446 | | _ = inherit_files.addOneAssumeCapacity(); |
| 447 | | |
| 448 | | _ = protocol_args.addManyAsArrayAssumeCapacity(@sizeOf(Io.File.Handle)); |
| 449 | | if (suffix.len > 0) { |
| 450 | | protocol_args.appendAssumeCapacity(@backingInt(std.zig.Client.Message.Arg.suffix)); |
| 451 | | protocol_args.appendSliceAssumeCapacity(prefix); |
| 452 | | protocol_args.appendAssumeCapacity(0); |
| 453 | | } |
| 454 | | }, |
| 455 | | .output_directory => { |
| 456 | | const prefix = if (arg.prefix.value) |p| p.slice(conf) else ""; |
| 457 | | const suffix = if (arg.suffix.value) |p| p.slice(conf) else ""; |
| 458 | | const basename = arg.basename.value.?.slice(conf); |
| 459 | | |
| 460 | | man.hash.addBytesZ(prefix); |
| 461 | | man.hash.addBytesZ(basename); |
| 462 | | man.hash.addBytesZ(suffix); |
| 463 | | assert(!arg.flags.dep_file); |
| 464 | | |
| 465 | | try protocol_args.ensureUnusedCapacity(gpa, 1 + prefix.len + 1 + |
| 466 | | 1 + @sizeOf(Io.Dir.Handle) + |
| 467 | | 1 + suffix.len + 1); |
| 468 | | if (prefix.len > 0) { |
| 469 | | protocol_args.appendAssumeCapacity(@backingInt(std.zig.Client.Message.Arg.prefix)); |
| 470 | | protocol_args.appendSliceAssumeCapacity(prefix); |
| 471 | | protocol_args.appendAssumeCapacity(0); |
| 472 | | } |
| 473 | | protocol_args.appendAssumeCapacity(@backingInt(std.zig.Client.Message.Arg.output_dir)); |
| 474 | | |
| 475 | | // Add a placeholder into the argument list because we need the |
| 476 | | // manifest hash to be updated with all arguments before the |
| 477 | | // object directory is computed. |
| 478 | | try owned_dirs.resize(gpa, owned_dirs.bit_length + 1, false); |
| 479 | | try inherit_dirs.ensureUnusedCapacity(gpa, 1); |
| 480 | | try output_placeholders.append(gpa, .{ |
| 481 | | .index = @intCast(inherit_dirs.items.len), |
| 482 | | .offset = @intCast(protocol_args.items.len), |
| 483 | | .arg_index = arg_index, |
| 484 | | }); |
| 485 | | _ = inherit_dirs.addOneAssumeCapacity(); |
| 528 | if (conf_run.captured_stdout.value) |captured| { |
| 529 | man.hash.addBytes(captured.basename.slice(conf)); |
| 530 | man.hash.add(conf_run.flags.stdout_trim_whitespace); |
| 531 | } |
| 486 | 532 | |
| 487 | | _ = protocol_args.addManyAsArrayAssumeCapacity(@sizeOf(Io.Dir.Handle)); |
| 488 | | if (suffix.len > 0) { |
| 489 | | protocol_args.appendAssumeCapacity(@backingInt(std.zig.Client.Message.Arg.suffix)); |
| 490 | | protocol_args.appendSliceAssumeCapacity(prefix); |
| 491 | | protocol_args.appendAssumeCapacity(0); |
| 492 | | } |
| 493 | | }, |
| 494 | | .passthru => if (maker.run_args) |run_args| { |
| 495 | | man.hash.addListOfBytes(run_args); |
| 533 | if (conf_run.captured_stderr.value) |captured| { |
| 534 | man.hash.addBytes(captured.basename.slice(conf)); |
| 535 | man.hash.add(conf_run.flags.stderr_trim_whitespace); |
| 536 | } |
| 496 | 537 | |
| 497 | | for (run_args) |run_arg| { |
| 498 | | try protocol_args.ensureUnusedCapacity(gpa, 1 + run_arg.len + 1); |
| 499 | | protocol_args.appendAssumeCapacity(@backingInt(std.zig.Client.Message.Arg.string)); |
| 500 | | protocol_args.appendSliceAssumeCapacity(run_arg); |
| 501 | | protocol_args.appendAssumeCapacity(0); |
| 502 | | } |
| 503 | | }, |
| 504 | | .enable_darling => try thirdPartyToggleProtocol(gpa, &man.hash, &protocol_args, conf, graph.enable_darling, arg.prefix.value, arg.suffix.value), |
| 505 | | .enable_qemu => try thirdPartyToggleProtocol(gpa, &man.hash, &protocol_args, conf, graph.enable_qemu, arg.prefix.value, arg.suffix.value), |
| 506 | | .enable_rosetta => try thirdPartyToggleProtocol(gpa, &man.hash, &protocol_args, conf, graph.enable_rosetta, arg.prefix.value, arg.suffix.value), |
| 507 | | .enable_wasmtime => try thirdPartyToggleProtocol(gpa, &man.hash, &protocol_args, conf, graph.enable_wasmtime, arg.prefix.value, arg.suffix.value), |
| 508 | | .enable_wine => try thirdPartyToggleProtocol(gpa, &man.hash, &protocol_args, conf, graph.enable_wine, arg.prefix.value, arg.suffix.value), |
| 509 | | } |
| 510 | | } |
| 511 | | }, |
| 512 | | } |
| 538 | switch (conf_run.flags.stdio) { |
| 539 | .infer_from_args, .inherit, .zig_test, .protocol => {}, |
| 540 | .check => { |
| 541 | man.hash.addBytes(if (conf_run.expect_stderr_exact.value) |bytes| bytes.slice(conf) else ""); |
| 542 | man.hash.addBytes(if (conf_run.expect_stdout_exact.value) |bytes| bytes.slice(conf) else ""); |
| 543 | for (conf_run.expect_stderr_match.slice) |bytes| man.hash.addBytes(bytes.slice(conf)); |
| 544 | for (conf_run.expect_stdout_match.slice) |bytes| man.hash.addBytes(bytes.slice(conf)); |
| 545 | man.hash.add(conf_run.flags2.expect_term_status); |
| 546 | man.hash.addOptional(conf_run.expect_term_value.value); |
| 547 | }, |
| 548 | } |
| 513 | 549 | |
| 514 | | switch (conf_run.stdin.u) { |
| 515 | | .bytes => |bytes| { |
| 516 | | man.hash.addBytes(bytes.slice(conf)); |
| 517 | | }, |
| 518 | | .lazy_path => |lazy_path| { |
| 550 | for (conf_run.file_inputs.slice) |lazy_path| { |
| 519 | 551 | const file_path = try maker.resolveLazyPathIndex(arena, lazy_path, run_index); |
| 520 | 552 | _ = try man.addInputPath(file_path, .{}); |
| 521 | | }, |
| 522 | | .none => {}, |
| 523 | | } |
| 524 | | |
| 525 | | if (conf_run.captured_stdout.value) |captured| { |
| 526 | | man.hash.addBytes(captured.basename.slice(conf)); |
| 527 | | man.hash.add(conf_run.flags.stdout_trim_whitespace); |
| 528 | | } |
| 529 | | |
| 530 | | if (conf_run.captured_stderr.value) |captured| { |
| 531 | | man.hash.addBytes(captured.basename.slice(conf)); |
| 532 | | man.hash.add(conf_run.flags.stderr_trim_whitespace); |
| 533 | | } |
| 553 | } |
| 534 | 554 | |
| 535 | | switch (conf_run.flags.stdio) { |
| 536 | | .infer_from_args, .inherit, .zig_test, .protocol => {}, |
| 537 | | .check => { |
| 538 | | man.hash.addBytes(if (conf_run.expect_stderr_exact.value) |bytes| bytes.slice(conf) else ""); |
| 539 | | man.hash.addBytes(if (conf_run.expect_stdout_exact.value) |bytes| bytes.slice(conf) else ""); |
| 540 | | for (conf_run.expect_stderr_match.slice) |bytes| man.hash.addBytes(bytes.slice(conf)); |
| 541 | | for (conf_run.expect_stdout_match.slice) |bytes| man.hash.addBytes(bytes.slice(conf)); |
| 542 | | man.hash.add(conf_run.flags2.expect_term_status); |
| 543 | | man.hash.addOptional(conf_run.expect_term_value.value); |
| 544 | | }, |
| 545 | | } |
| 555 | if (conf_run.cwd.value) |lazy_path| { |
| 556 | const cwd_path = try maker.resolveLazyPathIndex(arena, lazy_path, run_index); |
| 557 | _ = man.hash.addBytes(try cwd_path.toString(arena)); |
| 558 | } |
| 546 | 559 | |
| 547 | | for (conf_run.file_inputs.slice) |lazy_path| { |
| 548 | | const file_path = try maker.resolveLazyPathIndex(arena, lazy_path, run_index); |
| 549 | | _ = try man.addInputPath(file_path, .{}); |
| 550 | | } |
| 560 | // Whether the Run step has side effects *other than* updating the output arguments. |
| 561 | // When fuzzing we need to always run the test runner to populate fuzz_tests. |
| 562 | const has_side_effects = graph.fuzzing or conf_run.flags.has_side_effects or any_cli_positionals or |
| 563 | switch (conf_run.flags.stdio) { |
| 564 | .infer_from_args => !any_output_args and |
| 565 | conf_run.captured_stdout.value == null and |
| 566 | conf_run.captured_stderr.value == null, |
| 567 | .inherit => true, |
| 568 | .check, .zig_test, .protocol => false, |
| 569 | }; |
| 551 | 570 | |
| 552 | | if (conf_run.cwd.value) |lazy_path| { |
| 553 | | const cwd_path = try maker.resolveLazyPathIndex(arena, lazy_path, run_index); |
| 554 | | _ = man.hash.addBytes(try cwd_path.toString(arena)); |
| 555 | | } |
| 571 | if (!has_side_effects and try step.cacheHitWatched(maker, &man, progress_node)) { |
| 572 | // Cache hit; skip running command. |
| 573 | const digest = man.hitDigestHex(); |
| 574 | try populateGeneratedStdIo(maker, &conf_run, &digest); |
| 575 | try populateGeneratedPaths(maker, output_placeholders.items, &digest); |
| 576 | step.result_cached = true; |
| 577 | return; |
| 578 | } |
| 556 | 579 | |
| 557 | | // Whether the Run step has side effects *other than* updating the output arguments. |
| 558 | | // When fuzzing we need to always run the test runner to populate fuzz_tests. |
| 559 | | const has_side_effects = graph.fuzzing or conf_run.flags.has_side_effects or any_cli_positionals or |
| 560 | | switch (conf_run.flags.stdio) { |
| 561 | | .infer_from_args => !any_output_args and |
| 562 | | conf_run.captured_stdout.value == null and |
| 563 | | conf_run.captured_stderr.value == null, |
| 564 | | .inherit => true, |
| 565 | | .check, .zig_test, .protocol => false, |
| 566 | | }; |
| 580 | if (!any_discovered_inputs) { |
| 581 | // We already know the final output paths; use them directly. |
| 582 | const digest = if (has_side_effects) man.hash.final() else man.missDigestHex(); |
| 583 | const output_dir_path = "o" ++ Dir.path.sep_str ++ &digest; |
| 584 | try populateGeneratedStdIo(maker, &conf_run, &digest); |
| 585 | try populateGeneratedPathsCreateDirs(arena, run_index, maker, output_dir_path, output_placeholders.items, switch (conf_run.flags.stdio) { |
| 586 | .infer_from_args, .inherit, .check, .zig_test => .{ .argv = argv_list.items }, |
| 587 | .protocol => .{ .protocol = .{ |
| 588 | .owned_dirs = &owned_dirs, |
| 589 | .inherit_dirs = inherit_dirs.items, |
| 590 | .owned_files = &owned_files, |
| 591 | .inherit_files = inherit_files.items, |
| 592 | .args = protocol_args.items, |
| 593 | } }, |
| 594 | }); |
| 595 | runCommand(arena, run, run_index, maker, progress_node, argv_list.items, &.{}, &.{}, &.{}, &.{}, null, has_side_effects, output_dir_path, null) catch |err| switch (err) { |
| 596 | else => |e| return e, |
| 597 | error.MakeFailed, error.MakeSkipped => |e| { |
| 598 | try step.setWatchInputsFromManifest(maker, &man); |
| 599 | return e; |
| 600 | }, |
| 601 | }; |
| 602 | if (has_side_effects) { |
| 603 | try step.setWatchInputsFromManifest(maker, &man); |
| 604 | } else { |
| 605 | try step.finalizeManifestAndWatch(maker, &man); |
| 606 | } |
| 607 | return; |
| 608 | } |
| 567 | 609 | |
| 568 | | if (!has_side_effects and try step.cacheHitWatched(maker, &man, progress_node)) { |
| 569 | | // Cache hit; skip running command. |
| 570 | | const digest = man.hitDigestHex(); |
| 571 | | try populateGeneratedStdIo(maker, &conf_run, &digest); |
| 572 | | try populateGeneratedPaths(maker, output_placeholders.items, &digest); |
| 573 | | step.result_cached = true; |
| 574 | | return; |
| 575 | | } |
| 610 | // We do not know the final output paths yet; use temporary directory to run the command. |
| 611 | var rand_int: u64 = undefined; |
| 612 | io.random(@ptrCast(&rand_int)); |
| 613 | tmp_dir_path = ("tmp" ++ Dir.path.sep_str ++ std.fmt.hex(rand_int)).*; |
| 576 | 614 | |
| 577 | | if (!any_discovered_inputs) { |
| 578 | | // We already know the final output paths; use them directly. |
| 579 | | const digest = if (has_side_effects) man.hash.final() else man.missDigestHex(); |
| 580 | | const output_dir_path = "o" ++ Dir.path.sep_str ++ &digest; |
| 581 | | try populateGeneratedStdIo(maker, &conf_run, &digest); |
| 582 | | try populateGeneratedPathsCreateDirs(arena, run_index, maker, output_dir_path, output_placeholders.items, switch (conf_run.flags.stdio) { |
| 615 | try populateGeneratedPathsCreateDirs(arena, run_index, maker, &tmp_dir_path, output_placeholders.items, switch (conf_run.flags.stdio) { |
| 583 | 616 | .infer_from_args, .inherit, .check, .zig_test => .{ .argv = argv_list.items }, |
| 584 | 617 | .protocol => .{ .protocol = .{ |
| 585 | 618 | .owned_dirs = &owned_dirs, |
| ... | ... | @@ -589,57 +622,30 @@ pub fn make( |
| 589 | 622 | .args = protocol_args.items, |
| 590 | 623 | } }, |
| 591 | 624 | }); |
| 592 | | runCommand(arena, run, run_index, maker, progress_node, argv_list.items, &.{}, &.{}, &.{}, &.{}, null, has_side_effects, output_dir_path, null) catch |err| switch (err) { |
| 625 | runCommand( |
| 626 | arena, |
| 627 | run, |
| 628 | run_index, |
| 629 | maker, |
| 630 | progress_node, |
| 631 | argv_list.items, |
| 632 | inherit_dirs.items, |
| 633 | inherit_files.items, |
| 634 | protocol_args.items, |
| 635 | input_dirs.items, |
| 636 | &man, |
| 637 | has_side_effects, |
| 638 | &tmp_dir_path, |
| 639 | null, |
| 640 | ) catch |err| switch (err) { |
| 593 | 641 | else => |e| return e, |
| 594 | 642 | error.MakeFailed, error.MakeSkipped => |e| { |
| 595 | 643 | try step.setWatchInputsFromManifest(maker, &man); |
| 596 | 644 | return e; |
| 597 | 645 | }, |
| 598 | 646 | }; |
| 599 | | if (has_side_effects) { |
| 600 | | try step.setWatchInputsFromManifest(maker, &man); |
| 601 | | } else { |
| 602 | | try step.finalizeManifestAndWatch(maker, &man); |
| 603 | | } |
| 604 | | return; |
| 605 | | } |
| 606 | 647 | |
| 607 | | // We do not know the final output paths yet; use temporary directory to run the command. |
| 608 | | var rand_int: u64 = undefined; |
| 609 | | io.random(@ptrCast(&rand_int)); |
| 610 | | const tmp_dir_path = "tmp" ++ Dir.path.sep_str ++ std.fmt.hex(rand_int); |
| 611 | | |
| 612 | | try populateGeneratedPathsCreateDirs(arena, run_index, maker, tmp_dir_path, output_placeholders.items, switch (conf_run.flags.stdio) { |
| 613 | | .infer_from_args, .inherit, .check, .zig_test => .{ .argv = argv_list.items }, |
| 614 | | .protocol => .{ .protocol = .{ |
| 615 | | .owned_dirs = &owned_dirs, |
| 616 | | .inherit_dirs = inherit_dirs.items, |
| 617 | | .owned_files = &owned_files, |
| 618 | | .inherit_files = inherit_files.items, |
| 619 | | .args = protocol_args.items, |
| 620 | | } }, |
| 621 | | }); |
| 622 | | runCommand( |
| 623 | | arena, |
| 624 | | run, |
| 625 | | run_index, |
| 626 | | maker, |
| 627 | | progress_node, |
| 628 | | argv_list.items, |
| 629 | | inherit_dirs.items, |
| 630 | | inherit_files.items, |
| 631 | | protocol_args.items, |
| 632 | | input_dirs.items, |
| 633 | | &man, |
| 634 | | has_side_effects, |
| 635 | | tmp_dir_path, |
| 636 | | null, |
| 637 | | ) catch |err| switch (err) { |
| 638 | | else => |e| return e, |
| 639 | | error.MakeFailed, error.MakeSkipped => |e| { |
| 640 | | try step.setWatchInputsFromManifest(maker, &man); |
| 641 | | return e; |
| 642 | | }, |
| 648 | break :has_side_effects has_side_effects; |
| 643 | 649 | }; |
| 644 | 650 | |
| 645 | 651 | for (output_placeholders.items) |placeholder| { |
| ... | ... | @@ -686,7 +692,7 @@ pub fn make( |
| 686 | 692 | |
| 687 | 693 | if (any_output) { |
| 688 | 694 | // Rename into place. |
| 689 | | const tmp_path: Path = .{ .root_dir = cache_root, .sub_path = tmp_dir_path }; |
| 695 | const tmp_path: Path = .{ .root_dir = cache_root, .sub_path = &tmp_dir_path }; |
| 690 | 696 | const dst_path: Path = .{ .root_dir = cache_root, .sub_path = "o" ++ Dir.path.sep_str ++ &digest }; |
| 691 | 697 | Dir.rename( |
| 692 | 698 | tmp_path.root_dir.handle, |