233 lines
8.6 KiB
Markdown
233 lines
8.6 KiB
Markdown
# Your first build
|
|
|
|
[Documentation index](README.md) · [Troubleshooting](troubleshooting.md)
|
|
|
|
This walkthrough takes you from an FDS Git checkout to two verified ARM Linux
|
|
artifacts. It explains the output as you go. You do not need a Raspberry Pi.
|
|
|
|
At the end you will have a small Rust program built with static musl and GNU hello
|
|
packaged for aarch64 glibc. This proves that the workstation can build the two
|
|
kinds of software FDS/OS needs. It does not produce a bootable OS image.
|
|
|
|
## 1. Check the machine and checkout
|
|
|
|
Use an x86_64 Arch Linux workstation as a normal user. Check it with:
|
|
|
|
```sh
|
|
uname -m
|
|
cat /etc/os-release
|
|
id -u
|
|
```
|
|
|
|
Expect `x86_64`, `ID=arch`, and a user ID other than `0`. The bootstrap script
|
|
currently rejects other host platforms and root execution.
|
|
|
|
Enter your FDS checkout. For the existing development workspace:
|
|
|
|
```sh
|
|
cd /home/felis/source/fds
|
|
pwd
|
|
git status --short
|
|
```
|
|
|
|
On another workstation, substitute its checkout directory. It must contain
|
|
`Makefile`, `Cargo.toml`, `tools/`, `.gitmodules`, and Git metadata. Avoid spaces
|
|
in the path. There is no configured public remote in this workspace; obtain a
|
|
Git checkout from the project owner rather than using an invented clone URL.
|
|
|
|
You need HTTPS access to GitHub, Void repositories, Rust distribution servers,
|
|
and package source hosts. Initial downloads total hundreds of MB. Plan for
|
|
several GB of free disk space; the verified workstation used roughly 1.6 GB for
|
|
the Void masterdir and 455 MB for its hostdir cache, before Rustup and other
|
|
outputs. These are observations, not fixed requirements or a build-time promise.
|
|
|
|
```sh
|
|
df -h .
|
|
```
|
|
|
|
## 2. Install host prerequisites
|
|
|
|
On an otherwise maintained Arch installation, install the required packages:
|
|
|
|
```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
|
|
```
|
|
|
|
This is the host package installation step. Subsequent build commands run as your
|
|
normal user. The alternative `./tools/bootstrap-host --install-deps` runs the same
|
|
package installation and then continues bootstrap; choose one route.
|
|
|
|
The [dependency reference](build-host.md#host-dependencies) explains why each
|
|
package is needed. This project uses Rustup to select its pinned Rust compiler,
|
|
not an arbitrary system Rust version. If pacman reports an existing Rust package
|
|
conflict, resolve the host package choice before continuing; do not force file
|
|
replacement.
|
|
|
|
Check that bubblewrap can create a user namespace:
|
|
|
|
```sh
|
|
bwrap --ro-bind / / --unshare-user --uid 0 --gid 0 true
|
|
```
|
|
|
|
Success produces no output and exits normally. If it fails, use
|
|
[Troubleshooting](troubleshooting.md#bubblewrap-or-user-namespace-failure).
|
|
This is a host capability requirement, not something a Pi can fix.
|
|
|
|
## 3. Prepare the build environment
|
|
|
|
From the repository root:
|
|
|
|
```sh
|
|
make bootstrap
|
|
```
|
|
|
|
This performs these steps:
|
|
|
|
1. Initializes `vendor/void-packages` at the recorded Git commit.
|
|
2. Downloads the pinned static XBPS archive, verifies its SHA-256, and extracts
|
|
the host tools into `.host/xbps/`.
|
|
3. Copies the checked-in Void build configuration into the local upstream checkout.
|
|
4. Installs Rust 1.98.0, rustfmt, and `aarch64-unknown-linux-musl` through Rustup.
|
|
5. Fetches the locked workspace crates needed for Cargo to resolve the Dasung member,
|
|
including when building the dependency-free smoketest offline.
|
|
6. Creates the x86_64 glibc Void build container and verifies that GCC runs inside it.
|
|
|
|
The Void build container supplies compilers and package tools; it is not the
|
|
future FDS root filesystem. Rustup changes your user toolchain installation.
|
|
XBPS host tools stay inside this repository, and no Pi storage is written.
|
|
|
|
The final success marker is:
|
|
|
|
```text
|
|
PASS: M0 host bootstrap; run make smoke-test to build both aarch64 artifacts
|
|
```
|
|
|
|
The command saves its output in `out/logs/bootstrap.log`. Re-running bootstrap
|
|
reuses the checkout and downloads, but still checks their pins and integrity.
|
|
If it exits nonzero, stop here and resolve that failure before running smoke-test.
|
|
|
|
## 4. Cross-build both artifacts
|
|
|
|
```sh
|
|
make smoke-test
|
|
```
|
|
|
|
First Cargo builds `rust/fds-smoketest` for ARM, using the static musl libraries
|
|
and linker bundled with the Rust toolchain. Then xbps-src cross-compiles GNU
|
|
hello and packages it for aarch64 glibc. The first package build downloads the
|
|
cross compiler, target libraries, and build dependencies such as texinfo.
|
|
|
|
The script inspects actual ELF files and local package metadata. It checks:
|
|
|
|
| Artifact | Required result |
|
|
| --- | --- |
|
|
| Rust smoketest | AArch64, static linkage, no dynamic interpreter or shared library requirement |
|
|
| GNU hello in the XBPS package | AArch64, glibc loader and `libc.so.6` dependency |
|
|
|
|
A successful run contains these messages; other compiler output appears between them:
|
|
|
|
```text
|
|
PASS: aarch64 static ELF
|
|
PASS: aarch64 glibc ELF
|
|
PASS: XBPS package hello-2.12.3_1 architecture=aarch64 (glibc)
|
|
PASS: M0 smoke test complete
|
|
```
|
|
|
|
Without QEMU, it also reports:
|
|
|
|
```text
|
|
SKIP: ARM execution (optional qemu-aarch64 not installed); ELF verification passed
|
|
```
|
|
|
|
That skip means the ARM program was compiled and inspected, but not executed.
|
|
It does not hide a failed compiler or ELF check. If QEMU is installed, execution
|
|
must pass; an emulator failure is a real smoke-test failure.
|
|
|
|
## 5. Run the protection and formatting checks
|
|
|
|
```sh
|
|
make check
|
|
```
|
|
|
|
Run this after smoke-test: it expects the built Rust executable to exist. It
|
|
checks that bad inputs are rejected, that the Void pin and upstream files are
|
|
protected, that overlays cannot replace upstream packages, and that Rust source
|
|
is formatted. Several `PASS: rejects ...` lines are expected; they mean the
|
|
negative tests worked. The final commands include:
|
|
|
|
```text
|
|
PASS: M0 guardrail checks complete
|
|
cargo fmt --all -- --check
|
|
```
|
|
|
|
Rustfmt is normally silent on success. `make check` does not rebuild the ARM
|
|
program. After a source change, rebuild first, as described in
|
|
[Development](development.md#edit-and-rebuild-the-rust-program).
|
|
|
|
## 6. Inspect what you built
|
|
|
|
```sh
|
|
ls -lh out/fds-smoketest out/packages/
|
|
file out/fds-smoketest
|
|
./tools/verify-elf out/fds-smoketest aarch64 static
|
|
sha256sum -c out/manifests/artifacts.sha256
|
|
```
|
|
|
|
`file` should include `ARM aarch64` and `statically linked` (or `static-pie linked`).
|
|
The checksum command should report `OK` for both artifacts. Hashes verify the
|
|
files against this run's manifest; they are not release signatures.
|
|
|
|
For ELF details, use:
|
|
|
|
```sh
|
|
readelf -hW out/fds-smoketest
|
|
readelf -lW out/fds-smoketest
|
|
readelf -dW out/fds-smoketest
|
|
```
|
|
|
|
The header names AArch64. There should be no `INTERP` segment or `NEEDED` library.
|
|
An x86_64 host's `ldd` may say `not a dynamic executable` and return 1; that message
|
|
is expected here, but is insufficient by itself to prove a foreign ELF is static.
|
|
The [package guide](packages.md#inspect-the-built-package) walks through the
|
|
corresponding inspection of GNU hello.
|
|
|
|
## 7. Optionally execute the ARM Rust program
|
|
|
|
The [Arch qemu-user package](https://archlinux.org/packages/extra/x86_64/qemu-user/)
|
|
provides user-mode emulation. Install it if you want to execute the ARM program
|
|
on the x86_64 workstation:
|
|
|
|
```sh
|
|
sudo pacman -S --needed qemu-user
|
|
qemu-aarch64 out/fds-smoketest
|
|
```
|
|
|
|
Expected output:
|
|
|
|
```text
|
|
FDS/OS M0: aarch64 static-musl OK
|
|
```
|
|
|
|
Because this executable is static, this command needs no ARM rootfs or glibc
|
|
sysroot. Explicitly invoking `qemu-aarch64` also avoids needing automatic binfmt
|
|
registration. Re-running `make smoke-test` records its own QEMU check when the
|
|
emulator is on PATH.
|
|
|
|
This executes one Linux userspace program. It does not emulate the Pi's firmware,
|
|
USB bays, display, battery, or operating-system boot. QEMU execution was not
|
|
performed during the initial M0 validation; see the [recorded results](m0-validation.md).
|
|
|
|
## 8. Decide what to do next
|
|
|
|
- To build the configured OS filesystem and try its ARM programs, follow [Rootfs](rootfs.md): `make rootfs PROFILE=cli`, then `make rootfs-test`.
|
|
- To boot native s6 and open a development console, follow [Native init and ARM VM](init.md): `make init-test`, then `make vm`.
|
|
- To build the included Dasung monitor package, follow [Dasung](dasung.md).
|
|
- To edit the existing Rust program, follow [Development](development.md).
|
|
- To understand the `.xbps` artifact, follow [Packages](packages.md).
|
|
- To understand the intended removable operating system, read [Architecture](architecture.md) and [Cartridges](cartridges.md).
|
|
- To see when bootable images become possible, read [Roadmap](roadmap.md).
|
|
|
|
Bootstrap, smoke-test, and check complete the M0 foundation. Continue with the
|
|
M1 guide for a configured rootfs archive. There is still no flashing step.
|