diff options
Diffstat (limited to 'build.zig')
| -rw-r--r-- | build.zig | 36 |
1 files changed, 32 insertions, 4 deletions
@@ -1361,6 +1361,34 @@ fn readImage(step: *std.Build.Step, gpa: std.mem.Allocator, path: std.Build.Lazy return step.fail("{s} is not a usable image: {s}", .{ p, @errorName(err) }); } +/// Fail a step that could not open the serial port, and for the one error that is always the same +/// mistake, say what to do about it. +/// +/// `AccessDenied` is the first thing anyone hits: the device is owned by a group (uucp on Arch, +/// dialout on Debian) and the account is not in it. The subtlety worth printing is the SECOND half - +/// adding the group with `usermod -aG` does not affect any shell that is already running, because +/// credentials are captured at login. That produces exactly this error from a user who has already +/// "fixed" it, which is a genuinely confusing place to be. +fn failPort(step: *std.Build.Step, port: []const u8, err: anyerror) anyerror { + if (err != error.AccessDenied) return step.fail("cannot open {s}: {s}", .{ port, @errorName(err) }); + return step.fail( + \\cannot open {s}: AccessDenied + \\ + \\ {s} is owned by a group your session is not in (uucp on Arch, dialout on Debian): + \\ ls -l {s} + \\ + \\ If you are NOT in that group yet, join it and log in again: + \\ sudo usermod -aG uucp $USER + \\ + \\ If `id -nG` already lists it, this shell simply predates the change - group membership + \\ is captured at login. Either log out and back in, or take it in this shell: + \\ newgrp uucp + \\ + \\ Or run one command with the group, without touching this shell at all: + \\ sg uucp -c 'zig build ... ' + , .{ port, port, port }); +} + const FlashStep = struct { step: std.Build.Step, bin: std.Build.LazyPath, @@ -1402,7 +1430,7 @@ const FlashStep = struct { defer port_lock.unlock(b.graph.io); var port = serial.Port.open(self.port, self.baud) catch |err| - return step.fail("cannot open {s}: {s}", .{ self.port, @errorName(err) }); + return failPort(step, self.port, err); defer port.close(); const t_open = port.nowMs(); @@ -1476,7 +1504,7 @@ const MonitorStep = struct { defer port_lock.unlock(b.graph.io); var port = serial.Port.open(self.port, .b115200) catch |err| - return step.fail("cannot open {s}: {s}", .{ self.port, @errorName(err) }); + return failPort(step, self.port, err); defer port.close(); port.resetToRun(.{}) catch {}; @@ -1525,7 +1553,7 @@ const ConsoleStep = struct { defer port_lock.unlock(b.graph.io); console.attach(self.port, self.baud, .{}) catch |err| - return step.fail("console on {s}: {s}", .{ self.port, @errorName(err) }); + return failPort(step, self.port, err); } }; @@ -1550,7 +1578,7 @@ const ResetStep = struct { port_lock.lockUncancelable(b.graph.io); defer port_lock.unlock(b.graph.io); var port = serial.Port.open(self.port, .b115200) catch |err| - return step.fail("cannot open {s}: {s}", .{ self.port, @errorName(err) }); + return failPort(step, self.port, err); defer port.close(); port.resetToRun(.{}) catch |err| return step.fail("reset failed: {s}", .{@errorName(err)}); } |
