Files
fds-os/docs/developer/packages.md
T
2026-09-22 13:23:34 +08:00

7.2 KiB

Building and inspecting packages

Development reference and historical context. For current operating instructions, use the user manual. Acceptance applies only to the source and artifacts identified in each record.

Documentation index · Development · Glossary

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

./tools/build-package hello

The helper runs xbps-src -a aarch64 pkg hello and exports the main package to:

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:

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:

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:

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.

Host, build container, and target architectures

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.

The build deliberately ignores directories without a template. Development explains how active overlays are copied without changing upstream files.

The builder assembles a configured rootfs tar from this explicit set; see Rootfs. M2 adds native init and verifies it with a full ARM VM boot. 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 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 captures selected packages and build dependencies and compares independent offline builds. See its acceptance status before making a reproducibility claim.