Pi:dev build environment: Difference between revisions

From SpecNext Wiki
Jump to: navigation, search
No edit summary
via /pi-wiki-publish
 
Line 33: Line 33:
sudo apt-get install -y debootstrap qemu-user-static binfmt-support
sudo apt-get install -y debootstrap qemu-user-static binfmt-support
</syntaxhighlight>
</syntaxhighlight>
<code>qemu-user-static</code> + <code>binfmt-support</code> register handlers so debootstrap can run armhf binaries during second-stage configure. (On Pi 5 the host kernel can also execute armhf natively via aarch32 compat; binfmt-misc is the fallback.)


Verify:
Verify:
Line 44: Line 42:


=== 2. Add the apt signing key ===
=== 2. Add the apt signing key ===
The mirror is signed with the canonical Raspbian archive key (Mike Thompson, fingerprint <code>A0DA 38D0 D76E 8B5D 6388 7281 9165 938D 90FD DD2E</code>). Modern Pi OS Bookworm doesn't ship it, so add it explicitly:


<syntaxhighlight lang="bash">
<syntaxhighlight lang="bash">
Line 69: Line 65:
</syntaxhighlight>
</syntaxhighlight>


debootstrap downloads ~50 MB of <code>.deb</code>s, extracts them, and ends with this warning:
Ends with <code>W: Failure while configuring required packages</code>. Continue.


<pre>
=== 4. Neutralise segfaulting postinsts and force-install ===
W: Failure while configuring required packages.
W: See /srv/nextpi-buildroot/debootstrap/debootstrap.log for details (possibly the package systemd is at fault)
</pre>


This is expected — stretch's <code>systemd</code> postinst segfaults under Pi 5's kernel via aarch32 compat. The next step works around it; systemd is never actually run inside a build chroot.
<syntaxhighlight lang="bash">
 
for pkg in systemd plymouth mountall; do
=== 4. Force-install the unconfigured packages ===
  printf '#!/bin/sh\nexit 0\n' \
 
    | sudo tee /srv/nextpi-buildroot/var/lib/dpkg/info/${pkg}.postinst > /dev/null
The systemd configure failure halts dpkg's pending-configure pass and leaves several packages (including <code>apt</code>) unpacked-but-not-installed. Force them through:
  sudo chmod +x /srv/nextpi-buildroot/var/lib/dpkg/info/${pkg}.postinst
done


<syntaxhighlight lang="bash">
sudo chroot /srv/nextpi-buildroot \
sudo chroot /srv/nextpi-buildroot \
     /usr/bin/env -i PATH=/usr/sbin:/usr/bin:/sbin:/bin LANG=C \
     /usr/bin/env -i PATH=/usr/sbin:/usr/bin:/sbin:/bin LANG=C \
Line 88: Line 81:
</syntaxhighlight>
</syntaxhighlight>


Errors on <code>systemd</code>, <code>plymouth</code>, <code>mountall</code> are expected and harmless.
Errors on <code>systemd</code>, <code>plymouth</code>, <code>mountall</code> are expected. Verify:
 
Verify:


<syntaxhighlight lang="bash">
<syntaxhighlight lang="bash">
Line 108: Line 99:
</syntaxhighlight>
</syntaxhighlight>


