Wails v2.11 defaults to webkit2gtk-4.0 and takes 4.1 only when told —
#cgo !webkit2_41 pkg-config: webkit2gtk-4.0
#cgo webkit2_41 pkg-config: webkit2gtk-4.1
— and both the script and the doc had it the other way round: they
treated 4.1 as the default and offered a -tags webkit2_40 that does not
select anything. On a Debian 13 box, which ships only 4.1, the script
therefore detected 4.1, reported it as fine, passed no tag, ran npm for
several minutes and then stopped in cgo with "Package webkit2gtk-4.0 was
not found in the pkg-config search path".
Written from the Wails source rather than from memory this time, which
is where it should have come from in the first place.
libsoup is checked alongside, since it travels with the choice: 4.0
pairs with libsoup-2.4 and 4.1 with libsoup-3.0, and a missing one fails
the same way at the same late moment.
Both found on a real trixie box, which is the first time any of this has
run on Linux.
Go can be too NEW, and that is the harder failure to meet cold. The
Wails CLI parses this package with the golang.org/x/tools its own go.mod
pins, and that release cannot read the export data a newer compiler
writes. With go1.27 — which is simply what go.dev offers as current —
the build dies with
internal error: package "math" without types was imported from
"hamlog/internal/geo"
naming neither Go nor Wails nor anything an operator could act on. The
setup script now says so when it sees 1.27 or later, and the doc tells
people to take 1.26 rather than the latest. Every version in both is
1.26.3, which is what the Windows build uses.
And the sound-server check was asking the wrong question. It ran `pactl
info`, but pactl comes from pulseaudio-utils, a package that has nothing
to do with whether a server is running — so a Debian 13 desktop with
PipeWire working perfectly was told it had no sound server. OpsLog
speaks the PulseAudio protocol itself and connects to the native socket,
so the socket is what the check looks for now, with pactl used only to
print the server's name when it happens to be there. It also says to run
from the desktop session rather than over SSH, the socket belonging to
the logged-in session.
Measured rather than guessed: the whole repository was cross-compiled for
linux/amd64 and the gaps closed one by one. There were fewer than expected.
Flex and TCI were never Windows-specific — they carried //go:build windows by
inheritance and import nothing but net and gorilla/websocket. Untagged, no code
change. The two backends a Linux operator is most likely to own were already
portable.
Audio was 560 lines, not 2287: only devices.go and engine.go touch WASAPI, while
manager.go, recorder.go, wav.go and mp3.go were pure Go wearing the tag by
association. The whole platform surface is seven functions, now implemented a
second time on PulseAudio through github.com/jfreymuth/pulse — pure Go over the
server socket, so the no-cgo rule survives, and PipeWire answers the same
protocol. The fixed 16 kHz mono format and the server-side resampling mirror
what AUTOCONVERTPCM does on Windows, for the same reason.
OmniRig is the only real loss, and its backend still EXISTS off Windows rather
than being compiled out of app.go: a settings database is portable, so an
operator moving a profile across keeps "omnirig" saved and must be told to pick
a native backend instead of meeting a nil one.
The parts where Linux is not Windows, and where a compile-only stub would have
been a silent bug:
- data dir: still beside the binary, but ~/.local/share/OpsLog/data when that
folder belongs to the system — decided by trying the write, because /opt and
/usr/local are writable on some stations and not others.
- single instance: an flock, not a pid file. The kernel drops it however the
process dies, so a crash leaves nothing to delete by hand. This is the guard
that stops two instances fighting over the rig frequency.
- update: simpler here. Unix renames over a running binary, so the deferred
swap the Windows path needs a detached helper for is unreachable.
- tasklist/taskkill become /proc and SIGTERM; the boot log moves out of /tmp,
which is wiped exactly when the evidence is wanted.
- serial ports sorted naturally: /dev/ttyUSB10 was landing between USB1 and
USB2, the same trap COM10 fell into.
release.ps1 now cross-builds and vets for linux before it builds the exe, and
refuses the release if that fails — a port rots one unguarded x/sys/windows call
at a time.
Nothing has been executed on Linux yet: Wails needs webkit2gtk and cgo there, so
the binary must be built on Linux. scripts/linux-setup.sh checks the machine and
does it; BUILDING-LINUX.md is the manual version.
Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>