Release matrix: Linux, Windows, macOS and FreeBSD

Drop android (same binary as linux/arm64), big-endian ppc64 (cannot be
verified: even hello-world crashes under qemu-ppc64 with the cross
toolchain), NetBSD (cross 0.2.5's sysroot lacks libexecinfo), illumos,
Solaris and WASI, as agreed. docs/PLATFORMS.md records each decision.

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Andy Dixon
2026-10-08 12:40:30 +01:00
co-authored by Claude
parent 7506c1dbef
commit 25496ddb97
6 changed files with 56 additions and 93 deletions
+2 -2
View File
@@ -92,8 +92,8 @@ Command line:
- `ls`/`list` piped into a reader that stops early end quietly with
status 141, as Go's did by `SIGPIPE`.
Platforms: see `PLATFORMS.md`. Some targets Go built have no stable Rust
equivalent; they are listed there and need a decision before release.
Platforms: releases now cover Linux, Windows, macOS and FreeBSD (16
binaries, down from 43); `PLATFORMS.md` lists what was dropped and why.
## Unchanged on purpose
+27 -45
View File
@@ -1,8 +1,8 @@
# Platforms
The Go version was built for every target of `go tool dist list` that needs
no cgo: 43 binaries. Rust supports fewer operating systems and CPUs with a
prebuilt, stable standard library. This is the target-by-target record:
no cgo: 43 binaries. The Rust release is narrower by decision (Linux,
Windows, macOS, FreeBSD): 16 binaries. This is the target-by-target record:
how each is built, and how far it has actually been verified. "Runtime" means
a binary was executed; "build" means it only compiled and linked.
@@ -14,7 +14,10 @@ x86-64. `scripts/smoke.sh` is the runtime check: create a key and vault, store
files across object boundaries, read them back, then have the Go oracle read
what that binary wrote and the binary read what the oracle wrote.
## Supported
## Released
The release covers Linux, Windows, macOS and FreeBSD (a decision made during
the port: the Go release's more exotic targets are no longer built).
| Go name | Rust target | Linking | Built by | Verified |
| --- | --- | --- | --- | --- |
@@ -23,63 +26,42 @@ what that binary wrote and the binary read what the oracle wrote.
| linux/386 | i686-unknown-linux-musl | static | zig | runtime: smoke test under qemu-i386, cross-checked |
| linux/armv6 | arm-unknown-linux-musleabihf | static | zig | runtime: smoke test under qemu-arm, cross-checked |
| linux/armv7 | armv7-unknown-linux-musleabihf | static | zig | runtime: smoke test under qemu-arm, cross-checked |
| linux/riscv64 | riscv64gc-unknown-linux-musl | static | zig | runtime: smoke test under qemu-riscv64, cross-checked; unit tests under qemu (see note 1) |
| linux/riscv64 | riscv64gc-unknown-linux-musl | static | zig | runtime: smoke test and crypto unit tests under qemu-riscv64, cross-checked (note 1) |
| linux/loong64 | loongarch64-unknown-linux-musl | static | zig | runtime: smoke test under qemu-loongarch64, cross-checked |
| linux/ppc64le | powerpc64le-unknown-linux-musl | static | zig | runtime: smoke test under qemu-ppc64le, cross-checked |
| linux/s390x | s390x-unknown-linux-gnu | glibc, dynamic | zig | runtime: smoke test under qemu-s390x (big-endian) with an Ubuntu glibc sysroot, cross-checked |
| linux/ppc64 | powerpc64-unknown-linux-gnu | glibc, dynamic | cross (Docker) | see note 2 |
| android/arm64 | aarch64-unknown-linux-musl | static | zig | build only on Android; it is the linux/arm64 binary (see note 3) |
| windows/amd64 | x86_64-pc-windows-gnu | static CRT | zig | build; tests cross-compile cleanly; runtime in CI only (windows-2025 job, not yet run) |
| windows/386 | i686-pc-windows-gnu | static CRT | zig | build only |
| windows/arm64 | aarch64-pc-windows-gnullvm | static CRT | zig | build only |
| darwin/amd64 | x86_64-apple-darwin | system | a Mac (Xcode) | CI only (macos-15-intel job, not yet run) |
| darwin/arm64 | aarch64-apple-darwin | system | a Mac (Xcode) | CI only (macos-15 job, not yet run) |
| freebsd/amd64 | x86_64-unknown-freebsd | system | cross (Docker) | see note 4 |
| freebsd/386 | i686-unknown-freebsd | system | cross (Docker) | see note 4 |
| netbsd/amd64 | x86_64-unknown-netbsd | system | cross (Docker) | see note 4 |
| illumos/amd64 | x86_64-unknown-illumos | system | cross (Docker) | see note 4 |
| solaris/amd64 | x86_64-pc-solaris | system | cross (Docker) | see note 4 |
| wasip1/wasm | wasm32-wasip1 | n/a | cargo | build only; no agent, no terminal prompts (passphrase from the environment), lock file instead of locks |
| freebsd/amd64 | x86_64-unknown-freebsd | system | cross 0.2.5 (Docker) | build only (no emulator) |
| freebsd/386 | i686-unknown-freebsd | system | cross 0.2.5 (Docker) | build only |
Feature notes: the `unlock` agent works on Unix only (Linux, macOS, the BSDs,
illumos, Solaris); Windows asks for the passphrase every time. Full agent
hardening (`PR_SET_DUMPABLE`) is Linux-only; elsewhere the agent locks its
memory and disables core dumps. See `SECURITY.md`.
Feature notes: the `unlock` agent works on Linux, macOS and FreeBSD;
Windows asks for the passphrase every time. Full agent hardening
(`PR_SET_DUMPABLE`) is Linux-only; elsewhere the agent locks its memory and
disables core dumps. See `SECURITY.md`.
1. zig's bundled musl `getrandom()` never reaches the kernel on riscv64 (the
process spins). `build.sh` and `packaging/package.sh` build that target
with `--cfg getrandom_backend="linux_raw"`, which makes the `getrandom`
crate issue the system call itself; with that flag the binary passes.
2. zig links big-endian ppc64 for the ELFv2 ABI (`/lib64/ld64.so.2`), but
big-endian glibc distributions use ELFv1 (`ld64.so.1`), so the zig build
would not start there. `build.sh` builds it with `cross` (GCC toolchain)
instead.
3. Go's android/arm64 binary was a static Linux binary used in Termux; this
is the same. Name resolution for `add URL`/`mirror` reads
`/etc/resolv.conf`, which Android does not have, so those two commands
may fail to resolve hosts there; everything else is unaffected.
4. Built with `cross` 0.2.5 images; not executed (no emulator). The
dependency graph supports these systems (rustix, ring, getrandom).
## Not supported
## No longer released
These Go targets have no Rust target with a prebuilt standard library on the
stable toolchain (Rust tier 3, built only with nightly `-Zbuild-std`, or no
Rust target at all). Building them would need a nightly toolchain and
untested standard libraries, which this project does not ship.
| Go name | Rust status |
| Go name | Why |
| --- | --- |
| aix/ppc64 | tier 3 (powerpc64-ibm-aix) |
| dragonfly/amd64 | tier 3 |
| freebsd/arm, freebsd/arm64, freebsd/riscv64 | tier 3 |
| netbsd/386, netbsd/arm, netbsd/arm64 | tier 3 |
| openbsd/386, amd64, arm, arm64, ppc64, riscv64 | tier 3 (OpenBSD packages Rust itself; building in an OpenBSD VM would work) |
| linux/mips, mipsle, mips64, mips64le | tier 3 since Rust 1.72 |
| plan9/386, amd64, arm | no Rust target |
| js/wasm | wasm32-unknown-unknown has no filesystem or OS access; not meaningful for vault |
| android/arm64 | was a copy of the static Linux arm64 binary; that binary still runs in Termux, but `add URL`/`mirror` need `/etc/resolv.conf` |
| linux/ppc64 (big-endian) | zig links it for the ELFv2 loader that BE distributions lack; built with `cross` instead, even a hello-world crashes at start-up under qemu-ppc64, so it cannot be verified |
| linux/mips, mipsle, mips64, mips64le | Rust tier 3 (no stable std) since 1.72 |
| netbsd/amd64 | builds only with a newer sysroot than cross 0.2.5 provides (std needs `libexecinfo`); netbsd/386, arm, arm64 are tier 3 |
| openbsd/* | Rust tier 3; OpenBSD packages Rust itself, so a native build there would work |
| freebsd/arm, arm64, riscv64 | Rust tier 3 |
| dragonfly/amd64, aix/ppc64 | Rust tier 3 |
| illumos/amd64, solaris/amd64 | outside the chosen matrix (illumos builds with cross; Solaris has no cross 0.2.5 image) |
| wasip1/wasm | outside the chosen matrix (it builds; no agent, no prompts) |
| js/wasm | no filesystem in the browser target |
| plan9/* | no Rust target |
Dropping these is a scope change from the Go release (43 binaries) and needs
an explicit decision before a release: either accept the narrower matrix,
or add nightly/native builds for chosen targets (OpenBSD in a VM is the most
practical).
Asking `build.sh` for any of these reports it and fails.
+10 -14
View File
@@ -221,16 +221,15 @@ Linux PC or server & almost everything & vault-linux-amd64 \\
Linux on ARM64 & Pi 4/5 (64-bit OS), Graviton, Ampere & vault-linux-arm64 \\
Raspberry Pi, 32-bit & Pi 2, 3, 4 on a 32-bit OS & vault-linux-armv7 \\
Raspberry Pi Zero / 1 & the tiny older ones & vault-linux-armv6 \\
Android & in Termux & vault-android-arm64 \\
FreeBSD, NetBSD & amd64 (FreeBSD also 386) & vault-freebsd-amd64 etc. \\
Something exotic & RISC-V, POWER, s390x, LoongArch, illumos, Solaris & see \cmd{dist/} \\
Android & in Termux: the Linux ARM64 file & vault-linux-arm64 \\
FreeBSD & amd64 or 386 & vault-freebsd-amd64 etc. \\
Something exotic & RISC-V, POWER (little-endian), s390x, LoongArch & see \cmd{dist/} \\
\end{vtable}
\begin{squirrel}
The release covers some twenty platforms, from Windows on ARM to IBM
mainframes, and even WebAssembly. A few that the older Go builds reached,
such as Plan~9, OpenBSD and MIPS, have no stable Rust toolchain yet;
\file{docs/PLATFORMS.md} keeps the list. Will you ever need
The release covers sixteen builds for Linux, Windows, macOS and FreeBSD,
from Windows on ARM to IBM mainframes. The older Go builds reached further,
to Plan~9 and WebAssembly; \file{docs/PLATFORMS.md} says why those went. Will you ever need
\file{vault-linux-s390x}? Almost certainly not. Is it pleasing that it
exists? Extremely.
\end{squirrel}
@@ -290,8 +289,8 @@ so Gatekeeper quarantines it. Once you've checked the SHA-256, clear the flag:
\subsection{Android (Termux)}
\begin{shell}
$ curl -LO https://.../vault-android-arm64
$ chmod +x vault-android-arm64 && mv vault-android-arm64 $PREFIX/bin/vault
$ curl -LO https://.../vault-linux-arm64
$ chmod +x vault-linux-arm64 && mv vault-linux-arm64 $PREFIX/bin/vault
\end{shell}
\section{Did it work?}
@@ -311,8 +310,7 @@ $ ./build.sh # every platform it can, into ./dist, with SH
\end{shell}
\cmd{build.sh} cross-compiles Linux and Windows with \cmd{cargo-zigbuild}
and \cmd{zig}, macOS on a Mac, and the BSDs, illumos and Solaris with
\cmd{cross} and Docker; it says which targets your machine can't build.
and \cmd{zig}, macOS on a Mac, and FreeBSD with \cmd{cross} and Docker; it says which targets your machine can't build.
32-bit ARM Linux gets two builds, armv6 and armv7. Want just a few? Set
\env{TARGETS}. Want them somewhere else? Set \env{OUT}.
@@ -1080,8 +1078,7 @@ who's slow at typing never blocks you.
\textbf{What if vault crashes while holding the lock?} On Linux, macOS, the
BSDs and Windows, the operating system drops the lock the moment the process
dies. Nothing to clean up. Older Go builds of vault use the very same locks,
so mixing versions is safe. On WebAssembly, which has no file locks, vault
uses a \file{.lock} file instead. If one's ever left behind,
so mixing versions is safe. If one's ever left behind,
vault tells you after a minute exactly which file to delete.
\end{whyso}
@@ -1335,7 +1332,6 @@ could not read passphrase (set VAULT\_PASSPHRASE\ldots) & No terminal to ask on,
agent did not start: \ldots & \cmd{unlock} couldn't start its helper. The reason follows; commands still work, asking for the passphrase. \\
nothing was unlocked & \cmd{vault lock} found nothing to lock. Not an error. \\
waiting for another vault process to finish & Not an error. Another command is writing; this one continues when it's done. \\
vault still locked after a minute\ldots & WebAssembly only. If nothing else is running, delete the file it names. \\
cannot lock the vault: \ldots & The lock file couldn't be opened or locked; the reason follows. Check the vault folder's permissions. \\
\ldots\ changed while being added & The file was being written while vault read it. Nothing was stored; try again when it's finished. \\
\ldots\ changed after it was stored; not deleting it & \cmd{migrate} stored the file, but it changed before it could be deleted. The original is kept; the vault has the version it read. \\