| author | |
| committer | |
| log | 4aa8fa898de3847f3a0469edf4484f60c3ecf051 |
| tree | 09cd8a615231a24c19e1d86040b84f5c93d444d2 |
| parent | d9881466382093f3c29ebe3f36a7d09d72407837 |
unless pkg_config == .force, this is supposed to be allowed3 files changed, 59 insertions(+), 37 deletions(-)
lib/compiler/Maker/PkgConfig.zig+23-15| ... | @@ -1,6 +1,7 @@ | ... | @@ -1,6 +1,7 @@ |
| 1 | const std = @import("std"); | 1 | const std = @import("std"); |
| 2 | const Io = std.Io; | 2 | const Io = std.Io; |
| 3 | const mem = std.mem; | 3 | const mem = std.mem; |
| 4 | const assert = std.debug.assert; | ||
| 4 | 5 | ||
| 5 | const Maker = @import("../Maker.zig"); | 6 | const Maker = @import("../Maker.zig"); |
| 6 | const Step = @import("Step.zig"); | 7 | const Step = @import("Step.zig"); |
| ... | @@ -92,14 +93,15 @@ pub fn run( | ... | @@ -92,14 +93,15 @@ pub fn run( |
| 92 | }; | 93 | }; |
| 93 | 94 | ||
| 94 | const pkg_config_exe = getExe(graph); | 95 | const pkg_config_exe = getExe(graph); |
| 95 | const captured = try step.captureChildProcess(maker, progress_node, &.{ | 96 | const stdout = try captureChildProcess(maker, step, .{ |
| 96 | pkg_config_exe, pkg_name, "--cflags", "--libs", | 97 | .argv = &.{ pkg_config_exe, pkg_name, "--cflags", "--libs" }, |
| 98 | .progress_node = progress_node, | ||
| 99 | .allow_failure = !force, | ||
| 97 | }); | 100 | }); |
| 98 | try step.handleChildProcessTerm(maker, captured.term); | ||
| 99 | 101 | ||
| 100 | var zig_cflags: std.ArrayList([]const u8) = .empty; | 102 | var zig_cflags: std.ArrayList([]const u8) = .empty; |
| 101 | var zig_libs: std.ArrayList([]const u8) = .empty; | 103 | var zig_libs: std.ArrayList([]const u8) = .empty; |
| 102 | var arg_it = mem.tokenizeAny(u8, captured.stdout, " \r\n\t"); | 104 | var arg_it = mem.tokenizeAny(u8, stdout, " \r\n\t"); |
| 103 | 105 | ||
| 104 | while (arg_it.next()) |arg| { | 106 | while (arg_it.next()) |arg| { |
| 105 | if (mem.eql(u8, arg, "-I")) { | 107 | if (mem.eql(u8, arg, "-I")) { |
| ... | @@ -168,19 +170,14 @@ fn getList(maker: *Maker, step: *Step, progress_node: std.Progress.Node, force: | ... | @@ -168,19 +170,14 @@ fn getList(maker: *Maker, step: *Step, progress_node: std.Progress.Node, force: |
| 168 | if (pc.list) |list| return list; | 170 | if (pc.list) |list| return list; |
| 169 | 171 | ||
| 170 | const pkg_config_exe = getExe(graph); | 172 | const pkg_config_exe = getExe(graph); |
| 171 | const captured = try step.captureChildProcess(maker, progress_node, &.{ pkg_config_exe, "--list-all" }); | 173 | const stdout = try captureChildProcess(maker, step, .{ |
| 172 | if (force) { | 174 | .argv = &.{ pkg_config_exe, "--list-all" }, |
| 173 | try step.handleChildProcessTerm(maker, captured.term); | 175 | .progress_node = progress_node, |
| 174 | } else switch (captured.term) { | 176 | .allow_failure = !force, |
| 175 | .exited => |code| if (code != 0) return error.PkgConfigUnavailable, | 177 | }); |
| 176 | else => { | ||
| 177 | try step.handleChildProcessTerm(maker, captured.term); | ||
| 178 | unreachable; | ||
| 179 | }, | ||
| 180 | } | ||
| 181 | 178 | ||
| 182 | var list: std.ArrayList(Pkg) = .empty; | 179 | var list: std.ArrayList(Pkg) = .empty; |
| 183 | var line_it = mem.tokenizeAny(u8, captured.stdout, "\r\n"); | 180 | var line_it = mem.tokenizeAny(u8, stdout, "\r\n"); |
| 184 | while (line_it.next()) |line| { | 181 | while (line_it.next()) |line| { |
| 185 | if (mem.trim(u8, line, " \t").len == 0) continue; | 182 | if (mem.trim(u8, line, " \t").len == 0) continue; |
| 186 | var tok_it = mem.tokenizeAny(u8, line, " \t"); | 183 | var tok_it = mem.tokenizeAny(u8, line, " \t"); |
| ... | @@ -200,3 +197,14 @@ fn getList(maker: *Maker, step: *Step, progress_node: std.Progress.Node, force: | ... | @@ -200,3 +197,14 @@ fn getList(maker: *Maker, step: *Step, progress_node: std.Progress.Node, force: |
| 200 | pc.list = result; | 197 | pc.list = result; |
| 201 | return result; | 198 | return result; |
| 202 | } | 199 | } |
| 200 | |||
| 201 | fn captureChildProcess(maker: *Maker, step: *Step, options: Step.CaptureChildProcessOptions) ![]const u8 { | ||
| 202 | const captured = step.captureChildProcess(maker, options) catch |err| switch (err) { | ||
| 203 | error.FileNotFound => return error.PkgConfigUnavailable, | ||
| 204 | else => |e| return e, | ||
| 205 | }; | ||
| 206 | assert(step.result_failed_command != null); | ||
| 207 | if (captured.term.success()) return captured.stdout; | ||
| 208 | if (!options.allow_failure) return step.fail(maker, "{s} {f}", .{ options.argv[0], captured.term }); | ||
| 209 | return error.PkgConfigUnavailable; | ||
| 210 | } |
lib/compiler/Maker/Step.zig+27-21| ... | @@ -329,13 +329,19 @@ pub fn reset(step: *Step, maker: *Maker) void { | ... | @@ -329,13 +329,19 @@ pub fn reset(step: *Step, maker: *Maker) void { |
| 329 | step.result_error_bundle = std.zig.ErrorBundle.empty; | 329 | step.result_error_bundle = std.zig.ErrorBundle.empty; |
| 330 | } | 330 | } |
| 331 | 331 | ||
| 332 | /// Populates `s.result_failed_command`. | 332 | pub const CaptureChildProcessError = error{ |
| 333 | pub fn captureChildProcess( | 333 | FileNotFound, |
| 334 | s: *Step, | 334 | } || ExtendedMakeError; |
| 335 | maker: *Maker, | 335 | |
| 336 | progress_node: std.Progress.Node, | 336 | pub const CaptureChildProcessOptions = struct { |
| 337 | argv: []const []const u8, | 337 | argv: []const []const u8, |
| 338 | ) !std.process.RunResult { | 338 | progress_node: std.Progress.Node = .none, |
| 339 | environ_map: ?*const std.process.Environ.Map = null, | ||
| 340 | allow_failure: bool = false, | ||
| 341 | }; | ||
| 342 | |||
| 343 | /// Populates `s.result_failed_command`. | ||
| 344 | pub fn captureChildProcess(s: *Step, maker: *Maker, options: CaptureChildProcessOptions) !std.process.RunResult { | ||
| 339 | const gpa = maker.gpa; | 345 | const gpa = maker.gpa; |
| 340 | const graph = maker.graph; | 346 | const graph = maker.graph; |
| 341 | const arena = graph.arena; // TODO stop leaking into process arena | 347 | const arena = graph.arena; // TODO stop leaking into process arena |
| ... | @@ -343,20 +349,25 @@ pub fn captureChildProcess( | ... | @@ -343,20 +349,25 @@ pub fn captureChildProcess( |
| 343 | 349 | ||
| 344 | // If an error occurs, it's happened in this command: | 350 | // If an error occurs, it's happened in this command: |
| 345 | assert(s.result_failed_command == null); | 351 | assert(s.result_failed_command == null); |
| 346 | s.result_failed_command = try std.zig.allocPrintCmd(gpa, argv, .{}); | 352 | s.result_failed_command = try std.zig.allocPrintCmd(gpa, options.argv, .{}); |
| 347 | 353 | ||
| 348 | try handleChildProcUnsupported(s, maker); | 354 | try handleChildProcUnsupported(s, maker); |
| 349 | try graph.handleVerbose(.inherit, null, argv); | 355 | try graph.handleVerbose(.inherit, null, options.argv); |
| 350 | 356 | ||
| 351 | const result = std.process.run(arena, io, .{ | 357 | const result = std.process.run(arena, io, .{ |
| 352 | .argv = argv, | 358 | .argv = options.argv, |
| 353 | .environ_map = &graph.environ_map, | 359 | .environ_map = options.environ_map orelse &graph.environ_map, |
| 354 | .progress_node = progress_node, | 360 | .progress_node = options.progress_node, |
| 355 | }) catch |err| return s.fail(maker, "failed to run {s}: {t}", .{ argv[0], err }); | 361 | }) catch |err| { |
| 362 | switch (err) { | ||
| 363 | error.OutOfMemory, error.Canceled => |e| return e, | ||
| 364 | error.FileNotFound => |e| if (options.allow_failure) return e, | ||
| 365 | else => {}, | ||
| 366 | } | ||
| 367 | return s.fail(maker, "failed to run {s}: {t}", .{ options.argv[0], err }); | ||
| 368 | }; | ||
| 356 | 369 | ||
| 357 | if (result.stderr.len > 0) { | 370 | if (result.stderr.len > 0) try s.result_error_msgs.append(arena, result.stderr); |
| 358 | try s.result_error_msgs.append(arena, result.stderr); | ||
| 359 | } | ||
| 360 | 371 | ||
| 361 | return result; | 372 | return result; |
| 362 | } | 373 | } |
| ... | @@ -679,12 +690,7 @@ pub inline fn handleChildProcUnsupported(s: *Step, maker: *Maker) FailError!void | ... | @@ -679,12 +690,7 @@ pub inline fn handleChildProcUnsupported(s: *Step, maker: *Maker) FailError!void |
| 679 | /// Asserts that the caller has already populated `s.result_failed_command`. | 690 | /// Asserts that the caller has already populated `s.result_failed_command`. |
| 680 | pub fn handleChildProcessTerm(s: *Step, maker: *Maker, term: std.process.Child.Term) FailError!void { | 691 | pub fn handleChildProcessTerm(s: *Step, maker: *Maker, term: std.process.Child.Term) FailError!void { |
| 681 | assert(s.result_failed_command != null); | 692 | assert(s.result_failed_command != null); |
| 682 | return switch (term) { | 693 | if (!term.success()) return s.fail(maker, "process {f}", .{term}); |
| 683 | .exited => |code| if (code != 0) s.fail(maker, "process exited with error code {d}", .{code}), | ||
| 684 | .signal => |sig| s.fail(maker, "process terminated with signal {t}", .{sig}), | ||
| 685 | .stopped => |sig| s.fail(maker, "process stopped with signal {t}", .{sig}), | ||
| 686 | .unknown => s.fail(maker, "process terminated unexpectedly", .{}), | ||
| 687 | }; | ||
| 688 | } | 694 | } |
| 689 | 695 | ||
| 690 | /// Prefer `cacheHitAndWatch` unless you already added watch inputs | 696 | /// Prefer `cacheHitAndWatch` unless you already added watch inputs |
lib/compiler/Maker/Step/Fmt.zig+9-1| ... | @@ -43,7 +43,15 @@ pub fn make( | ... | @@ -43,7 +43,15 @@ pub fn make( |
| 43 | argv.appendAssumeCapacity(try maker.resolveLazyPathIndexAbs(arena, lp, step_index)); | 43 | argv.appendAssumeCapacity(try maker.resolveLazyPathIndexAbs(arena, lp, step_index)); |
| 44 | } | 44 | } |
| 45 | 45 | ||
| 46 | const run_result = try step.captureChildProcess(maker, progress_node, argv.items); | 46 | const run_result = step.captureChildProcess(maker, .{ |
| 47 | .progress_node = progress_node, | ||
| 48 | .argv = argv.items, | ||
| 49 | .allow_failure = false, | ||
| 50 | }) catch |err| switch (err) { | ||
| 51 | error.FileNotFound => unreachable, | ||
| 52 | else => |e| return e, | ||
| 53 | }; | ||
| 54 | |||
| 47 | if (conf_fmt.flags.check) switch (run_result.term) { | 55 | if (conf_fmt.flags.check) switch (run_result.term) { |
| 48 | .exited => |code| if (code != 0 and run_result.stdout.len != 0) { | 56 | .exited => |code| if (code != 0 and run_result.stdout.len != 0) { |
| 49 | var it = std.mem.tokenizeScalar(u8, run_result.stdout, '\n'); | 57 | var it = std.mem.tokenizeScalar(u8, run_result.stdout, '\n'); |