# Building and inspecting packages [Documentation index](README.md) · [Development](development.md) · [Glossary](glossary.md) FDS uses Void's XBPS package format and xbps-src build machinery for ordinary Linux software. M0 verifies this route by cross-compiling GNU hello 2.12.3_1 for **aarch64 glibc** on the x86_64 Arch workstation. This guide assumes `make bootstrap` and `make smoke-test` have succeeded. All commands run from the repository root. They inspect a local package; they do not install it on Arch or create a Pi root filesystem. ## What each tool does | Tool or file | Role | | --- | --- | | `vendor/void-packages/srcpkgs/hello/template` | Pinned upstream recipe: sources, checksums, dependencies, build/install steps | | `xbps-src` | Creates the build environment, cross-compiles, and packages files | | `.host/xbps/usr/bin/xbps-query` | Reads package metadata and dependencies | | `.host/xbps/usr/bin/xbps-rindex` | Creates or updates a package repository index | | `.host/xbps/usr/bin/xbps-install` | Installs packages into a selected root; bootstrap uses it for the build container | | `*.aarch64.xbps` | Package archive with metadata and installed file contents | | `aarch64-repodata` | Index allowing XBPS to find packages in an output directory | Arch's pacman manages workstation packages. XBPS manages Void/FDS packages. An XBPS archive cannot be passed to pacman, and an ARM package cannot be executed as native x86_64 software just because it was built on this workstation. ## Rebuild the verified package ```sh ./tools/build-package hello ``` The helper runs `xbps-src -a aarch64 pkg hello` and exports the main package to: ```text out/packages/hello-2.12.3_1.aarch64.xbps ``` It reuses upstream's cache and build state; an already built package may not need recompiling. The helper's log is `out/logs/xbps-hello.log`. The package version in this guide comes from the current source pin, not a promise about a future pin. Standalone `tools/build-package` does not index exported output. To refresh the local index for this package: ```sh XBPS_ARCH=aarch64 .host/xbps/usr/bin/xbps-rindex \ -a out/packages/hello-2.12.3_1.aarch64.xbps ``` `make smoke-test` already performs that indexing step. Explicit `XBPS_ARCH` matters: a host tool's default architecture is not the architecture of the package you want to inspect. ## Inspect the built package Query only the local exported repository, avoiding a remote prebuilt package: ```sh XBPS_ARCH=aarch64 .host/xbps/usr/bin/xbps-query \ -i --repository "$PWD/out/packages" -p pkgver hello XBPS_ARCH=aarch64 .host/xbps/usr/bin/xbps-query \ -i --repository "$PWD/out/packages" -p architecture hello XBPS_ARCH=aarch64 .host/xbps/usr/bin/xbps-query \ -i --repository "$PWD/out/packages" -x hello ``` The first two commands should print `hello-2.12.3_1` and `aarch64`. The third lists runtime dependencies recorded by the package. `-i` ignores configured repositories, so the explicit output directory supplies the lookup here. List the archive contents and extract just the executable into a new directory: ```sh tar -tf out/packages/hello-2.12.3_1.aarch64.xbps extract_dir=$(mktemp -d "$PWD/out/hello-inspect.XXXXXX") tar -xf out/packages/hello-2.12.3_1.aarch64.xbps \ -C "$extract_dir" ./usr/bin/hello ./tools/verify-elf "$extract_dir/usr/bin/hello" aarch64 glibc readelf -lW "$extract_dir/usr/bin/hello" readelf -dW "$extract_dir/usr/bin/hello" printf 'Extracted program: %s/usr/bin/hello\n' "$extract_dir" ``` The check should print `PASS: aarch64 glibc ELF`. The program headers name `/lib/ld-linux-aarch64.so.1`, and dynamic entries include `libc.so.6`. This checks the program inside the archive, not just its filename or metadata. The scratch folder remains under `out/` for inspection. Running this dynamic ARM program also needs ARM glibc and its loader. M0 verifies its package and ELF structure, not hello execution under QEMU. The static Rust program can be run with the simpler [QEMU example](getting-started.md#7-optionally-execute-the-arm-rust-program). ## Host, build container, and target architectures ```text Host utility: x86_64 static-musl XBPS runs on Arch Build container: x86_64 glibc Void supplies native build tools Target package: aarch64 glibc GNU hello runs on ARM Linux FDS Rust program: aarch64 static-musl executable runs on ARM Linux ``` The wrapper selects `XBPS_ARCH=x86_64` for build-container operations and `-a aarch64` for the target cross build. Package indexing/query examples override `XBPS_ARCH=aarch64`. Using `aarch64-musl` would select the wrong general userspace ABI for FDS, even though FDS-owned Rust executables use musl internally. ## FDS packages and overlays | Package directory | Responsibility and status | | --- | --- | | `packages/fds-base/` | Implemented: base system package selection and dependencies | | `packages/fds-base-files/` | Implemented: FDS identity, filesystem layout, and base configuration | | `packages/fds-init/` | Implemented: native init skeleton, runtime mounts, console and service graph | | `packages/fds-kernel/` | Implemented: pinned Pi kernel, DTBs, overlays and matching modules | | `packages/fds-cartridged/` | Cartridge daemon packaging | | `packages/fds-cli/` | Implemented: verified static-musl FDS CLI | | `packages/fds-eink/` | E-Ink configuration and related integration | All nine FDS base packages, including cartridged, E-Ink configuration and the bounded DHCP client, are built by `make packages` or `make rootfs PROFILE=cli`. The separate `packages/fds-dasungd/` overlay is active: use `make dasung` to prepare its verified static binary and build the package. It is required by `image/base-packages.list` and belongs to the base boot bundle; see [Dasung](dasung.md). The build deliberately ignores directories without a `template`. [Development](development.md#how-future-package-overlays-fit) explains how active overlays are copied without changing upstream files. The builder assembles a configured rootfs tar from this explicit set; see [Rootfs](rootfs.md). M2 adds native init and verifies it with a full [ARM VM boot](init.md). `make system-card` now packages it as read-only EROFS inside GPT. Runtime updates replace SYSTEM media; PROGRAM media uses self-contained images instead of modifying the root. See [Media tools](media-tools.md) for those implemented workflows; the small package smoke-test only checks the build foundation. ## What the records prove `out/manifests/artifacts.sha256` records the output hashes from the most recent successful smoke-test. `void-package-inputs.sha256` records cached XBPS archive hashes, and `void-build-packages.txt` records packages left installed after the build. Logs retain additional build dependency information. The Void source commit, Rust toolchain, and static XBPS archive are pinned. These ordinary build records alone do not freeze the rolling Void repository. M12's separate [frozen-input workflow](reproducible-builds.md) captures selected packages and build dependencies and compares independent offline builds. See its acceptance status before making a reproducibility claim.