#!/usr/bin/env bash # Build PNG-enabled iPXE binaries from source. # # Why from source: the official boot.ipxe.org binaries (and the # Debian-packaged ones) are NOT built with CONSOLE_FRAMEBUFFER + # IMAGE_PNG + CONSOLE_CMD, so `console --picture` is a no-op on them — # you can't paint a graphical boot-menu background. iVentoy solves this # by shipping its own iPXE build with exactly those three flags; we do # the same, from upstream iPXE, with a thin auditable config delta # (deploy/ipxe/local/{general,console}.h). # # Why a real cross-compiler instead of QEMU: building amd64 iPXE by # emulating an amd64 gcc under QEMU on an arm64 host intermittently # segfaults cc1 (the reason this was stuck for ~8 releases). Running a # NATIVE arm64 gcc that cross-targets x86_64 (CROSS_COMPILE= # x86_64-linux-gnu-) sidesteps emulation entirely — the compiler is a # native binary, it just emits x86_64 objects. This stage is meant to # run on $BUILDPLATFORM (the native builder arch), NOT the emulated # target platform. # # Outputs (into $DEST), using the filenames OpenPXE's arch mapping # expects: # snponly.efi x86_64 UEFI, PNG-enabled # ipxe.efi x86_64 UEFI, PNG-enabled (bundled drivers) # # We build ONLY x86_64 UEFI, always via the x86_64 cross toolchain # (`x86_64-linux-gnu-gcc`). That's deliberately host-arch-agnostic: it # works whether this stage runs on an arm64 Mac builder or an amd64 CI # runner, because the cross compiler runs native and emits x86_64 # either way. Building arm64-efi or BIOS here would re-introduce a # dependency on the host arch (native arm64 build) or a 32-bit multilib # toolchain — so those arches keep their upstream-fetched (no-PNG) # binaries and fall back to the menu's clean `|| console` text screen. # Modern PXE clients are overwhelmingly x86_64 UEFI, which get the full # graphical background. set -euo pipefail ROOT="$(cd "$(dirname "$0")/.." && pwd)" DEST="${1:-$ROOT/assets/ipxe}" WORK="$(mktemp -d)" trap 'rm -rf "$WORK"' EXIT # Pinned upstream iPXE. Rolling master is fine functionally, but a pin # keeps builds reproducible and protects against a transient master # breakage. Bump deliberately. IPXE_REPO="https://github.com/ipxe/ipxe.git" IPXE_REF="${IPXE_REF:-master}" echo ">> cloning iPXE ($IPXE_REF)" git clone --depth 1 --branch "$IPXE_REF" "$IPXE_REPO" "$WORK/ipxe" 2>/dev/null \ || git clone "$IPXE_REPO" "$WORK/ipxe" SRC="$WORK/ipxe/src" echo ">> applying OpenPXE config overrides (PNG + framebuffer + console cmd)" mkdir -p "$SRC/config/local" cp "$ROOT/deploy/ipxe/local/general.h" "$SRC/config/local/general.h" cp "$ROOT/deploy/ipxe/local/console.h" "$SRC/config/local/console.h" mkdir -p "$DEST" # x86_64 UEFI — cross-compiled with the native arm64 gcc targeting # x86_64. HOST_CC stays the native cc for iPXE's build-time utilities # (elf2efi, zbin, …); only the target objects use the cross compiler. echo ">> building x86_64 UEFI (snponly.efi, ipxe.efi)" make -C "$SRC" -j"$(nproc)" \ CROSS_COMPILE=x86_64-linux-gnu- \ bin-x86_64-efi/snponly.efi \ bin-x86_64-efi/ipxe.efi cp "$SRC/bin-x86_64-efi/snponly.efi" "$DEST/snponly.efi" cp "$SRC/bin-x86_64-efi/ipxe.efi" "$DEST/ipxe.efi" echo ">> iPXE build complete:" ls -l "$DEST"/snponly.efi "$DEST"/ipxe.efi