| 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 | 1 | const std = @import("std"); |
| 2 | 2 | const Io = std.Io; |
| 3 | 3 | const mem = std.mem; |
| 4 | const assert = std.debug.assert; | |
| 4 | 5 | |
| 5 | 6 | const Maker = @import("../Maker.zig"); |
| 6 | 7 | const Step = @import("Step.zig"); |
| ... | ... | @@ -92,14 +93,15 @@ pub fn run( |
| 92 | 93 | }; |
| 93 | 94 | |
| 94 | 95 | const pkg_config_exe = getExe(graph); |
| 95 | const captured = try step.captureChildProcess(maker, progress_node, &.{ | |
| 96 | pkg_config_exe, pkg_name, "--cflags", "--libs", | |
| 96 | const stdout = try captureChildProcess(maker, step, .{ | |
| 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 | 102 | var zig_cflags: std.ArrayList([]const u8) = .empty; |
| 101 | 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 | 106 | while (arg_it.next()) |arg| { |
| 105 | 107 | if (mem.eql(u8, arg, "-I")) { |
| ... | ... | @@ -168,19 +170,14 @@ fn getList(maker: *Maker, step: *Step, progress_node: std.Progress.Node, force: |
| 168 | 170 | if (pc.list) |list| return list; |
| 169 | 171 | |
| 170 | 172 | const pkg_config_exe = getExe(graph); |
| 171 | const captured = try step.captureChildProcess(maker, progress_node, &.{ pkg_config_exe, "--list-all" }); | |
| 172 | if (force) { | |
| 173 | try step.handleChildProcessTerm(maker, captured.term); | |
| 174 | } else switch (captured.term) { | |
| 175 | .exited => |code| if (code != 0) return error.PkgConfigUnavailable, | |
| 176 | else => { | |
| 177 | try step.handleChildProcessTerm(maker, captured.term); | |
| 178 | unreachable; | |
| 179 | }, | |
| 180 | } | |
| 173 | const stdout = try captureChildProcess(maker, step, .{ | |
| 174 | .argv = &.{ pkg_config_exe, "--list-all" }, | |
| 175 | .progress_node = progress_node, | |
| 176 | .allow_failure = !force, | |
| 177 | }); | |
| 181 | 178 | |
| 182 | 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 | 181 | while (line_it.next()) |line| { |
| 185 | 182 | if (mem.trim(u8, line, " \t").len == 0) continue; |
| 186 | 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 | 197 | pc.list = result; |
| 201 | 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 | 329 | step.result_error_bundle = std.zig.ErrorBundle.empty; |
| 330 | 330 | } |
| 331 | 331 | |
| 332 | /// Populates `s.result_failed_command`. | |
| 333 | pub fn captureChildProcess( | |
| 334 | s: *Step, | |
| 335 | maker: *Maker, | |
| 336 | progress_node: std.Progress.Node, | |
| 332 | pub const CaptureChildProcessError = error{ | |
| 333 | FileNotFound, | |
| 334 | } || ExtendedMakeError; | |
| 335 | ||
| 336 | pub const CaptureChildProcessOptions = struct { | |
| 337 | 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 | 345 | const gpa = maker.gpa; |
| 340 | 346 | const graph = maker.graph; |
| 341 | 347 | const arena = graph.arena; // TODO stop leaking into process arena |
| ... | ... | @@ -343,20 +349,25 @@ pub fn captureChildProcess( |
| 343 | 349 | |
| 344 | 350 | // If an error occurs, it's happened in this command: |
| 345 | 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 | 354 | try handleChildProcUnsupported(s, maker); |
| 349 | try graph.handleVerbose(.inherit, null, argv); | |
| 355 | try graph.handleVerbose(.inherit, null, options.argv); | |
| 350 | 356 | |
| 351 | 357 | const result = std.process.run(arena, io, .{ |
| 352 | .argv = argv, | |
| 353 | .environ_map = &graph.environ_map, | |
| 354 | .progress_node = progress_node, | |
| 355 | }) catch |err| return s.fail(maker, "failed to run {s}: {t}", .{ argv[0], err }); | |
| 358 | .argv = options.argv, | |
| 359 | .environ_map = options.environ_map orelse &graph.environ_map, | |
| 360 | .progress_node = options.progress_node, | |
| 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) { | |
| 358 | try s.result_error_msgs.append(arena, result.stderr); | |
| 359 | } | |
| 370 | if (result.stderr.len > 0) try s.result_error_msgs.append(arena, result.stderr); | |
| 360 | 371 | |
| 361 | 372 | return result; |
| 362 | 373 | } |
| ... | ... | @@ -679,12 +690,7 @@ pub inline fn handleChildProcUnsupported(s: *Step, maker: *Maker) FailError!void |
| 679 | 690 | /// Asserts that the caller has already populated `s.result_failed_command`. |
| 680 | 691 | pub fn handleChildProcessTerm(s: *Step, maker: *Maker, term: std.process.Child.Term) FailError!void { |
| 681 | 692 | assert(s.result_failed_command != null); |
| 682 | return switch (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 | }; | |
| 693 | if (!term.success()) return s.fail(maker, "process {f}", .{term}); | |
| 688 | 694 | } |
| 689 | 695 | |
| 690 | 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 | 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 | 55 | if (conf_fmt.flags.check) switch (run_result.term) { |
| 48 | 56 | .exited => |code| if (code != 0 and run_result.stdout.len != 0) { |
| 49 | 57 | var it = std.mem.tokenizeScalar(u8, run_result.stdout, '\n'); |