# 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.