These are session-only; see [[#Persistent mounts|Persistent mounts]] below for fstab.
Session-only; see [[#Persistent mounts|Persistent mounts]] for fstab.
 
=== 6. Hold the broken packages ===


So future <code>apt-get install</code> runs don't re-extract systemd and re-trigger the postinst:
=== 6. Hold systemd, plymouth, mountall ===


<syntaxhighlight lang="bash">
<syntaxhighlight lang="bash">
Line 120: Line 109:
</syntaxhighlight>
</syntaxhighlight>


=== 7. Install build dependencies ===
=== 7. Install the NextPi 1.92D package set + dev variants ===


<syntaxhighlight lang="bash">
<syntaxhighlight lang="bash">
sudo chroot /srv/nextpi-buildroot \
sudo chroot /srv/nextpi-buildroot \
     /usr/bin/env -i PATH=/usr/sbin:/usr/bin:/sbin:/bin LANG=C HOME=/root \
     /usr/bin/env -i PATH=/usr/sbin:/usr/bin:/sbin:/bin LANG=C HOME=/root \
     /bin/bash -c "apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
     /bin/bash -c "
        autoconf automake libtool libtool-bin pkg-config \
        apt-get update -qq && \
        libbz2-dev libaudiofile-dev \
        wget -q -O /tmp/buildroot.packages https://zx.xalior.com/nextpi_dev/buildroot.packages && \
        wget git ca-certificates"
        DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
            \$(cat /tmp/buildroot.packages)
    "
</syntaxhighlight>
</syntaxhighlight>


<code>libtool-bin</code> is required separately on stretch — the <code>libtool</code> umbrella package no longer ships the <code>/usr/bin/libtool</code> script.
~50 s on Pi 5 / NVMe; chroot grows to ~2.0 GB. Toolchain check:
 
A <code>W: APT had planned for dpkg to do more than it reported back</code> warning about <code>systemd:armhf</code> will appear on every apt-get run; that's the hold doing its job.
 
Toolchain check:


<syntaxhighlight lang="bash">
<syntaxhighlight lang="bash">
Line 159: Line 146:
</syntaxhighlight>
</syntaxhighlight>


Wall-clock ~10–15 s on Pi 5 / NVMe. Verify:
~10–15 s on Pi 5 / NVMe. Verify:


<syntaxhighlight lang="bash">
<syntaxhighlight lang="bash">
Line 165: Line 152:
# ELF 32-bit LSB shared object, ARM, EABI5 version 1 (SYSV), dynamically linked
# ELF 32-bit LSB shared object, ARM, EABI5 version 1 (SYSV), dynamically linked
</syntaxhighlight>
</syntaxhighlight>
Chroot is ready.


== Persistent mounts ==
== Persistent mounts ==


The bind mounts in step 5 are session-only. For a long-lived build host, add to <code>/etc/fstab</code>:
Add to <code>/etc/fstab</code>:


<syntaxhighlight lang="text">
<syntaxhighlight lang="text">
Line 179: Line 164:
</syntaxhighlight>
</syntaxhighlight>


(<code>/etc/resolv.conf</code> will need re-copying after host reboot regardless.)
<code>/etc/resolv.conf</code> needs re-copying after host reboot.
 
== Sources ==
 
* Apt mirror: <code>http://zx.xalior.com/nextpi_dev stretch main contrib non-free rpi firmware</code>.
* Signing key: https://zx.xalior.com/nextpi_dev/debian_nextpi.key — sha256 <code>ca59cd4f2bcbc3a1d41ba6815a02a8dc5c175467a59bd87edeac458f4a5345de</code>. Byte-identical to https://archive.raspbian.org/raspbian.public.key.
* Package list: https://zx.xalior.com/nextpi_dev/buildroot.packages — 369 entries (NextPi 1.92D installed set, less firmware/kernel/Pi-hardware, plus available <code>-dev</code> variants).
* Smoke-test source: libspectrum 1.6.0 from https://sourceforge.net/projects/fuse-emulator/files/libspectrum/.

Latest revision as of 19:07, 5 May 2026

Working draft. Procedure re-validated 2026-05-05 on Pi OS Bookworm / Pi 5.


Reproducible procedure for setting up a build host that produces stretch-armhf binaries (compatible with the Raspbian-9 base used by NextPi) on any modern aarch64 Raspberry Pi running Pi OS Bookworm.

Why

NextPi releases ship as Raspbian 9 (stretch) armhf binaries. This procedure builds those binaries inside a stretch-armhf chroot hosted on a modern aarch64 Pi. aarch64 hardware can execute armhf userspace natively via aarch32 compat, so the build runs at host CPU speed without QEMU emulation, while the toolchain and libraries remain pinned to stretch for ABI compatibility with the deployment target. Apt sources point at the project's stretch mirror at http://zx.xalior.com/nextpi_dev, which keeps package versions deterministic across build hosts.

Measured speedup, libspectrum 1.6.0 build:

Build host Time Ratio
Pi 3, 4× Cortex-A53 armv7l, SD card (native stretch) 65 s 1.0×
Pi 5, 4× Cortex-A76 aarch64, NVMe (chroot) 11 s 5.9×

Prerequisites

  • Vanilla Pi OS Bookworm on a Pi 4 or Pi 5 with ~5 GB free disk.
  • SSH access as a sudo-capable user.
  • Network reach to zx.xalior.com.

Procedure

1. Install host tooling

sudo apt-get update
sudo apt-get install -y debootstrap qemu-user-static binfmt-support

Verify:

dpkg --print-foreign-architectures   # should list: armhf
ls /proc/sys/fs/binfmt_misc/ | grep qemu-arm

2. Add the apt signing key

curl -sL https://zx.xalior.com/nextpi_dev/debian_nextpi.key \
  | sudo gpg --dearmor -o /etc/apt/trusted.gpg.d/debian_nextpi.gpg

Confirm:

sudo gpg --no-default-keyring --keyring /etc/apt/trusted.gpg.d/debian_nextpi.gpg --list-keys
# pub rsa2048 2012-04-01 [SC] A0DA38D0D76E8B5D638872819165938D90FDDD2E
# uid Mike Thompson (Raspberry Pi Debian armhf ARMv6+VFP)

3. Debootstrap the chroot

sudo debootstrap --arch=armhf --variant=buildd \
    --keyring=/etc/apt/trusted.gpg.d/debian_nextpi.gpg \
    stretch /srv/nextpi-buildroot/ \
    http://zx.xalior.com/nextpi_dev

Ends with W: Failure while configuring required packages. Continue.

4. Neutralise segfaulting postinsts and force-install

for pkg in systemd plymouth mountall; do
  printf '#!/bin/sh\nexit 0\n' \
    | sudo tee /srv/nextpi-buildroot/var/lib/dpkg/info/${pkg}.postinst > /dev/null
  sudo chmod +x /srv/nextpi-buildroot/var/lib/dpkg/info/${pkg}.postinst
done

sudo chroot /srv/nextpi-buildroot \
    /usr/bin/env -i PATH=/usr/sbin:/usr/bin:/sbin:/bin LANG=C \
    /bin/bash -c "dpkg --install --force-depends --force-confdef --force-confold --force-overwrite --force-bad-version --recursive /var/cache/apt/archives/"

Errors on systemd, plymouth, mountall are expected. Verify:

sudo chroot /srv/nextpi-buildroot \
    /usr/bin/env -i PATH=/usr/sbin:/usr/bin:/sbin:/bin LANG=C \
    /bin/bash -c "type apt-get && type gcc"

5. Bind-mount runtime filesystems

for m in proc sys dev dev/pts; do
  sudo mkdir -p /srv/nextpi-buildroot/$m
  sudo mount --bind /$m /srv/nextpi-buildroot/$m
done
sudo cp /etc/resolv.conf /srv/nextpi-buildroot/etc/

Session-only; see Persistent mounts for fstab.

6. Hold systemd, plymouth, mountall

sudo chroot /srv/nextpi-buildroot \
    /usr/bin/env -i PATH=/usr/sbin:/usr/bin:/sbin:/bin LANG=C \
    /bin/bash -c "apt-mark hold systemd plymouth mountall"

7. Install the NextPi 1.92D package set + dev variants

sudo chroot /srv/nextpi-buildroot \
    /usr/bin/env -i PATH=/usr/sbin:/usr/bin:/sbin:/bin LANG=C HOME=/root \
    /bin/bash -c "
        apt-get update -qq && \
        wget -q -O /tmp/buildroot.packages https://zx.xalior.com/nextpi_dev/buildroot.packages && \
        DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
            \$(cat /tmp/buildroot.packages)
    "

~50 s on Pi 5 / NVMe; chroot grows to ~2.0 GB. Toolchain check:

sudo chroot /srv/nextpi-buildroot /usr/bin/env -i PATH=/usr/sbin:/usr/bin:/sbin:/bin /bin/bash -c \
    "gcc --version | head -1; automake --version | head -1; libtool --version | head -1; pkg-config --version"

Expect: gcc 6.3.0, automake 1.15, libtool 2.4.6, pkg-config 0.29.

8. Smoke test: build libspectrum 1.6.0

sudo chroot /srv/nextpi-buildroot \
    /usr/bin/env -i PATH=/usr/sbin:/usr/bin:/sbin:/bin LANG=C HOME=/root \
    /bin/bash -c '
        cd /tmp && \
        wget -q https://sourceforge.net/projects/fuse-emulator/files/libspectrum/1.6.0/libspectrum-1.6.0.tar.gz/download -O libspectrum-1.6.0.tar.gz && \
        tar xzf libspectrum-1.6.0.tar.gz && \
        cd libspectrum-1.6.0 && \
        ./configure --with-fake-glib --quiet && \
        time make -s
    '

~10–15 s on Pi 5 / NVMe. Verify:

file /srv/nextpi-buildroot/tmp/libspectrum-1.6.0/.libs/libspectrum.so.8.10.0
# ELF 32-bit LSB shared object, ARM, EABI5 version 1 (SYSV), dynamically linked

Persistent mounts

Add to /etc/fstab:

/proc        /srv/nextpi-buildroot/proc      none  bind  0 0
/sys         /srv/nextpi-buildroot/sys       none  bind  0 0
/dev         /srv/nextpi-buildroot/dev       none  bind  0 0
/dev/pts     /srv/nextpi-buildroot/dev/pts   none  bind  0 0

/etc/resolv.conf needs re-copying after host reboot.

Sources