Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Linux release glibc verification

Issue #730 asked whether the Linux release baseline was glibc 2.28 or 2.30. The v0.8.9 published archives support glibc 2.28 on both x86-64 and AArch64. The release text’s 2.28 requirement needs no correction. This audit was performed on 2026-11-05; it does not qualify unpublished builds.

Published artifact evidence

The downloaded v0.8.9 archives matched their published SHA-256 files:

ArchiveSHA-256
plenty-0.8.9-x86_64-unknown-linux-gnu.tar.gz249526b6536b503227e9b9e176398e74a0becddb8eb3db14a3d6e3b53134015a
plenty-0.8.9-aarch64-unknown-linux-gnu.tar.gz370bb7541ab3ebd2026ca0cbeb036814231bf32728296634c5f9153812c4c2da

For each architecture, scripts/release/check-elf.sh passed for bin/plenty, bin/plentyc, bin/libplenty_dataframe_v1.so and bin/libplenty_linalg_v1.so. All eight files have a highest referenced GLIBC version of 2.28 and GCC symbol version of 4.2.0. The 2.28 reference is statx, a weak undefined symbol. No file references GLIBC_2.30 or a later version. The audit also checked ELF architecture, loader, allowed dynamic libraries, absence of RPATH/RUNPATH and engine SONAMEs. Symbol inspection alone is not an execution test or proof that earlier glibc versions are supported.

Baseline execution

The published archives were tested with the existing scripts/release/smoke-in-container.sh harness, using the pinned AlmaLinux 8 images from scripts/release/toolchain.env:

ArchitectureImage manifest digestExecution
x86-64sha256:8b469a3a78515e8a18ea8fc727e6a3679e1d0c5ba6f58d5b30be3d0d9b86cffeNative x86-64 container
AArch64sha256:29fdedeed8a6707558c9e03b5d3e8f09eac5307cdd0811218d7d55a2cc9ae522ARM64 container under QEMU user emulation

Both containers reported AlmaLinux 8.10 and glibc 2.28. The harness installed only the documented gcc tar gzip prerequisites, disconnected the network, and ran the extracted archives without Rust or a source checkout. It checked both compiler version commands, compiled and executed a program using SQLite and SHA-256, ran a generated project, and repeated the checks after relocating the installation and installing a second copy. The dataframe and linalg smokes additionally exercised their native engines, optional linkage and app-only --dist relocation. All three unmodified smoke scripts passed on x86-64.

The stock ARM compiler smoke first passed compilation, execution and the project check, then failed its missing-linker diagnostic assertion. Under QEMU 10.2.2, invoking absent cc reported linker driver `cc` failed (exit status: 127) rather than the expected installation hint. A temporary copy of smoke-test.sh accepted either diagnostic for that one negative test; the nonzero-exit requirement and all other checks stayed unchanged. The repeated compiler smoke and both unmodified engine smokes passed. This adaptation is not a change to the release harness or evidence that the original ARM diagnostic assertion passed.

These are libc/userspace checks on host Linux 7.2.11-200.fc44.x86_64. They do not qualify the oldest supported kernel, native ARM concurrency or other ARM page sizes. They establish the supported 2.28 baseline for these artifacts; they do not claim that every older version fails or every library operation was exercised.

Current source and generated programs

The source inspected was main commit fefe4bae (the audit worktree base); the published tag was v0.8.9, locally resolved to f65fdda439f8af2e15289c441f5aa626ab59c808. Current build.sh requires glibc 2.28, both release build images are pinned manylinux_2_28 images, and check-elf.sh rejects release binaries above 2.28. This audit did not rebuild current main and does not substitute for its release qualification. The Linux build, ELF audit and smoke scripts used here are unchanged between that tag and the audit base.

The 2.30 reference in the release workflow explanation concerns the upstream ARM mold 3.0.0 build tool: its binary imports gettid@GLIBC_2.30. The ARM baseline build uses its image’s GNU linker instead. Mold is not shipped in the Plenty archive and is not an installation dependency. This tool requirement does not raise the compiler’s glibc baseline.

Programs link against the compiling machine’s C library and startup objects. A program built on a newer distribution may require a newer glibc even when its compiler runs on 2.28. Build on the oldest supported deployment system, and audit and execute the resulting program there. Programs using dataframe or linalg also need the matching engine; the shipped engines passed this 2.28 audit. Locally rebuilt or substituted engines have their own requirements. See installation requirements and native linking.

Repeating the check

Download both archives and their checksum files for the release being checked. From the download directory, verify each checksum, extract the archive, then change to the source checkout and run its audit for each target. Set target to x86_64-unknown-linux-gnu or aarch64-unknown-linux-gnu, and root to the absolute path of the extracted archive directory:

export PLENTY_RELEASE_TARGET="$target"
bash scripts/release/check-elf.sh "$root/bin/plenty" "$root/bin/plentyc"
for engine in dataframe linalg; do
    library="libplenty_${engine}_v1.so"
    bash scripts/release/check-elf.sh --engine "$library" "$root/bin/$library"
done

Run smoke-in-container.sh IMAGE ARCHIVE with each pinned baseline image and its matching archive. On an x86-64 host with ARM binfmt/QEMU already configured, set DOCKER_DEFAULT_PLATFORM=linux/arm64 for the ARM invocation. Keep the checksum file beside the archive. Record the release identity, hashes, image digests, audit output and smoke exit statuses; do not infer artifact compatibility solely from the source configuration.