| ... | @@ -12,6 +12,7 @@ const Path = std.Build.Cache.Path; | ... | @@ -12,6 +12,7 @@ const Path = std.Build.Cache.Path; |
| 12 | const assert = std.debug.assert; | 12 | const assert = std.debug.assert; |
| 13 | const mem = std.mem; | 13 | const mem = std.mem; |
| 14 | const process = std.process; | 14 | const process = std.process; |
| | 15 | const allocPrint = std.fmt.allocPrint; |
| 15 | | 16 | |
| 16 | const Step = @import("../Step.zig"); | 17 | const Step = @import("../Step.zig"); |
| 17 | const Maker = @import("../../Maker.zig"); | 18 | const Maker = @import("../../Maker.zig"); |
| ... | @@ -26,115 +27,158 @@ cached_test_metadata: ?CachedTestMetadata = null, | ... | @@ -26,115 +27,158 @@ cached_test_metadata: ?CachedTestMetadata = null, |
| 26 | /// executable that contains fuzz tests. | 27 | /// executable that contains fuzz tests. |
| 27 | rebuilt_executable: ?Path = null, | 28 | rebuilt_executable: ?Path = null, |
| 28 | | 29 | |
| | 30 | /// Persisted to reuse memory on subsequent calls to `make`. |
| | 31 | argv: std.ArrayList([]const u8) = .empty, |
| | 32 | /// Persisted to reuse memory on subsequent calls to `make`. |
| | 33 | output_placeholders: std.ArrayList(IndexedOutput) = .empty, |
| | 34 | |
| 29 | pub fn make( | 35 | pub fn make( |
| 30 | run: *Run, | 36 | run: *Run, |
| 31 | step_index: Configuration.Step.Index, | 37 | run_index: Configuration.Step.Index, |
| 32 | maker: *Maker, | 38 | maker: *Maker, |
| 33 | progress_node: std.Progress.Node, | 39 | progress_node: std.Progress.Node, |
| 34 | ) Step.ExtendedMakeError!void { | 40 | ) Step.ExtendedMakeError!void { |
| 35 | if (true) @panic("TODO implement run.make()"); | | |
| 36 | const graph = maker.graph; | 41 | const graph = maker.graph; |
| 37 | const step = maker.stepByIndex(step_index); | 42 | const gpa = maker.gpa; |
| | 43 | const step = maker.stepByIndex(run_index); |
| 38 | const io = graph.io; | 44 | const io = graph.io; |
| 39 | const arena = graph.arena; // TODO don't leak into the process arena | 45 | const arena = graph.arena; // TODO don't leak into the process arena |
| 40 | const has_side_effects = run.hasSideEffects(); | 46 | const conf = &maker.scanned_config.configuration; |
| | 47 | const conf_step = run_index.ptr(conf); |
| | 48 | const conf_run = conf_step.extended.get(conf.extra).run; |
| | 49 | const argv_list = &run.argv; |
| | 50 | const output_placeholders = &run.output_placeholders; |
| 41 | | 51 | |
| 42 | var argv_list = std.array_list.Managed([]const u8).init(arena); | 52 | argv_list.clearRetainingCapacity(); |
| 43 | var output_placeholders = std.array_list.Managed(IndexedOutput).init(arena); | 53 | output_placeholders.clearRetainingCapacity(); |
| 44 | | 54 | |
| 45 | var man = graph.cache.obtain(); | 55 | var man = graph.cache.obtain(); |
| 46 | defer man.deinit(); | 56 | defer man.deinit(); |
| 47 | | 57 | |
| 48 | if (run.environ_map) |environ_map| { | 58 | if (conf_run.environ_map.value) |environ_map_index| { |
| 49 | for (environ_map.keys(), environ_map.values()) |key, value| { | 59 | const environ_map = environ_map_index.get(conf); |
| 50 | man.hash.addBytes(key); | 60 | for (environ_map.keys.slice(conf), environ_map.values.slice(conf)) |key, value| { |
| 51 | man.hash.addBytes(value); | 61 | man.hash.addBytesZ(key.slice(conf)); |
| | 62 | man.hash.addBytesZ(value.slice(conf)); |
| 52 | } | 63 | } |
| 53 | } | 64 | } |
| 54 | | 65 | |
| 55 | man.hash.add(run.color); | 66 | man.hash.add(conf_run.flags.color); |
| 56 | man.hash.add(run.disable_zig_progress); | 67 | man.hash.add(conf_run.flags.disable_zig_progress); |
| 57 | | 68 | |
| 58 | for (run.argv.items) |arg| { | 69 | for (conf_run.args.slice) |arg_index| { |
| 59 | switch (arg) { | 70 | const arg = arg_index.get(conf); |
| 60 | .bytes => |bytes| { | 71 | try argv_list.ensureUnusedCapacity(gpa, 1); |
| 61 | try argv_list.append(bytes); | 72 | switch (arg.flags.tag) { |
| 62 | man.hash.addBytes(bytes); | 73 | .string => { |
| | 74 | const prefix = arg.prefix.value.?.slice(conf); |
| | 75 | argv_list.appendAssumeCapacity(prefix); |
| | 76 | man.hash.addBytesZ(prefix); |
| 63 | }, | 77 | }, |
| 64 | .lazy_path => |file| { | 78 | .path_file => { |
| 65 | const file_path = file.lazy_path.getPath3(graph, step); | 79 | const prefix = if (arg.prefix.value) |p| p.slice(conf) else ""; |
| 66 | try argv_list.append(graph.fmt("{s}{s}", .{ file.prefix, run.convertPathArg(maker, file_path) })); | 80 | const suffix = if (arg.suffix.value) |p| p.slice(conf) else ""; |
| 67 | man.hash.addBytes(file.prefix); | 81 | const file_path = try maker.resolveLazyPathIndex(arena, arg.path.value.?, run_index); |
| | 82 | argv_list.appendAssumeCapacity(try mem.concat(arena, u8, &.{ |
| | 83 | prefix, try convertPathArg(run_index, maker, file_path), suffix, |
| | 84 | })); |
| | 85 | man.hash.addBytesZ(prefix); |
| | 86 | man.hash.addBytesZ(suffix); |
| 68 | _ = try man.addFilePath(file_path, null); | 87 | _ = try man.addFilePath(file_path, null); |
| 69 | }, | 88 | }, |
| 70 | .decorated_directory => |dd| { | 89 | .path_directory => { |
| 71 | const file_path = dd.lazy_path.getPath3(graph, step); | 90 | const prefix = if (arg.prefix.value) |p| p.slice(conf) else ""; |
| 72 | const resolved_arg = graph.fmt("{s}{s}{s}", .{ dd.prefix, run.convertPathArg(maker, file_path), dd.suffix }); | 91 | const suffix = if (arg.suffix.value) |p| p.slice(conf) else ""; |
| 73 | try argv_list.append(resolved_arg); | 92 | const file_path = try maker.resolveLazyPathIndex(arena, arg.path.value.?, run_index); |
| | 93 | const resolved_arg = try mem.concat(arena, u8, &.{ |
| | 94 | prefix, try convertPathArg(run_index, maker, file_path), suffix, |
| | 95 | }); |
| | 96 | argv_list.appendAssumeCapacity(resolved_arg); |
| 74 | man.hash.addBytes(resolved_arg); | 97 | man.hash.addBytes(resolved_arg); |
| 75 | }, | 98 | }, |
| 76 | .file_content => |file_plp| { | 99 | .file_content => { |
| 77 | const file_path = file_plp.lazy_path.getPath3(graph, step); | 100 | const prefix = if (arg.prefix.value) |p| p.slice(conf) else ""; |
| | 101 | const suffix = if (arg.suffix.value) |p| p.slice(conf) else ""; |
| | 102 | const file_path = try maker.resolveLazyPathIndex(arena, arg.path.value.?, run_index); |
| 78 | | 103 | |
| 79 | var result: std.Io.Writer.Allocating = .init(arena); | 104 | var result: std.Io.Writer.Allocating = .init(arena); |
| 80 | errdefer result.deinit(); | 105 | result.writer.writeAll(prefix) catch return error.OutOfMemory; |
| 81 | result.writer.writeAll(file_plp.prefix) catch return error.OutOfMemory; | | |
| 82 | | 106 | |
| 83 | const file = file_path.root_dir.handle.openFile(io, file_path.subPathOrDot(), .{}) catch |err| { | 107 | const file = file_path.root_dir.handle.openFile(io, file_path.sub_path, .{}) catch |err| |
| 84 | return step.fail( | 108 | return step.fail(maker, "unable to open input file {f}: {t}", .{ file_path, err }); |
| 85 | "unable to open input file '{f}': {t}", | | |
| 86 | .{ file_path, err }, | | |
| 87 | ); | | |
| 88 | }; | | |
| 89 | defer file.close(io); | 109 | defer file.close(io); |
| 90 | | 110 | |
| 91 | var buf: [1024]u8 = undefined; | 111 | var file_reader = file.reader(io, &.{}); |
| 92 | var file_reader = file.reader(io, &buf); | | |
| 93 | _ = file_reader.interface.streamRemaining(&result.writer) catch |err| switch (err) { | 112 | _ = file_reader.interface.streamRemaining(&result.writer) catch |err| switch (err) { |
| 94 | error.ReadFailed => return step.fail( | 113 | error.ReadFailed => switch (file_reader.err.?) { |
| 95 | "failed to read from '{f}': {t}", | 114 | error.Canceled => |e| return e, |
| 96 | .{ file_path, file_reader.err.? }, | 115 | else => |e| return step.fail(maker, "failed to read from {f}: {t}", .{ file_path, e }), |
| 97 | ), | 116 | }, |
| 98 | error.WriteFailed => return error.OutOfMemory, | 117 | error.WriteFailed => return error.OutOfMemory, |
| 99 | }; | 118 | }; |
| | 119 | result.writer.writeAll(suffix) catch return error.OutOfMemory; |
| 100 | | 120 | |
| 101 | try argv_list.append(result.written()); | 121 | argv_list.appendAssumeCapacity(result.written()); |
| 102 | man.hash.addBytes(file_plp.prefix); | 122 | man.hash.addBytesZ(prefix); |
| | 123 | man.hash.addBytesZ(suffix); |
| 103 | _ = try man.addFilePath(file_path, null); | 124 | _ = try man.addFilePath(file_path, null); |
| 104 | }, | 125 | }, |
| 105 | .artifact => |pa| { | 126 | .artifact => { |
| 106 | const artifact = pa.artifact; | 127 | const prefix = if (arg.prefix.value) |p| p.slice(conf) else ""; |
| 107 | | 128 | const suffix = if (arg.suffix.value) |p| p.slice(conf) else ""; |
| 108 | if (artifact.rootModuleTarget().os.tag == .windows) { | 129 | const producer_index = arg.producer.value.?; |
| | 130 | const producer_step = producer_index.ptr(conf); |
| | 131 | const producer = producer_step.extended.get(conf.extra).compile; |
| | 132 | const root_module = producer.root_module.get(conf); |
| | 133 | const root_module_target = root_module.resolved_target.get(conf).?.result.get(conf); |
| | 134 | const os_tag = root_module_target.flags.os_tag.unwrap().?; |
| | 135 | |
| | 136 | if (true) @panic("TODO"); |
| | 137 | |
| | 138 | if (os_tag == .windows) { |
| 109 | // On Windows we don't have rpaths so we have to add .dll search paths to PATH | 139 | // On Windows we don't have rpaths so we have to add .dll search paths to PATH |
| 110 | addPathForDynLibs(artifact); | 140 | addPathForDynLibs(producer_index); |
| 111 | } | 141 | } |
| 112 | const file_path = artifact.installed_path orelse artifact.generated_bin.?.path.?; | 142 | const file_path = producer_index.installed_path orelse producer_index.generated_bin.?.path.?; |
| 113 | | 143 | |
| 114 | try argv_list.append(graph.fmt("{s}{s}", .{ | 144 | argv_list.appendAssumeCapacity(try mem.concat(arena, u8, &.{ |
| 115 | pa.prefix, | 145 | prefix, |
| 116 | run.convertPathArg(maker, .{ .root_dir = .cwd(), .sub_path = file_path }), | 146 | try convertPathArg(run_index, maker, .{ .root_dir = .cwd(), .sub_path = file_path }), |
| | 147 | suffix, |
| 117 | })); | 148 | })); |
| 118 | | 149 | |
| 119 | _ = try man.addFile(file_path, null); | 150 | _ = try man.addFile(file_path, null); |
| 120 | }, | 151 | }, |
| 121 | .output_file, .output_directory => |output| { | 152 | .output_file, .output_directory => { |
| 122 | man.hash.addBytes(output.prefix); | 153 | const prefix = if (arg.prefix.value) |p| p.slice(conf) else ""; |
| 123 | man.hash.addBytes(output.basename); | 154 | const suffix = if (arg.suffix.value) |p| p.slice(conf) else ""; |
| | 155 | const basename = arg.basename.value.?.slice(conf); |
| | 156 | |
| | 157 | man.hash.addBytesZ(prefix); |
| | 158 | man.hash.addBytesZ(basename); |
| | 159 | man.hash.addBytesZ(suffix); |
| | 160 | |
| 124 | // Add a placeholder into the argument list because we need the | 161 | // Add a placeholder into the argument list because we need the |
| 125 | // manifest hash to be updated with all arguments before the | 162 | // manifest hash to be updated with all arguments before the |
| 126 | // object directory is computed. | 163 | // object directory is computed. |
| 127 | try output_placeholders.append(.{ | 164 | try output_placeholders.append(gpa, .{ |
| 128 | .index = argv_list.items.len, | 165 | .index = @intCast(argv_list.items.len), |
| 129 | .tag = arg, | 166 | .arg_index = arg_index, |
| 130 | .output = output, | | |
| 131 | }); | 167 | }); |
| 132 | _ = try argv_list.addOne(); | 168 | argv_list.items.len += 1; |
| | 169 | }, |
| | 170 | .cli_rest_positionals => { |
| | 171 | if (maker.run_args) |run_args| { |
| | 172 | try argv_list.appendSlice(gpa, run_args); |
| | 173 | for (run_args) |s| man.hash.addBytes(s); |
| | 174 | } |
| 133 | }, | 175 | }, |
| 134 | } | 176 | } |
| 135 | } | 177 | } |
| 136 | | 178 | |
| 137 | switch (run.stdin) { | 179 | if (true) @panic("TODO"); |
| | 180 | |
| | 181 | switch (conf_run.stdin.u) { |
| 138 | .bytes => |bytes| { | 182 | .bytes => |bytes| { |
| 139 | man.hash.addBytes(bytes); | 183 | man.hash.addBytes(bytes); |
| 140 | }, | 184 | }, |
| ... | @@ -145,28 +189,30 @@ pub fn make( | ... | @@ -145,28 +189,30 @@ pub fn make( |
| 145 | .none => {}, | 189 | .none => {}, |
| 146 | } | 190 | } |
| 147 | | 191 | |
| 148 | if (run.captured_stdout) |captured| { | 192 | if (conf_run.captured_stdout) |captured| { |
| 149 | man.hash.addBytes(captured.output.basename); | 193 | man.hash.addBytes(captured.output.basename); |
| 150 | man.hash.add(captured.trim_whitespace); | 194 | man.hash.add(captured.trim_whitespace); |
| 151 | } | 195 | } |
| 152 | | 196 | |
| 153 | if (run.captured_stderr) |captured| { | 197 | if (conf_run.captured_stderr) |captured| { |
| 154 | man.hash.addBytes(captured.output.basename); | 198 | man.hash.addBytes(captured.output.basename); |
| 155 | man.hash.add(captured.trim_whitespace); | 199 | man.hash.add(captured.trim_whitespace); |
| 156 | } | 200 | } |
| 157 | | 201 | |
| 158 | std.log.err("TODO hashStdIo", .{}); | 202 | std.log.err("TODO hashStdIo", .{}); |
| 159 | //hashStdIo(&man.hash, run.stdio); | 203 | //hashStdIo(&man.hash, conf_run.stdio); |
| 160 | | 204 | |
| 161 | for (run.file_inputs.items) |lazy_path| { | 205 | for (conf_run.file_inputs.items) |lazy_path| { |
| 162 | _ = try man.addFile(lazy_path.getPath2(graph, step), null); | 206 | _ = try man.addFile(lazy_path.getPath2(graph, step), null); |
| 163 | } | 207 | } |
| 164 | | 208 | |
| 165 | if (run.cwd) |cwd| { | 209 | if (conf_run.cwd) |cwd| { |
| 166 | const cwd_path = cwd.getPath3(graph, step); | 210 | const cwd_path = cwd.getPath3(graph, step); |
| 167 | _ = man.hash.addBytes(try cwd_path.toString(arena)); | 211 | _ = man.hash.addBytes(try cwd_path.toString(arena)); |
| 168 | } | 212 | } |
| 169 | | 213 | |
| | 214 | const has_side_effects = conf_run.flags.has_side_effects; |
| | 215 | |
| 170 | if (!has_side_effects and try step.cacheHitAndWatch(&man)) { | 216 | if (!has_side_effects and try step.cacheHitAndWatch(&man)) { |
| 171 | // cache hit, skip running command | 217 | // cache hit, skip running command |
| 172 | const digest = man.final(); | 218 | const digest = man.final(); |
| ... | @@ -182,7 +228,7 @@ pub fn make( | ... | @@ -182,7 +228,7 @@ pub fn make( |
| 182 | return; | 228 | return; |
| 183 | } | 229 | } |
| 184 | | 230 | |
| 185 | const dep_output_file = run.dep_output_file orelse { | 231 | const dep_output_file = conf_run.dep_output_file orelse { |
| 186 | // We already know the final output paths, use them directly. | 232 | // We already know the final output paths, use them directly. |
| 187 | const digest = if (has_side_effects) | 233 | const digest = if (has_side_effects) |
| 188 | man.hash.final() | 234 | man.hash.final() |
| ... | @@ -205,18 +251,18 @@ pub fn make( | ... | @@ -205,18 +251,18 @@ pub fn make( |
| 205 | else => unreachable, | 251 | else => unreachable, |
| 206 | }; | 252 | }; |
| 207 | graph.cache_root.handle.createDirPath(io, output_sub_dir_path) catch |err| { | 253 | graph.cache_root.handle.createDirPath(io, output_sub_dir_path) catch |err| { |
| 208 | return step.fail("unable to make path '{f}{s}': {t}", .{ | 254 | return step.fail(maker, "unable to make path '{f}{s}': {t}", .{ |
| 209 | graph.cache_root, output_sub_dir_path, err, | 255 | graph.cache_root, output_sub_dir_path, err, |
| 210 | }); | 256 | }); |
| 211 | }; | 257 | }; |
| 212 | const arg_output_path = run.convertPathArg(maker, .{ | 258 | const arg_output_path = try convertPathArg(run_index, maker, .{ |
| 213 | .root_dir = .cwd(), | 259 | .root_dir = .cwd(), |
| 214 | .sub_path = placeholder.output.generated_file.getPath(), | 260 | .sub_path = placeholder.output.generated_file.getPath(), |
| 215 | }); | 261 | }); |
| 216 | argv_list.items[placeholder.index] = if (placeholder.output.prefix.len == 0) | 262 | argv_list.items[placeholder.index] = if (placeholder.output.prefix.len == 0) |
| 217 | arg_output_path | 263 | arg_output_path |
| 218 | else | 264 | else |
| 219 | graph.fmt("{s}{s}", .{ placeholder.output.prefix, arg_output_path }); | 265 | try allocPrint(arena, "{s}{s}", .{ placeholder.output.prefix, arg_output_path }); |
| 220 | } | 266 | } |
| 221 | | 267 | |
| 222 | try runCommand(run, maker, progress_node, argv_list.items, has_side_effects, output_dir_path, null); | 268 | try runCommand(run, maker, progress_node, argv_list.items, has_side_effects, output_dir_path, null); |
| ... | @@ -238,7 +284,7 @@ pub fn make( | ... | @@ -238,7 +284,7 @@ pub fn make( |
| 238 | else => unreachable, | 284 | else => unreachable, |
| 239 | }; | 285 | }; |
| 240 | graph.cache_root.handle.createDirPath(io, output_sub_dir_path) catch |err| { | 286 | graph.cache_root.handle.createDirPath(io, output_sub_dir_path) catch |err| { |
| 241 | return step.fail("unable to make path '{f}{s}': {t}", .{ | 287 | return step.fail(maker, "unable to make path '{f}{s}': {t}", .{ |
| 242 | graph.cache_root, output_sub_dir_path, err, | 288 | graph.cache_root, output_sub_dir_path, err, |
| 243 | }); | 289 | }); |
| 244 | }; | 290 | }; |
| ... | @@ -247,9 +293,9 @@ pub fn make( | ... | @@ -247,9 +293,9 @@ pub fn make( |
| 247 | .sub_path = graph.pathJoin(&output_components), | 293 | .sub_path = graph.pathJoin(&output_components), |
| 248 | }; | 294 | }; |
| 249 | placeholder.output.generated_file.path = raw_output_path.toString(arena) catch @panic("OOM"); | 295 | placeholder.output.generated_file.path = raw_output_path.toString(arena) catch @panic("OOM"); |
| 250 | argv_list.items[placeholder.index] = graph.fmt("{s}{s}", .{ | 296 | argv_list.items[placeholder.index] = try mem.concat(arena, u8, .{ |
| 251 | placeholder.output.prefix, | 297 | placeholder.output.prefix, |
| 252 | run.convertPathArg(maker, raw_output_path), | 298 | try convertPathArg(run_index, maker, raw_output_path), |
| 253 | }); | 299 | }); |
| 254 | } | 300 | } |
| 255 | | 301 | |
| ... | @@ -268,7 +314,7 @@ pub fn make( | ... | @@ -268,7 +314,7 @@ pub fn make( |
| 268 | man.final(); | 314 | man.final(); |
| 269 | | 315 | |
| 270 | const any_output = output_placeholders.items.len > 0 or | 316 | const any_output = output_placeholders.items.len > 0 or |
| 271 | run.captured_stdout != null or run.captured_stderr != null; | 317 | conf_run.captured_stdout != null or conf_run.captured_stderr != null; |
| 272 | | 318 | |
| 273 | // Rename into place | 319 | // Rename into place |
| 274 | if (any_output) { | 320 | if (any_output) { |
| ... | @@ -277,17 +323,17 @@ pub fn make( | ... | @@ -277,17 +323,17 @@ pub fn make( |
| 277 | graph.cache_root.handle.rename(tmp_dir_path, graph.cache_root.handle, o_sub_path, io) catch |err| switch (err) { | 323 | graph.cache_root.handle.rename(tmp_dir_path, graph.cache_root.handle, o_sub_path, io) catch |err| switch (err) { |
| 278 | Dir.RenameError.DirNotEmpty => { | 324 | Dir.RenameError.DirNotEmpty => { |
| 279 | graph.cache_root.handle.deleteTree(io, o_sub_path) catch |del_err| { | 325 | graph.cache_root.handle.deleteTree(io, o_sub_path) catch |del_err| { |
| 280 | return step.fail("unable to remove dir '{f}'{s}: {t}", .{ | 326 | return step.fail(maker, "unable to remove dir '{f}'{s}: {t}", .{ |
| 281 | graph.cache_root, tmp_dir_path, del_err, | 327 | graph.cache_root, tmp_dir_path, del_err, |
| 282 | }); | 328 | }); |
| 283 | }; | 329 | }; |
| 284 | graph.cache_root.handle.rename(tmp_dir_path, graph.cache_root.handle, o_sub_path, io) catch |retry_err| { | 330 | graph.cache_root.handle.rename(tmp_dir_path, graph.cache_root.handle, o_sub_path, io) catch |retry_err| { |
| 285 | return step.fail("unable to rename dir '{f}{s}' to '{f}{s}': {t}", .{ | 331 | return step.fail(maker, "unable to rename dir '{f}{s}' to '{f}{s}': {t}", .{ |
| 286 | graph.cache_root, tmp_dir_path, graph.cache_root, o_sub_path, retry_err, | 332 | graph.cache_root, tmp_dir_path, graph.cache_root, o_sub_path, retry_err, |
| 287 | }); | 333 | }); |
| 288 | }; | 334 | }; |
| 289 | }, | 335 | }, |
| 290 | else => return step.fail("unable to rename dir '{f}{s}' to '{f}{s}': {t}", .{ | 336 | else => return step.fail(maker, "unable to rename dir '{f}{s}' to '{f}{s}': {t}", .{ |
| 291 | graph.cache_root, tmp_dir_path, graph.cache_root, o_sub_path, err, | 337 | graph.cache_root, tmp_dir_path, graph.cache_root, o_sub_path, err, |
| 292 | }), | 338 | }), |
| 293 | }; | 339 | }; |
| ... | @@ -309,6 +355,7 @@ pub fn make( | ... | @@ -309,6 +355,7 @@ pub fn make( |
| 309 | /// * The wait fails, indicating the child closed stdout and stderr | 355 | /// * The wait fails, indicating the child closed stdout and stderr |
| 310 | fn waitZigTest( | 356 | fn waitZigTest( |
| 311 | run: *Run, | 357 | run: *Run, |
| | 358 | maker: *Maker, |
| 312 | child: *process.Child, | 359 | child: *process.Child, |
| 313 | options: Step.MakeOptions, | 360 | options: Step.MakeOptions, |
| 314 | multi_reader: *Io.File.MultiReader, | 361 | multi_reader: *Io.File.MultiReader, |
| ... | @@ -412,6 +459,7 @@ fn waitZigTest( | ... | @@ -412,6 +459,7 @@ fn waitZigTest( |
| 412 | switch (header.tag) { | 459 | switch (header.tag) { |
| 413 | .zig_version => { | 460 | .zig_version => { |
| 414 | if (!std.mem.eql(u8, builtin.zig_version_string, body)) return run.step.fail( | 461 | if (!std.mem.eql(u8, builtin.zig_version_string, body)) return run.step.fail( |
| | 462 | maker, |
| 415 | "zig version mismatch build runner vs compiler: '{s}' vs '{s}'", | 463 | "zig version mismatch build runner vs compiler: '{s}' vs '{s}'", |
| 416 | .{ builtin.zig_version_string, body }, | 464 | .{ builtin.zig_version_string, body }, |
| 417 | ); | 465 | ); |
| ... | @@ -1028,6 +1076,7 @@ const StdioPollEnum = enum { stdout, stderr }; | ... | @@ -1028,6 +1076,7 @@ const StdioPollEnum = enum { stdout, stderr }; |
| 1028 | | 1076 | |
| 1029 | fn evalZigTest( | 1077 | fn evalZigTest( |
| 1030 | run: *Run, | 1078 | run: *Run, |
| | 1079 | maker: *Maker, |
| 1031 | spawn_options: process.SpawnOptions, | 1080 | spawn_options: process.SpawnOptions, |
| 1032 | options: Step.MakeOptions, | 1081 | options: Step.MakeOptions, |
| 1033 | fuzz_context: ?FuzzContext, | 1082 | fuzz_context: ?FuzzContext, |
| ... | @@ -1102,7 +1151,7 @@ fn evalZigTest( | ... | @@ -1102,7 +1151,7 @@ fn evalZigTest( |
| 1102 | | 1151 | |
| 1103 | // The individual unit test results are irrelevant: the test runner itself broke! | 1152 | // The individual unit test results are irrelevant: the test runner itself broke! |
| 1104 | // Fail immediately without populating `s.test_results`. | 1153 | // Fail immediately without populating `s.test_results`. |
| 1105 | return run.step.fail("unable to write stdin ({t}); test process unexpectedly {f}", .{ err, fmtTerm(term) }); | 1154 | return run.step.fail(maker, "unable to write stdin ({t}); test process unexpectedly {f}", .{ err, fmtTerm(term) }); |
| 1106 | }, | 1155 | }, |
| 1107 | .no_poll => |no_poll| { | 1156 | .no_poll => |no_poll| { |
| 1108 | // This might be a success (we requested exit and the child dutifully closed stdout) or | 1157 | // This might be a success (we requested exit and the child dutifully closed stdout) or |
| ... | @@ -1141,7 +1190,7 @@ fn evalZigTest( | ... | @@ -1141,7 +1190,7 @@ fn evalZigTest( |
| 1141 | if (!tests_done or !termMatches(.{ .exited = 0 }, term)) { | 1190 | if (!tests_done or !termMatches(.{ .exited = 0 }, term)) { |
| 1142 | // The individual unit test results are irrelevant: the test runner itself broke! | 1191 | // The individual unit test results are irrelevant: the test runner itself broke! |
| 1143 | // Fail immediately without populating `s.test_results`. | 1192 | // Fail immediately without populating `s.test_results`. |
| 1144 | return run.step.fail("test process unexpectedly {f}", .{fmtTerm(term)}); | 1193 | return run.step.fail(maker, "test process unexpectedly {f}", .{fmtTerm(term)}); |
| 1145 | } | 1194 | } |
| 1146 | | 1195 | |
| 1147 | // We're done with all of the tests! Commit the test results and return. | 1196 | // We're done with all of the tests! Commit the test results and return. |
| ... | @@ -1181,7 +1230,7 @@ fn evalZigTest( | ... | @@ -1181,7 +1230,7 @@ fn evalZigTest( |
| 1181 | run.step.result_stderr = try arena.dupe(u8, stderr); | 1230 | run.step.result_stderr = try arena.dupe(u8, stderr); |
| 1182 | // The individual unit test results in `results` are irrelevant: the test runner | 1231 | // The individual unit test results in `results` are irrelevant: the test runner |
| 1183 | // is broken! Fail immediately without populating `s.test_results`. | 1232 | // is broken! Fail immediately without populating `s.test_results`. |
| 1184 | return run.step.fail("test runner failed to respond for {f}", .{Io.Duration{ .nanoseconds = timeout.ns_elapsed }}); | 1233 | return run.step.fail(maker, "test runner failed to respond for {f}", .{Io.Duration{ .nanoseconds = timeout.ns_elapsed }}); |
| 1185 | }, | 1234 | }, |
| 1186 | } | 1235 | } |
| 1187 | comptime unreachable; | 1236 | comptime unreachable; |
| ... | @@ -1313,7 +1362,7 @@ fn evalGeneric(run: *Run, maker: *Maker, spawn_options: process.SpawnOptions) !E | ... | @@ -1313,7 +1362,7 @@ fn evalGeneric(run: *Run, maker: *Maker, spawn_options: process.SpawnOptions) !E |
| 1313 | switch (run.stdin) { | 1362 | switch (run.stdin) { |
| 1314 | .bytes => |bytes| { | 1363 | .bytes => |bytes| { |
| 1315 | child.stdin.?.writeStreamingAll(io, bytes) catch |err| { | 1364 | child.stdin.?.writeStreamingAll(io, bytes) catch |err| { |
| 1316 | return run.step.fail("unable to write stdin: {t}", .{err}); | 1365 | return run.step.fail(maker, "unable to write stdin: {t}", .{err}); |
| 1317 | }; | 1366 | }; |
| 1318 | child.stdin.?.close(io); | 1367 | child.stdin.?.close(io); |
| 1319 | child.stdin = null; | 1368 | child.stdin = null; |
| ... | @@ -1321,7 +1370,7 @@ fn evalGeneric(run: *Run, maker: *Maker, spawn_options: process.SpawnOptions) !E | ... | @@ -1321,7 +1370,7 @@ fn evalGeneric(run: *Run, maker: *Maker, spawn_options: process.SpawnOptions) !E |
| 1321 | .lazy_path => |lazy_path| { | 1370 | .lazy_path => |lazy_path| { |
| 1322 | const path = lazy_path.getPath3(graph, &run.step); | 1371 | const path = lazy_path.getPath3(graph, &run.step); |
| 1323 | const file = path.root_dir.handle.openFile(io, path.subPathOrDot(), .{}) catch |err| { | 1372 | const file = path.root_dir.handle.openFile(io, path.subPathOrDot(), .{}) catch |err| { |
| 1324 | return run.step.fail("unable to open stdin file: {t}", .{err}); | 1373 | return run.step.fail(maker, "unable to open stdin file: {t}", .{err}); |
| 1325 | }; | 1374 | }; |
| 1326 | defer file.close(io); | 1375 | defer file.close(io); |
| 1327 | // TODO https://github.com/ziglang/zig/issues/23955 | 1376 | // TODO https://github.com/ziglang/zig/issues/23955 |
| ... | @@ -1330,15 +1379,15 @@ fn evalGeneric(run: *Run, maker: *Maker, spawn_options: process.SpawnOptions) !E | ... | @@ -1330,15 +1379,15 @@ fn evalGeneric(run: *Run, maker: *Maker, spawn_options: process.SpawnOptions) !E |
| 1330 | var write_buffer: [1024]u8 = undefined; | 1379 | var write_buffer: [1024]u8 = undefined; |
| 1331 | var stdin_writer = child.stdin.?.writerStreaming(io, &write_buffer); | 1380 | var stdin_writer = child.stdin.?.writerStreaming(io, &write_buffer); |
| 1332 | _ = stdin_writer.interface.sendFileAll(&file_reader, .unlimited) catch |err| switch (err) { | 1381 | _ = stdin_writer.interface.sendFileAll(&file_reader, .unlimited) catch |err| switch (err) { |
| 1333 | error.ReadFailed => return run.step.fail("failed to read from {f}: {t}", .{ | 1382 | error.ReadFailed => return run.step.fail(maker, "failed to read from {f}: {t}", .{ |
| 1334 | path, file_reader.err.?, | 1383 | path, file_reader.err.?, |
| 1335 | }), | 1384 | }), |
| 1336 | error.WriteFailed => return run.step.fail("failed to write to stdin: {t}", .{ | 1385 | error.WriteFailed => return run.step.fail(maker, "failed to write to stdin: {t}", .{ |
| 1337 | stdin_writer.err.?, | 1386 | stdin_writer.err.?, |
| 1338 | }), | 1387 | }), |
| 1339 | }; | 1388 | }; |
| 1340 | stdin_writer.interface.flush() catch |err| switch (err) { | 1389 | stdin_writer.interface.flush() catch |err| switch (err) { |
| 1341 | error.WriteFailed => return run.step.fail("failed to write to stdin: {t}", .{ | 1390 | error.WriteFailed => return run.step.fail(maker, "failed to write to stdin: {t}", .{ |
| 1342 | stdin_writer.err.?, | 1391 | stdin_writer.err.?, |
| 1343 | }), | 1392 | }), |
| 1344 | }; | 1393 | }; |
| ... | @@ -1418,15 +1467,13 @@ fn evalGeneric(run: *Run, maker: *Maker, spawn_options: process.SpawnOptions) !E | ... | @@ -1418,15 +1467,13 @@ fn evalGeneric(run: *Run, maker: *Maker, spawn_options: process.SpawnOptions) !E |
| 1418 | } | 1467 | } |
| 1419 | | 1468 | |
| 1420 | const IndexedOutput = struct { | 1469 | const IndexedOutput = struct { |
| 1421 | index: usize, | 1470 | index: u32, |
| 1422 | tag: Configuration.Step.Run.Arg.Tag, | 1471 | arg_index: Configuration.Step.Run.Arg.Index, |
| 1423 | output: *Output, | | |
| 1424 | }; | 1472 | }; |
| 1425 | | 1473 | |
| 1426 | const Output = void; // TODO | | |
| 1427 | | | |
| 1428 | pub fn rerunInFuzzMode( | 1474 | pub fn rerunInFuzzMode( |
| 1429 | run: *Run, | 1475 | run: *Run, |
| | 1476 | run_index: Configuration.Step.Index, |
| 1430 | fuzz: *std.Build.Fuzz, | 1477 | fuzz: *std.Build.Fuzz, |
| 1431 | prog_node: std.Progress.Node, | 1478 | prog_node: std.Progress.Node, |
| 1432 | ) !void { | 1479 | ) !void { |
| ... | @@ -1444,11 +1491,11 @@ pub fn rerunInFuzzMode( | ... | @@ -1444,11 +1491,11 @@ pub fn rerunInFuzzMode( |
| 1444 | }, | 1491 | }, |
| 1445 | .lazy_path => |file| { | 1492 | .lazy_path => |file| { |
| 1446 | const file_path = file.lazy_path.getPath3(b, step); | 1493 | const file_path = file.lazy_path.getPath3(b, step); |
| 1447 | try argv_list.append(arena, b.fmt("{s}{s}", .{ file.prefix, run.convertPathArg(maker, file_path) })); | 1494 | try argv_list.append(arena, b.fmt("{s}{s}", .{ file.prefix, convertPathArg(run_index, maker, file_path) })); |
| 1448 | }, | 1495 | }, |
| 1449 | .decorated_directory => |dd| { | 1496 | .decorated_directory => |dd| { |
| 1450 | const file_path = dd.lazy_path.getPath3(b, step); | 1497 | const file_path = dd.lazy_path.getPath3(b, step); |
| 1451 | try argv_list.append(arena, b.fmt("{s}{s}{s}", .{ dd.prefix, run.convertPathArg(maker, file_path), dd.suffix })); | 1498 | try argv_list.append(arena, b.fmt("{s}{s}{s}", .{ dd.prefix, convertPathArg(run_index, maker, file_path), dd.suffix })); |
| 1452 | }, | 1499 | }, |
| 1453 | .file_content => |file_plp| { | 1500 | .file_content => |file_plp| { |
| 1454 | const file_path = file_plp.lazy_path.getPath3(b, step); | 1501 | const file_path = file_plp.lazy_path.getPath3(b, step); |
| ... | @@ -1477,7 +1524,7 @@ pub fn rerunInFuzzMode( | ... | @@ -1477,7 +1524,7 @@ pub fn rerunInFuzzMode( |
| 1477 | }; | 1524 | }; |
| 1478 | try argv_list.append(arena, b.fmt("{s}{s}", .{ | 1525 | try argv_list.append(arena, b.fmt("{s}{s}", .{ |
| 1479 | pa.prefix, | 1526 | pa.prefix, |
| 1480 | run.convertPathArg(maker, .{ .root_dir = .cwd(), .sub_path = file_path }), | 1527 | convertPathArg(run_index, maker, .{ .root_dir = .cwd(), .sub_path = file_path }), |
| 1481 | })); | 1528 | })); |
| 1482 | }, | 1529 | }, |
| 1483 | .output_file, .output_directory => unreachable, | 1530 | .output_file, .output_directory => unreachable, |
| ... | @@ -1675,7 +1722,7 @@ fn runCommand( | ... | @@ -1675,7 +1722,7 @@ fn runCommand( |
| 1675 | | 1722 | |
| 1676 | const host_dl = graph.host.result.dynamic_linker.get() orelse "(none)"; | 1723 | const host_dl = graph.host.result.dynamic_linker.get() orelse "(none)"; |
| 1677 | | 1724 | |
| 1678 | return step.fail( | 1725 | return step.fail(maker, |
| 1679 | \\the host system is unable to execute binaries from the target | 1726 | \\the host system is unable to execute binaries from the target |
| 1680 | \\ because the host dynamic linker is '{s}', | 1727 | \\ because the host dynamic linker is '{s}', |
| 1681 | \\ while the target dynamic linker is '{s}'. | 1728 | \\ while the target dynamic linker is '{s}'. |
| ... | @@ -1688,7 +1735,7 @@ fn runCommand( | ... | @@ -1688,7 +1735,7 @@ fn runCommand( |
| 1688 | const host_name = try graph.host.result.zigTriple(b.allocator); | 1735 | const host_name = try graph.host.result.zigTriple(b.allocator); |
| 1689 | const foreign_name = try root_target.zigTriple(b.allocator); | 1736 | const foreign_name = try root_target.zigTriple(b.allocator); |
| 1690 | | 1737 | |
| 1691 | return step.fail("the host system ({s}) is unable to execute binaries from the target ({s})", .{ | 1738 | return step.fail(maker, "the host system ({s}) is unable to execute binaries from the target ({s})", .{ |
| 1692 | host_name, foreign_name, | 1739 | host_name, foreign_name, |
| 1693 | }); | 1740 | }); |
| 1694 | }, | 1741 | }, |
| ... | @@ -1706,12 +1753,12 @@ fn runCommand( | ... | @@ -1706,12 +1753,12 @@ fn runCommand( |
| 1706 | break :term spawnChildAndCollect(run, maker, progress_node, interp_argv.items, &environ_map, has_side_effects, fuzz_context) catch |e| { | 1753 | break :term spawnChildAndCollect(run, maker, progress_node, interp_argv.items, &environ_map, has_side_effects, fuzz_context) catch |e| { |
| 1707 | if (!run.failing_to_execute_foreign_is_an_error) return error.MakeSkipped; | 1754 | if (!run.failing_to_execute_foreign_is_an_error) return error.MakeSkipped; |
| 1708 | if (e == error.MakeFailed) return error.MakeFailed; // error already reported | 1755 | if (e == error.MakeFailed) return error.MakeFailed; // error already reported |
| 1709 | return step.fail("unable to spawn interpreter {s}: {t}", .{ interp_argv.items[0], e }); | 1756 | return step.fail(maker, "unable to spawn interpreter {s}: {t}", .{ interp_argv.items[0], e }); |
| 1710 | }; | 1757 | }; |
| 1711 | } | 1758 | } |
| 1712 | if (err == error.MakeFailed) return error.MakeFailed; // error already reported | 1759 | if (err == error.MakeFailed) return error.MakeFailed; // error already reported |
| 1713 | | 1760 | |
| 1714 | return step.fail("failed to spawn and capture stdio from {s}: {t}", .{ argv[0], err }); | 1761 | return step.fail(maker, "failed to spawn and capture stdio from {s}: {t}", .{ argv[0], err }); |
| 1715 | }; | 1762 | }; |
| 1716 | | 1763 | |
| 1717 | const generic_result = opt_generic_result orelse { | 1764 | const generic_result = opt_generic_result orelse { |
| ... | @@ -1748,7 +1795,7 @@ fn runCommand( | ... | @@ -1748,7 +1795,7 @@ fn runCommand( |
| 1748 | const sub_path = b.pathJoin(&output_components); | 1795 | const sub_path = b.pathJoin(&output_components); |
| 1749 | const sub_path_dirname = Dir.path.dirname(sub_path).?; | 1796 | const sub_path_dirname = Dir.path.dirname(sub_path).?; |
| 1750 | b.cache_root.handle.createDirPath(io, sub_path_dirname) catch |err| { | 1797 | b.cache_root.handle.createDirPath(io, sub_path_dirname) catch |err| { |
| 1751 | return step.fail("unable to make path '{f}{s}': {s}", .{ | 1798 | return step.fail(maker, "unable to make path '{f}{s}': {s}", .{ |
| 1752 | b.cache_root, sub_path_dirname, @errorName(err), | 1799 | b.cache_root, sub_path_dirname, @errorName(err), |
| 1753 | }); | 1800 | }); |
| 1754 | }; | 1801 | }; |
| ... | @@ -1759,7 +1806,7 @@ fn runCommand( | ... | @@ -1759,7 +1806,7 @@ fn runCommand( |
| 1759 | .trailing => mem.trimEnd(u8, stream.bytes.?, &std.ascii.whitespace), | 1806 | .trailing => mem.trimEnd(u8, stream.bytes.?, &std.ascii.whitespace), |
| 1760 | }; | 1807 | }; |
| 1761 | b.cache_root.handle.writeFile(io, .{ .sub_path = sub_path, .data = data }) catch |err| { | 1808 | b.cache_root.handle.writeFile(io, .{ .sub_path = sub_path, .data = data }) catch |err| { |
| 1762 | return step.fail("unable to write file '{f}{s}': {s}", .{ | 1809 | return step.fail(maker, "unable to write file '{f}{s}': {s}", .{ |
| 1763 | b.cache_root, sub_path, @errorName(err), | 1810 | b.cache_root, sub_path, @errorName(err), |
| 1764 | }); | 1811 | }); |
| 1765 | }; | 1812 | }; |
| ... | @@ -1771,7 +1818,7 @@ fn runCommand( | ... | @@ -1771,7 +1818,7 @@ fn runCommand( |
| 1771 | .check => |checks| for (checks.items) |check| switch (check) { | 1818 | .check => |checks| for (checks.items) |check| switch (check) { |
| 1772 | .expect_stderr_exact => |expected_bytes| { | 1819 | .expect_stderr_exact => |expected_bytes| { |
| 1773 | if (!mem.eql(u8, expected_bytes, generic_result.stderr.?)) { | 1820 | if (!mem.eql(u8, expected_bytes, generic_result.stderr.?)) { |
| 1774 | return step.fail( | 1821 | return step.fail(maker, |
| 1775 | \\========= expected this stderr: ========= | 1822 | \\========= expected this stderr: ========= |
| 1776 | \\{s} | 1823 | \\{s} |
| 1777 | \\========= but found: ==================== | 1824 | \\========= but found: ==================== |
| ... | @@ -1784,7 +1831,7 @@ fn runCommand( | ... | @@ -1784,7 +1831,7 @@ fn runCommand( |
| 1784 | }, | 1831 | }, |
| 1785 | .expect_stderr_match => |match| { | 1832 | .expect_stderr_match => |match| { |
| 1786 | if (mem.find(u8, generic_result.stderr.?, match) == null) { | 1833 | if (mem.find(u8, generic_result.stderr.?, match) == null) { |
| 1787 | return step.fail( | 1834 | return step.fail(maker, |
| 1788 | \\========= expected to find in stderr: ========= | 1835 | \\========= expected to find in stderr: ========= |
| 1789 | \\{s} | 1836 | \\{s} |
| 1790 | \\========= but stderr does not contain it: ===== | 1837 | \\========= but stderr does not contain it: ===== |
| ... | @@ -1797,7 +1844,7 @@ fn runCommand( | ... | @@ -1797,7 +1844,7 @@ fn runCommand( |
| 1797 | }, | 1844 | }, |
| 1798 | .expect_stdout_exact => |expected_bytes| { | 1845 | .expect_stdout_exact => |expected_bytes| { |
| 1799 | if (!mem.eql(u8, expected_bytes, generic_result.stdout.?)) { | 1846 | if (!mem.eql(u8, expected_bytes, generic_result.stdout.?)) { |
| 1800 | return step.fail( | 1847 | return step.fail(maker, |
| 1801 | \\========= expected this stdout: ========= | 1848 | \\========= expected this stdout: ========= |
| 1802 | \\{s} | 1849 | \\{s} |
| 1803 | \\========= but found: ==================== | 1850 | \\========= but found: ==================== |
| ... | @@ -1810,7 +1857,7 @@ fn runCommand( | ... | @@ -1810,7 +1857,7 @@ fn runCommand( |
| 1810 | }, | 1857 | }, |
| 1811 | .expect_stdout_match => |match| { | 1858 | .expect_stdout_match => |match| { |
| 1812 | if (mem.find(u8, generic_result.stdout.?, match) == null) { | 1859 | if (mem.find(u8, generic_result.stdout.?, match) == null) { |
| 1813 | return step.fail( | 1860 | return step.fail(maker, |
| 1814 | \\========= expected to find in stdout: ========= | 1861 | \\========= expected to find in stdout: ========= |
| 1815 | \\{s} | 1862 | \\{s} |
| 1816 | \\========= but stdout does not contain it: ===== | 1863 | \\========= but stdout does not contain it: ===== |
| ... | @@ -1823,7 +1870,7 @@ fn runCommand( | ... | @@ -1823,7 +1870,7 @@ fn runCommand( |
| 1823 | }, | 1870 | }, |
| 1824 | .expect_term => |expected_term| { | 1871 | .expect_term => |expected_term| { |
| 1825 | if (!termMatches(expected_term, generic_result.term)) { | 1872 | if (!termMatches(expected_term, generic_result.term)) { |
| 1826 | return step.fail("process {f} (expected {f})", .{ | 1873 | return step.fail(maker, "process {f} (expected {f})", .{ |
| 1827 | fmtTerm(generic_result.term), | 1874 | fmtTerm(generic_result.term), |
| 1828 | fmtTerm(expected_term), | 1875 | fmtTerm(expected_term), |
| 1829 | }); | 1876 | }); |
| ... | @@ -2069,21 +2116,23 @@ fn hasAnyOutputArgs(run: Run) bool { | ... | @@ -2069,21 +2116,23 @@ fn hasAnyOutputArgs(run: Run) bool { |
| 2069 | /// | 2116 | /// |
| 2070 | /// Whenever a path is included in the argv of a child, it should be put through this function first | 2117 | /// Whenever a path is included in the argv of a child, it should be put through this function first |
| 2071 | /// to make sure the child doesn't see paths relative to a cwd other than its own. | 2118 | /// to make sure the child doesn't see paths relative to a cwd other than its own. |
| 2072 | fn convertPathArg(run: *Run, maker: *Maker, path: Path) []const u8 { | 2119 | fn convertPathArg(run_index: Configuration.Step.Index, maker: *Maker, path: Path) ![]const u8 { |
| 2073 | const b = run.step.owner; | 2120 | const conf = &maker.scanned_config.configuration; |
| | 2121 | const conf_step = run_index.ptr(conf); |
| | 2122 | const conf_run = conf_step.extended.get(conf.extra).run; |
| 2074 | const graph = maker.graph; | 2123 | const graph = maker.graph; |
| 2075 | const arena = graph.arena; | 2124 | const arena = graph.arena; // TODO don't leak into process arena |
| 2076 | | 2125 | |
| 2077 | const path_str = path.toString(arena) catch @panic("OOM"); | 2126 | const path_str = try path.toString(arena); |
| 2078 | if (Dir.path.isAbsolute(path_str)) { | 2127 | if (Dir.path.isAbsolute(path_str)) { |
| 2079 | // Absolute paths don't need changing. | 2128 | // Absolute paths don't need changing. |
| 2080 | return path_str; | 2129 | return path_str; |
| 2081 | } | 2130 | } |
| 2082 | const child_cwd_rel: []const u8 = rel: { | 2131 | const child_cwd_rel: []const u8 = rel: { |
| 2083 | const child_lazy_cwd = run.cwd orelse break :rel path_str; | 2132 | const child_lazy_cwd = conf_run.cwd.value orelse break :rel path_str; |
| 2084 | const child_cwd = child_lazy_cwd.getPath3(b, &run.step).toString(arena) catch @panic("OOM"); | 2133 | const child_cwd = try maker.resolveLazyPathIndexAbs(arena, child_lazy_cwd, run_index); |
| 2085 | // Convert it from relative to *our* cwd, to relative to the *child's* cwd. | 2134 | // Convert it from relative to *our* cwd, to relative to the *child's* cwd. |
| 2086 | break :rel Dir.path.relative(arena, graph.cache.cwd, &graph.environ_map, child_cwd, path_str) catch @panic("OOM"); | 2135 | break :rel try Dir.path.relative(arena, graph.cache.cwd, &graph.environ_map, child_cwd, path_str); |
| 2087 | }; | 2136 | }; |
| 2088 | // Not every path can be made relative, e.g. if the path and the child cwd are on different | 2137 | // Not every path can be made relative, e.g. if the path and the child cwd are on different |
| 2089 | // disk designators on Windows. In that case, `relative` will return an absolute path which we can | 2138 | // disk designators on Windows. In that case, `relative` will return an absolute path which we can |
| ... | @@ -2094,10 +2143,10 @@ fn convertPathArg(run: *Run, maker: *Maker, path: Path) []const u8 { | ... | @@ -2094,10 +2143,10 @@ fn convertPathArg(run: *Run, maker: *Maker, path: Path) []const u8 { |
| 2094 | // * On POSIX, the executable name cannot be a single component like 'foo' | 2143 | // * On POSIX, the executable name cannot be a single component like 'foo' |
| 2095 | // * Some executables might treat a leading '-' like a flag, which we must avoid | 2144 | // * Some executables might treat a leading '-' like a flag, which we must avoid |
| 2096 | // There's no harm in it, so just *always* apply this prefix. | 2145 | // There's no harm in it, so just *always* apply this prefix. |
| 2097 | return Dir.path.join(arena, &.{ ".", child_cwd_rel }) catch @panic("OOM"); | 2146 | return Dir.path.join(arena, &.{ ".", child_cwd_rel }); |
| 2098 | } | 2147 | } |
| 2099 | | 2148 | |
| 2100 | fn addPathForDynLibs(artifact: *Step.Compile) void { | 2149 | fn addPathForDynLibs(artifact: Configuration.Step.Index) void { |
| 2101 | if (true) @panic("TODO"); | 2150 | if (true) @panic("TODO"); |
| 2102 | for (artifact.getCompileDependencies(true)) |compile| { | 2151 | for (artifact.getCompileDependencies(true)) |compile| { |
| 2103 | if (compile.root_module.resolved_target.?.result.os.tag == .windows and | 2152 | if (compile.root_module.resolved_target.?.result.os.tag == .windows and |
| ... | @@ -2127,13 +2176,13 @@ fn failForeign( | ... | @@ -2127,13 +2176,13 @@ fn failForeign( |
| 2127 | const host_name = try graph.host.result.zigTriple(process_arena); | 2176 | const host_name = try graph.host.result.zigTriple(process_arena); |
| 2128 | const foreign_name = try exe.rootModuleTarget().zigTriple(process_arena); | 2177 | const foreign_name = try exe.rootModuleTarget().zigTriple(process_arena); |
| 2129 | | 2178 | |
| 2130 | return step.fail( | 2179 | return step.fail(maker, |
| 2131 | \\unable to spawn foreign binary '{s}' ({s}) on host system ({s}) | 2180 | \\unable to spawn foreign binary '{s}' ({s}) on host system ({s}) |
| 2132 | \\ consider using {s} or enabling skip_foreign_checks in the Run step | 2181 | \\ consider using {s} or enabling skip_foreign_checks in the Run step |
| 2133 | , .{ argv0, foreign_name, host_name, suggested_flag }); | 2182 | , .{ argv0, foreign_name, host_name, suggested_flag }); |
| 2134 | }, | 2183 | }, |
| 2135 | else => { | 2184 | else => { |
| 2136 | return step.fail("unable to spawn foreign binary '{s}'", .{argv0}); | 2185 | return step.fail(maker, "unable to spawn foreign binary '{s}'", .{argv0}); |
| 2137 | }, | 2186 | }, |
| 2138 | } | 2187 | } |
| 2139 | } | 2188 | } |