250 lines
14 KiB
Markdown
250 lines
14 KiB
Markdown
# M0: Arch Linux x86_64 build host
|
|
|
|
Development reference and historical context. For current operating instructions, use the [user manual](../README.md). Acceptance applies only to the source and artifacts identified in each record.
|
|
|
|
|
|
[Documentation index](README.md) · [First build](getting-started.md) · [Troubleshooting](troubleshooting.md)
|
|
|
|
This is the technical reference for the build foundation used by later milestones.
|
|
The [rootfs guide](rootfs.md) adds assembly, Python and isolated ARM execution requirements. If you are
|
|
setting up the repository for the first time, follow [Your first build](getting-started.md)
|
|
for an ordered walkthrough with expected output. For editing, rebuilding, and
|
|
configuration changes after setup, use [Development](development.md).
|
|
|
|
## Scope and pinned inputs
|
|
|
|
M0 validates the cross-build environment. The scoped [Dasung integration](dasung.md)
|
|
adds a controller package and service definitions without implementing a full OS.
|
|
M1 adds the configured FDS rootfs; M2 adds native init and the generic ARM VM.
|
|
M3 adds static FDS tools. M4 cross-builds the Pi kernel and creates initramfs,
|
|
SYSTEM GPT/EROFS and a FAT32 boot partition; see [Boot images](boot.md).
|
|
M6 adds cartridge management and M7 adds writable DATA. M8 adds the optional
|
|
WindowMaker stack and on-demand Ethernet. M12 adds the [complete internal disk](internal-storage.md),
|
|
independent recovery and persistent machine settings. The
|
|
[signature tools](releases.md) have passed acceptance; the
|
|
[frozen-input workflow](reproducible-builds.md) and signed local 0.1.0 release
|
|
have passed two complete offline builds and artifact/archive verification. The [desktop guide](desktop.md) explains the
|
|
new dependencies and the development image used for virtual display tests.
|
|
See [Native init](init.md) for the additional test dependencies. An ARM host
|
|
and a connected Pi are not required.
|
|
|
|
| Input | Pin |
|
|
| --- | --- |
|
|
| void-packages | Git submodule and `VOID_PACKAGES_COMMIT`: `02a3cbc132c3c4a3a9d59e9b98f517af5dd11cd1` |
|
|
| Static XBPS host tools | Versioned `0.60.4_1.x86_64-musl` URL and a SHA-256 digest stored in this repository |
|
|
| Rust | `rust-toolchain.toml`: 1.98.0, minimal profile, rustfmt |
|
|
| Rust target | `aarch64-unknown-linux-musl` |
|
|
| Rust crate dependencies | Smoketest has none; all workspace dependencies, including shared Clap CLI parsing, are pinned in `Cargo.lock`, fetched at bootstrap, and built with `--locked --offline` |
|
|
| XBPS test package | `srcpkgs/hello/template` in the pinned Void tree: GNU hello 2.12.3_1 |
|
|
| Pi kernel | `packages/fds-kernel/template`: 6.12.87, pinned Raspberry Pi source archive and FDS config delta |
|
|
| Pi firmware | `config/pi-firmware.conf`: signed 20260715_1 package with a pinned SHA-256 |
|
|
|
|
The musl ABI of the static host tools does not determine the target ABI. Scripts
|
|
explicitly use `XBPS_ARCH=x86_64` for the glibc build container, then run
|
|
`./xbps-src -a aarch64 pkg hello` to build the ARM glibc package. Local ARM package
|
|
indexing also explicitly sets `XBPS_ARCH=aarch64`.
|
|
|
|
## Generic Linux workstation tools and desktop additions
|
|
|
|
`make workstation` builds native `fds-cartridge` and `fds-emulator`. Runtime
|
|
requirements are QEMU, erofs-utils, bubblewrap and native XBPS with a prepared
|
|
Void source checkout for software creation. `fds-cartridge` invokes xbps-src,
|
|
installs runtime dependencies and creates direct EROFS trees. The Rust tar reader
|
|
and xz utility remain for legacy cartridges and package/source archives. See
|
|
[the current workstation guide](../workstation.md).
|
|
|
|
The target `fds-control` panel uses x11rb 0.13.2's pure-Rust core X11 connection.
|
|
It adds no shared GUI toolkit or background service. Its protocol, hostname and
|
|
OS-access dependencies are locked and included in Rust license notices. Both
|
|
the panel and foreground launcher are packaged in fds-cli as static ARM binaries.
|
|
See [the revision rationale](current-revision.md).
|
|
|
|
## Host dependencies
|
|
|
|
Run as an ordinary user on x86_64 Arch Linux with unprivileged user namespaces.
|
|
Rootfs construction now requires Linux 6.7+ with namespaced `binfmt_misc` support.
|
|
The M5 build uses a private handler and static QEMU for child execution; it does
|
|
not register an ARM interpreter in the workstation's global registry.
|
|
The checkout path must not contain whitespace, a limitation of upstream
|
|
xbps-src. Allow several GB of disk space and provide a network connection.
|
|
|
|
```sh
|
|
sudo pacman -S --needed bash coreutils binutils git curl make file tar xz gzip zstd \
|
|
bubblewrap rustup ca-certificates findutils diffutils grep sed gawk util-linux
|
|
```
|
|
|
|
Alternatively, run `./tools/bootstrap-host --install-deps`. Only this explicit
|
|
option invokes sudo/pacman. Default `make bootstrap` checks dependencies and
|
|
exits nonzero when one is missing, without installing host system packages.
|
|
|
|
Dependency rationale:
|
|
|
|
- bash, coreutils, findutils, diffutils, grep, sed, gawk, and util-linux provide
|
|
the build scripts and upstream build system with their required shell tools.
|
|
- git pins upstream source; curl and CA certificates download HTTPS inputs.
|
|
- tar, xz, gzip, and zstd extract archives and XBPS packages.
|
|
- file and binutils inspect ELF artifacts; make provides the build entry points.
|
|
- bubblewrap runs the build container as an ordinary user.
|
|
- rustup installs the pinned Rust toolchain and target. rustfmt checks source
|
|
formatting and is not a runtime dependency.
|
|
|
|
Rust's bundled `rust-lld` and target-provided static musl/CRT are sufficient for
|
|
the current pure-Rust smoketest. No Zig, Docker, OpenSSL crate, or additional
|
|
musl runtime is required. The imported Dasung controller bundles libusb and uses a Void musl C cross
|
|
compiler inside the container; see [its dependency rationale](dasung.md#dependencies-and-source-provenance).
|
|
Glibc C libraries cannot simply be reused in static-musl binaries.
|
|
|
|
## Exact commands
|
|
|
|
Run sequentially from the repository root:
|
|
|
|
```sh
|
|
make bootstrap
|
|
make smoke-test
|
|
make check
|
|
```
|
|
|
|
Bootstrap initializes the pinned submodule, verifies and extracts XBPS, checks
|
|
the tools' x86_64 static ELF properties, installs the pinned Rust toolchain and
|
|
target, fetches the locked workspace crates, copies `config/xbps-src.conf` into the local Void checkout, then runs the
|
|
equivalent of:
|
|
|
|
```sh
|
|
export PATH="$PWD/.host/xbps/usr/bin:$PATH"
|
|
export XBPS_ARCH=x86_64
|
|
cd vendor/void-packages
|
|
./xbps-src -A x86_64 binary-bootstrap
|
|
```
|
|
|
|
`binary-bootstrap` installs upstream **base-chroot** as a compilation environment.
|
|
It is separate from the FDS `fds-base` target rootfs built in M1. Builds run through
|
|
bubblewrap without starting Void services on Arch. Repeated bootstrap reuses the
|
|
masterdir and verified downloads. The script checks the container architecture,
|
|
installed base-chroot package, and execution of GCC inside the container.
|
|
|
|
To reproduce the two builds individually from the repository root:
|
|
|
|
```sh
|
|
./tools/cargo-build --locked --offline --release \
|
|
--target aarch64-unknown-linux-musl -p fds-smoketest
|
|
./tools/build-package hello
|
|
```
|
|
|
|
The latter command sets the local XBPS PATH, checks the Void pin, and executes
|
|
this command within the submodule:
|
|
|
|
```sh
|
|
./xbps-src -a aarch64 pkg hello
|
|
```
|
|
|
|
xbps-src installs the aarch64 GNU cross toolchain that runs on x86_64, together
|
|
with the target glibc sysroot. No Pi compilation is needed. The pinned template's
|
|
checksum verifies the package source archive.
|
|
|
|
## Validation
|
|
|
|
```sh
|
|
file target/aarch64-unknown-linux-musl/release/fds-smoketest
|
|
readelf -hW target/aarch64-unknown-linux-musl/release/fds-smoketest
|
|
readelf -lW target/aarch64-unknown-linux-musl/release/fds-smoketest
|
|
readelf -dW target/aarch64-unknown-linux-musl/release/fds-smoketest
|
|
readelf -VW target/aarch64-unknown-linux-musl/release/fds-smoketest
|
|
ldd target/aarch64-unknown-linux-musl/release/fds-smoketest
|
|
```
|
|
|
|
Rust acceptance requires ELF64, little endian, AArch64, executable type EXEC/DYN,
|
|
static linkage reported by `file`, no `PT_INTERP`, no `DT_NEEDED`, and no
|
|
`GLIBC_*` version requirements. Static PIE is also acceptable. The pinned Rust
|
|
target, self-contained linking configuration, and compile-time target checks
|
|
establish musl provenance; an ELF's static label alone does not identify its libc.
|
|
|
|
`ldd` is supplemental diagnostic output. A static executable normally produces
|
|
`not a dynamic executable` with exit status 1. **An x86_64 host's ldd alone cannot
|
|
prove that an ARM executable is static.**
|
|
|
|
XBPS validation checks architecture=aarch64 in the local package index, then
|
|
extracts `usr/bin/hello` from the generated package. It requires AArch64,
|
|
`/lib/ld-linux-aarch64.so.1`, and `libc.so.6`. An architecture suffix in a package
|
|
filename is not sufficient evidence.
|
|
|
|
`make check` verifies rejection of the wrong architecture, dynamic executables
|
|
passed as static, a static-musl executable passed as a glibc package, non-ELF
|
|
input, missing artifacts, invalid arguments, Void pin drift, and modified
|
|
upstream files. It also tests overlay protection and runs rustfmt. Pipelines
|
|
enable pipefail so `tee` cannot hide a failed build.
|
|
|
|
Optionally install `sudo pacman -S --needed qemu-user` to execute the ARM Rust
|
|
binary during smoke-test and compare its output. When qemu-aarch64 is absent,
|
|
the script explicitly reports SKIP. M0's required acceptance is actual
|
|
cross-compilation plus ELF/package inspection. Static inspection is not an ARM
|
|
runtime or Pi boot test.
|
|
|
|
## Inputs, caches, and overlays
|
|
|
|
Use `make clean-preview` followed by `make clean` when repeated builds and VM
|
|
tests accumulate. [Cleanup](cleanup.md) explains the retained current images,
|
|
release/input archives and caches. Full image builds and VM suites need tens of
|
|
GiB per working tree, beyond the initial M0 smoke test's requirements.
|
|
|
|
- `.host/xbps/`: project-local host tools, not installed into `/usr`.
|
|
- `vendor/void-packages/masterdir-x86_64/`: glibc build container.
|
|
- `vendor/void-packages/hostdir/`: download caches, cross packages, and build output.
|
|
- `out/packages/`: exported aarch64 test package and its repository index.
|
|
- `out/manifests/void-build-packages.txt`: packages remaining installed after the
|
|
build. Cross toolchains and temporary dependencies removed by xbps-src remain
|
|
traceable through cache digests and build logs.
|
|
- `out/manifests/void-package-inputs.sha256`: digests of cached `.xbps` inputs.
|
|
- `out/manifests/artifacts.sha256`: validation artifact digests.
|
|
- `out/logs/`: actual command logs, including logs from failed attempts.
|
|
|
|
Place FDS package overlays at `packages/fds-*/template`. `tools/prepare-void`
|
|
copies only directories containing a template and refuses to replace tracked
|
|
upstream packages. These copies are visible inside the build container. Base,
|
|
base-files, init, CLI, kernel and Dasung overlays are active; future directories
|
|
without templates remain inactive.
|
|
|
|
If an overlay changes and preparation reports a stale copy, inspect and preserve
|
|
any unique edits before moving the specific generated copy out of `srcpkgs/` and
|
|
retrying. Modified upstream tracked files cause immediate failure. Conflicting
|
|
local build configuration also causes failure and must be reconciled explicitly.
|
|
See [configuration and overlay troubleshooting](troubleshooting.md#configuration-or-overlay-conflict)
|
|
for the procedure.
|
|
|
|
Updating Void requires an explicit change to both the submodule gitlink and
|
|
`VOID_PACKAGES_COMMIT`, followed by validation and a commit containing both.
|
|
Do not fetch master and silently change the pin. Replacing the static host XBPS
|
|
archive also requires updating both its versioned URL and checksum.
|
|
|
|
## Known limitations
|
|
|
|
1. Source templates, Rust, and XBPS tools are pinned; **the complete Void binary
|
|
repository is not snapshotted**. Initial bootstrap, xbps-src build-container
|
|
updates, and missing build dependencies still use signed rolling repositories.
|
|
Cached inputs, version inventories, and digests support auditing but cannot
|
|
guarantee future upstream retention. M12 preserves the exact selected
|
|
packages, sources and build tools through the accepted
|
|
[snapshot and offline workflow](reproducible-builds.md). Its two fresh builds
|
|
produced 27 matching artifacts. This freezes the release inputs, not the
|
|
entire rolling Void repository; the original M0 check alone does not
|
|
establish reproducibility.
|
|
2. Bootstrap supports x86_64 Arch Linux. Other host distributions and ARM hosts
|
|
have not been validated. Unprivileged user namespaces must be available.
|
|
3. M4 tests the actual Pi kernel and initramfs-to-EROFS handoff in a generic ARM
|
|
VM. This does not emulate Pi firmware, RP1, physical bays or the display.
|
|
Media burning and physical boot-performance measurements remain separate work.
|
|
4. `opt-level=z` is the plan's initial setting, not a proven fastest setting.
|
|
Compare optimization levels later using real programs and hardware.
|
|
5. During the initial upstream bootstrap, bubblewrap's mounted `/tmp` produced
|
|
`rm: cannot remove '//tmp': Device or resource busy` in the cleanup phase.
|
|
Upstream returned success; the subsequent container execution, cross build,
|
|
and public bootstrap command passed. The upstream source was left unchanged.
|
|
|
|
## Upstream references
|
|
|
|
- [Pinned Void xbps-src usage and foreign host documentation](https://github.com/void-linux/void-packages/blob/02a3cbc132c3c4a3a9d59e9b98f517af5dd11cd1/README.md)
|
|
- [Pinned aarch64 cross profile](https://github.com/void-linux/void-packages/blob/02a3cbc132c3c4a3a9d59e9b98f517af5dd11cd1/common/cross-profiles/aarch64.sh)
|
|
- [Void static XBPS](https://docs.voidlinux.org/xbps/troubleshooting/static.html)
|
|
- [Official static tool SHA-256 checksums](https://repo-default.voidlinux.org/static/sha256sums.txt)
|
|
- [Rust aarch64-unknown-linux-musl](https://doc.rust-lang.org/rustc/platform-support/aarch64-unknown-linux-musl.html)
|
|
- [Rust self-contained linking](https://doc.rust-lang.org/rustc/codegen-options/index.html#link-self-contained)
|