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
+6 -7
View File
@@ -68,21 +68,20 @@ jobs:
run: | run: |
rustup target add x86_64-unknown-linux-musl aarch64-unknown-linux-musl i686-unknown-linux-musl \ rustup target add x86_64-unknown-linux-musl aarch64-unknown-linux-musl i686-unknown-linux-musl \
arm-unknown-linux-musleabihf armv7-unknown-linux-musleabihf riscv64gc-unknown-linux-musl \ arm-unknown-linux-musleabihf armv7-unknown-linux-musleabihf riscv64gc-unknown-linux-musl \
loongarch64-unknown-linux-musl powerpc64le-unknown-linux-musl powerpc64-unknown-linux-gnu \ loongarch64-unknown-linux-musl powerpc64le-unknown-linux-musl \
s390x-unknown-linux-gnu x86_64-pc-windows-gnu i686-pc-windows-gnu aarch64-pc-windows-gnullvm wasm32-wasip1 \ s390x-unknown-linux-gnu x86_64-pc-windows-gnu i686-pc-windows-gnu aarch64-pc-windows-gnullvm \
x86_64-unknown-freebsd i686-unknown-freebsd x86_64-unknown-netbsd x86_64-unknown-illumos x86_64-pc-solaris x86_64-unknown-freebsd i686-unknown-freebsd
- name: build - name: build
run: | run: |
# Everything but macOS, which the test job builds on a Mac. # Everything but macOS, which the test job builds on a Mac.
TARGETS="linux/amd64 linux/arm64 linux/386 linux/armv6 linux/armv7 linux/riscv64 linux/loong64 \ TARGETS="linux/amd64 linux/arm64 linux/386 linux/armv6 linux/armv7 linux/riscv64 linux/loong64 \
linux/ppc64le linux/ppc64 linux/s390x android/arm64 windows/amd64 windows/386 windows/arm64 \ linux/ppc64le linux/s390x windows/amd64 windows/386 windows/arm64 freebsd/amd64 freebsd/386" ./build.sh
freebsd/amd64 freebsd/386 netbsd/amd64 illumos/amd64 solaris/amd64 wasip1/wasm" ./build.sh
- name: run builds under qemu, cross-checked with the Go oracle - name: run builds under qemu, cross-checked with the Go oracle
run: | run: |
sudo apt-get update -q && sudo apt-get install -yq qemu-user libc6-s390x-cross libc6-ppc64-cross sudo apt-get update -q && sudo apt-get install -yq qemu-user libc6-s390x-cross
(cd oracle/go && go build -o ../../target/vault-go .) (cd oracle/go && go build -o ../../target/vault-go .)
for t in "arm64 qemu-aarch64" "armv7 qemu-arm" "riscv64 qemu-riscv64" "ppc64le qemu-ppc64le" \ for t in "arm64 qemu-aarch64" "armv7 qemu-arm" "riscv64 qemu-riscv64" "ppc64le qemu-ppc64le" \
"s390x qemu-s390x -L /usr/s390x-linux-gnu" "ppc64 qemu-ppc64 -L /usr/powerpc64-linux-gnu"; do "s390x qemu-s390x -L /usr/s390x-linux-gnu"; do
EMU="${t#* }" scripts/smoke.sh "dist/vault-linux-${t%% *}" target/vault-go EMU="${t#* }" scripts/smoke.sh "dist/vault-linux-${t%% *}" target/vault-go
done done
- uses: actions/upload-artifact@v4 - uses: actions/upload-artifact@v4
+2 -4
View File
@@ -37,7 +37,7 @@ TARGETS="linux/amd64 windows/amd64" ./build.sh
`build.sh` cross-compiles with `cargo-zigbuild` and `zig` (Linux, statically `build.sh` cross-compiles with `cargo-zigbuild` and `zig` (Linux, statically
linked with musl, and Windows), on a Mac for macOS, and with `cross` and linked with musl, and Windows), on a Mac for macOS, and with `cross` and
Docker for the BSDs, illumos and Solaris. It names binaries as before Docker for FreeBSD. The release covers Linux, Windows, macOS and FreeBSD. It names binaries as before
(`vault-linux-arm64`, `vault-windows-amd64.exe`, …), builds 32-bit ARM Linux (`vault-linux-arm64`, `vault-windows-amd64.exe`, …), builds 32-bit ARM Linux
for both armv6 and armv7, and writes `dist/SHA256SUMS`. `docs/PLATFORMS.md` for both armv6 and armv7, and writes `dist/SHA256SUMS`. `docs/PLATFORMS.md`
lists every target, how it is built and tested, and the Go targets Rust lists every target, how it is built and tested, and the Go targets Rust
@@ -103,9 +103,7 @@ Commands that change the vault take an exclusive lock on `DIR/.lock`, and
commands that read it take a shared one. A second process waits, and says commands that read it take a shared one. A second process waits, and says
so, until the first finishes. The operating system releases the lock if a so, until the first finishes. The operating system releases the lock if a
process dies; the locks are the same ones the Go version used, so old and process dies; the locks are the same ones the Go version used, so old and
new versions exclude each other. WebAssembly (WASI) has no file locks, so new versions exclude each other.
there the lock file itself is the lock. After a crash there you remove it
by hand; the error message names it.
Adding a name that already exists replaces it. `get` never replaces an Adding a name that already exists replaces it. `get` never replaces an
existing file (or symlink) and writes nothing until the whole file has existing file (or symlink) and writes nothing until the whole file has
+9 -21
View File
@@ -9,16 +9,13 @@
# release builds from the pinned toolchain (rust-toolchain.toml) and the # release builds from the pinned toolchain (rust-toolchain.toml) and the
# locked dependencies (Cargo.lock), with build paths remapped so the output # locked dependencies (Cargo.lock), with build paths remapped so the output
# does not depend on where the tree lives. Linux binaries are static (musl) # does not depend on where the tree lives. Linux binaries are static (musl)
# except s390x and ppc64, which link glibc dynamically; static linking is # except s390x, which links glibc dynamically; static linking is
# checked. SHA256SUMS is written next to the binaries. # checked. SHA256SUMS is written next to the binaries.
# #
# How each target is built, and what the host needs: # How each target is built, and what the host needs:
# zig cargo-zigbuild and zig on PATH (Linux, Windows GNU ABI) # zig cargo-zigbuild and zig on PATH (Linux, Windows GNU ABI)
# mac a Mac with Xcode (macOS) # mac a Mac with Xcode (macOS)
# cross `cross` and Docker (FreeBSD, NetBSD, illumos, Solaris, # cross `cross` and Docker (FreeBSD)
# and big-endian ppc64, which zig
# links for the wrong ABI)
# cargo nothing extra (WASI)
# A requested target the host cannot build is reported, the others are still # A requested target the host cannot build is reported, the others are still
# built, and the script exits non-zero. See docs/PLATFORMS.md for the Go # built, and the script exits non-zero. See docs/PLATFORMS.md for the Go
# targets with no Rust equivalent; asking for one is an error. # targets with no Rust equivalent; asking for one is an error.
@@ -40,9 +37,7 @@ table() {
linux/riscv64 riscv64gc-unknown-linux-musl zig linux/riscv64 riscv64gc-unknown-linux-musl zig
linux/loong64 loongarch64-unknown-linux-musl zig linux/loong64 loongarch64-unknown-linux-musl zig
linux/ppc64le powerpc64le-unknown-linux-musl zig linux/ppc64le powerpc64le-unknown-linux-musl zig
linux/ppc64 powerpc64-unknown-linux-gnu cross
linux/s390x s390x-unknown-linux-gnu zig linux/s390x s390x-unknown-linux-gnu zig
android/arm64 aarch64-unknown-linux-musl zig
windows/amd64 x86_64-pc-windows-gnu zig windows/amd64 x86_64-pc-windows-gnu zig
windows/386 i686-pc-windows-gnu zig windows/386 i686-pc-windows-gnu zig
windows/arm64 aarch64-pc-windows-gnullvm zig windows/arm64 aarch64-pc-windows-gnullvm zig
@@ -50,19 +45,15 @@ table() {
darwin/arm64 aarch64-apple-darwin mac darwin/arm64 aarch64-apple-darwin mac
freebsd/amd64 x86_64-unknown-freebsd cross freebsd/amd64 x86_64-unknown-freebsd cross
freebsd/386 i686-unknown-freebsd cross freebsd/386 i686-unknown-freebsd cross
netbsd/amd64 x86_64-unknown-netbsd cross
illumos/amd64 x86_64-unknown-illumos cross
solaris/amd64 x86_64-pc-solaris cross
wasip1/wasm wasm32-wasip1 cargo
EOF EOF
} }
# Go targets that Rust cannot build with a stable toolchain (no prebuilt # Go-era targets no longer released (the release covers Linux, Windows,
# standard library, or no Rust target at all). See docs/PLATFORMS.md. # macOS and FreeBSD). See docs/PLATFORMS.md for why each was dropped.
unsupported="aix/ppc64 dragonfly/amd64 freebsd/arm freebsd/arm64 freebsd/riscv64 js/wasm unsupported="aix/ppc64 android/arm64 dragonfly/amd64 freebsd/arm freebsd/arm64 freebsd/riscv64
linux/mips linux/mipsle linux/mips64 linux/mips64le netbsd/386 netbsd/arm netbsd/arm64 illumos/amd64 js/wasm linux/mips linux/mipsle linux/mips64 linux/mips64le linux/ppc64
openbsd/386 openbsd/amd64 openbsd/arm openbsd/arm64 openbsd/ppc64 openbsd/riscv64 netbsd/386 netbsd/amd64 netbsd/arm netbsd/arm64 openbsd/386 openbsd/amd64 openbsd/arm
plan9/386 plan9/amd64 plan9/arm" openbsd/arm64 openbsd/ppc64 openbsd/riscv64 plan9/386 plan9/amd64 plan9/arm solaris/amd64 wasip1/wasm"
out=${OUT:-dist} out=${OUT:-dist}
jobs=${JOBS:-1} jobs=${JOBS:-1}
@@ -89,7 +80,7 @@ build_one() {
row=$(table | awk -v t="$want" '$1 == t') row=$(table | awk -v t="$want" '$1 == t')
if [[ -z $row ]]; then if [[ -z $row ]]; then
if grep -qw -- "$want" <<<"$unsupported"; then if grep -qw -- "$want" <<<"$unsupported"; then
echo "UNSUPPORTED $want: no stable Rust target; see docs/PLATFORMS.md" >&2 echo "UNSUPPORTED $want: not released; see docs/PLATFORMS.md" >&2
else else
echo "UNKNOWN $want" >&2 echo "UNKNOWN $want" >&2
fi fi
@@ -98,7 +89,6 @@ build_one() {
read -r _ triple method <<<"$row" read -r _ triple method <<<"$row"
os=${want%/*} os=${want%/*}
[[ $os == windows ]] && ext=.exe [[ $os == windows ]] && ext=.exe
[[ $os == wasip1 ]] && ext=.wasm
name=vault-${want/\//-}$ext name=vault-${want/\//-}$ext
tdir=$root/target tdir=$root/target
[[ $JOBS_N != 1 ]] && tdir=$CARGO_TARGET_DIR_BASE/$triple [[ $JOBS_N != 1 ]] && tdir=$CARGO_TARGET_DIR_BASE/$triple
@@ -114,7 +104,6 @@ build_one() {
command -v cross >/dev/null && command -v docker >/dev/null || command -v cross >/dev/null && command -v docker >/dev/null ||
{ echo "SKIPPED $want: needs cross and docker" >&2; return 1; } { echo "SKIPPED $want: needs cross and docker" >&2; return 1; }
cmd=(cross build) ;; cmd=(cross build) ;;
cargo) cmd=(cargo build) ;;
esac esac
local flags=$RUSTFLAGS local flags=$RUSTFLAGS
# zig's musl getrandom() never reaches the kernel on riscv64 (it spins); # zig's musl getrandom() never reaches the kernel on riscv64 (it spins);
@@ -126,7 +115,6 @@ build_one() {
return 1 return 1
fi fi
bin=$tdir/$triple/release/vault$ext bin=$tdir/$triple/release/vault$ext
[[ $os == wasip1 ]] && bin=$tdir/$triple/release/vault.wasm
cp -- "$bin" "$OUT_DIR/$name" cp -- "$bin" "$OUT_DIR/$name"
if [[ $triple == *-musl* ]] && command -v file >/dev/null; then if [[ $triple == *-musl* ]] && command -v file >/dev/null; then
file -L "$OUT_DIR/$name" | grep -q 'static' || { echo "FAILED $want: not statically linked" >&2; return 1; } file -L "$OUT_DIR/$name" | grep -q 'static' || { echo "FAILED $want: not statically linked" >&2; return 1; }
+2 -2
View File
@@ -92,8 +92,8 @@ Command line:
- `ls`/`list` piped into a reader that stops early end quietly with - `ls`/`list` piped into a reader that stops early end quietly with
status 141, as Go's did by `SIGPIPE`. status 141, as Go's did by `SIGPIPE`.
Platforms: see `PLATFORMS.md`. Some targets Go built have no stable Rust Platforms: releases now cover Linux, Windows, macOS and FreeBSD (16
equivalent; they are listed there and need a decision before release. binaries, down from 43); `PLATFORMS.md` lists what was dropped and why.
## Unchanged on purpose ## Unchanged on purpose
+27 -45
View File
@@ -1,8 +1,8 @@
# Platforms # Platforms
The Go version was built for every target of `go tool dist list` that needs 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 no cgo: 43 binaries. The Rust release is narrower by decision (Linux,
prebuilt, stable standard library. This is the target-by-target record: 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 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. 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 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. 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 | | 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/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/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/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/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/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/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/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/386 | i686-pc-windows-gnu | static CRT | zig | build only |
| windows/arm64 | aarch64-pc-windows-gnullvm | 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/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) | | 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/amd64 | x86_64-unknown-freebsd | system | cross 0.2.5 (Docker) | build only (no emulator) |
| freebsd/386 | i686-unknown-freebsd | system | cross (Docker) | see note 4 | | freebsd/386 | i686-unknown-freebsd | system | cross 0.2.5 (Docker) | build only |
| 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 |
Feature notes: the `unlock` agent works on Unix only (Linux, macOS, the BSDs, Feature notes: the `unlock` agent works on Linux, macOS and FreeBSD;
illumos, Solaris); Windows asks for the passphrase every time. Full agent Windows asks for the passphrase every time. Full agent hardening
hardening (`PR_SET_DUMPABLE`) is Linux-only; elsewhere the agent locks its (`PR_SET_DUMPABLE`) is Linux-only; elsewhere the agent locks its memory and
memory and disables core dumps. See `SECURITY.md`. disables core dumps. See `SECURITY.md`.
1. zig's bundled musl `getrandom()` never reaches the kernel on riscv64 (the 1. zig's bundled musl `getrandom()` never reaches the kernel on riscv64 (the
process spins). `build.sh` and `packaging/package.sh` build that target process spins). `build.sh` and `packaging/package.sh` build that target
with `--cfg getrandom_backend="linux_raw"`, which makes the `getrandom` with `--cfg getrandom_backend="linux_raw"`, which makes the `getrandom`
crate issue the system call itself; with that flag the binary passes. 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 | Go name | Why |
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 |
| --- | --- | | --- | --- |
| aix/ppc64 | tier 3 (powerpc64-ibm-aix) | | 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` |
| dragonfly/amd64 | tier 3 | | 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 |
| freebsd/arm, freebsd/arm64, freebsd/riscv64 | tier 3 | | linux/mips, mipsle, mips64, mips64le | Rust tier 3 (no stable std) since 1.72 |
| netbsd/386, netbsd/arm, netbsd/arm64 | tier 3 | | 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/386, amd64, arm, arm64, ppc64, riscv64 | tier 3 (OpenBSD packages Rust itself; building in an OpenBSD VM would work) | | openbsd/* | Rust tier 3; OpenBSD packages Rust itself, so a native build there would work |
| linux/mips, mipsle, mips64, mips64le | tier 3 since Rust 1.72 | | freebsd/arm, arm64, riscv64 | Rust tier 3 |
| plan9/386, amd64, arm | no Rust target | | dragonfly/amd64, aix/ppc64 | Rust tier 3 |
| js/wasm | wasm32-unknown-unknown has no filesystem or OS access; not meaningful for vault | | 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 Asking `build.sh` for any of these reports it and fails.
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).
+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 \\ 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, 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 \\ Raspberry Pi Zero / 1 & the tiny older ones & vault-linux-armv6 \\
Android & in Termux & vault-android-arm64 \\ Android & in Termux: the Linux ARM64 file & vault-linux-arm64 \\
FreeBSD, NetBSD & amd64 (FreeBSD also 386) & vault-freebsd-amd64 etc. \\ FreeBSD & amd64 or 386 & vault-freebsd-amd64 etc. \\
Something exotic & RISC-V, POWER, s390x, LoongArch, illumos, Solaris & see \cmd{dist/} \\ Something exotic & RISC-V, POWER (little-endian), s390x, LoongArch & see \cmd{dist/} \\
\end{vtable} \end{vtable}
\begin{squirrel} \begin{squirrel}
The release covers some twenty platforms, from Windows on ARM to IBM The release covers sixteen builds for Linux, Windows, macOS and FreeBSD,
mainframes, and even WebAssembly. A few that the older Go builds reached, from Windows on ARM to IBM mainframes. The older Go builds reached further,
such as Plan~9, OpenBSD and MIPS, have no stable Rust toolchain yet; to Plan~9 and WebAssembly; \file{docs/PLATFORMS.md} says why those went. Will you ever need
\file{docs/PLATFORMS.md} keeps the list. Will you ever need
\file{vault-linux-s390x}? Almost certainly not. Is it pleasing that it \file{vault-linux-s390x}? Almost certainly not. Is it pleasing that it
exists? Extremely. exists? Extremely.
\end{squirrel} \end{squirrel}
@@ -290,8 +289,8 @@ so Gatekeeper quarantines it. Once you've checked the SHA-256, clear the flag:
\subsection{Android (Termux)} \subsection{Android (Termux)}
\begin{shell} \begin{shell}
$ curl -LO https://.../vault-android-arm64 $ curl -LO https://.../vault-linux-arm64
$ chmod +x vault-android-arm64 && mv vault-android-arm64 $PREFIX/bin/vault $ chmod +x vault-linux-arm64 && mv vault-linux-arm64 $PREFIX/bin/vault
\end{shell} \end{shell}
\section{Did it work?} \section{Did it work?}
@@ -311,8 +310,7 @@ $ ./build.sh # every platform it can, into ./dist, with SH
\end{shell} \end{shell}
\cmd{build.sh} cross-compiles Linux and Windows with \cmd{cargo-zigbuild} \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 and \cmd{zig}, macOS on a Mac, and FreeBSD with \cmd{cross} and Docker; it says which targets your machine can't build.
\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 32-bit ARM Linux gets two builds, armv6 and armv7. Want just a few? Set
\env{TARGETS}. Want them somewhere else? Set \env{OUT}. \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 \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 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, 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 so mixing versions is safe. If one's ever left behind,
uses a \file{.lock} file instead. If one's ever left behind,
vault tells you after a minute exactly which file to delete. vault tells you after a minute exactly which file to delete.
\end{whyso} \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. \\ 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. \\ 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. \\ 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. \\ 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 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. \\ \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. \\