Skip to content

Legacy glibc build for Ubuntu 22.04, Debian 12 and Raspberry Pi OS - #23

Merged
sanohiro merged 3 commits into
mainfrom
fix/legacy-glibc-build
Sep 27, 2026
Merged

sanohiro merged 3 commits into
mainfrom
fix/legacy-glibc-build

Conversation

@sanohiro

Copy link
Copy Markdown
Owner

Fixes #22.

Problem

Release binaries are built on Ubuntu 24.04 and require GLIBC_2.39, so they
fail at startup on Ubuntu 22.04, Debian 12 (bookworm) and Raspberry Pi OS
(bookworm):

bcon: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.39' not found

The .deb declared no libc6 dependency, so apt installed it without
complaint and the failure only appeared at runtime.

Changes

A second set of binaries is built inside an ubuntu:22.04 container. They need
only glibc 2.34, which covers jammy and bookworm, and are published under a new
apt legacy suite alongside the unchanged stable suite. install.sh reads
the system's glibc and selects the suite, so existing 24.04+ installs keep
receiving exactly the same packages as before
— the stable build jobs, its
.deb and its pool are untouched.

Three other bugs surfaced while testing this:

  • libsystemd-dev was missing from the build dependencies. libseat.pc
    has Requires.private: libsystemd, and it only worked because the GitHub
    runner image preinstalls it. A clean build following docs/installation.md
    failed at libseat-sys. Fixed in the workflows and in the docs.
  • install.sh could not be re-run. gpg --dearmor -o prompts before
    overwriting an existing keyring, and under curl | sh there is no tty, so it
    died with cannot open '/dev/tty'. Now passes --yes.
  • dpkg-scanpackages --arch filters by filename, not by the control field.
    bcon_amd64_legacy.deb does not match *_amd64.deb, which silently produced
    empty Packages files for the whole legacy suite. Packages are now named
    bcon_legacy_<arch>.deb.

The .deb libc6 dependency is now derived from the binary's own symbol
versions, so apt refuses a build the system cannot run instead of failing at
runtime.

Verification

Verified in containers (a real TTY was not available, so this covers packaging
and installation, not rendering):

Ubuntu 22.04 Debian 12 Ubuntu 24.04
suite selected legacy (glibc 2.35) legacy (glibc 2.36) stable (glibc 2.39)
apt install bcon resolves resolves resolves
upgrade from an existing 1.5.0 install kept back, then upgrades after re-running install.sh same upgrades directly
re-running install.sh switches to legacy switches to legacy no change

A 22.04 build of the real binary completes and requires at most GLIBC_2.34
(verified on aarch64).

Note for the release

The version must be bumped. If legacy ships as 1.5.0, users who already have
1.5.0 installed will not get the replacement package — apt sees the same
version and does nothing, leaving them broken.

Still unverified: whether bcon actually starts on a real 22.04 or bookworm
machine. Worth asking the reporter of #22 to confirm after the release.

🤖 Generated with Claude Code

sanohiro and others added 3 commits September 27, 2026 23:19
Release binaries are built on Ubuntu 24.04 and require GLIBC_2.39, so they
fail to start on Ubuntu 22.04, Debian 12 (bookworm) and Raspberry Pi OS
(bookworm). The .deb declared no libc6 dependency, so apt installed it
without complaint and the failure only appeared at runtime (#22).

Build a second set of binaries inside an ubuntu:22.04 container. They need
only glibc 2.34, which covers jammy and bookworm, and are published under a
new apt "legacy" suite alongside the unchanged "stable" suite. install.sh
reads the system's glibc and picks the suite, so existing 24.04+ installs
keep getting exactly the same packages as before.

Also:
- Pass --yes to gpg --dearmor in install.sh. Re-running the installer hung
  on the overwrite prompt once the keyring existed, which made "just run it
  again" impossible under curl | sh.
- Derive the .deb libc6 dependency from the binary's own symbol versions so
  apt refuses a build the system cannot run.
- Add libsystemd-dev to the build dependencies. libseat.pc requires it and
  it only worked because the runner image preinstalls it; a clean build
  following docs/installation.md failed at libseat-sys.
- Name the legacy packages bcon_legacy_<arch>.deb, since dpkg-scanpackages
  --arch filters by filename suffix and silently produced empty Packages
  files for bcon_<arch>_legacy.deb.

Verified in containers: 22.04, bookworm and 24.04 each select the right
suite and apt install resolves.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
- Build packages with dpkg-deb --root-owner-group. The release job runs as
  the runner user (uid 1001), so every path in the .deb carried that uid and
  installed files ended up owned by whichever local user happens to hold it
  rather than root. bcon runs as root from systemd, so that user could
  replace the binary. Pre-existing, but this block was rewritten here.

- Default install.sh to the legacy suite when the glibc version cannot be
  parsed. legacy runs everywhere stable does, so a detection failure now
  degrades to a working install instead of an unsatisfiable libc6 dependency.

- Document Raspberry Pi OS support as 64-bit only. Only amd64 and arm64 are
  built and the Release file declares as much, so on 32-bit armhf the
  installer succeeds and apt install then fails with "Unable to locate
  package bcon" and no explanation.

- Note that apt replaces the package across a suite switch even when the
  version is unchanged, since the installed version is no longer offered by
  any configured suite.

Two other review findings did not hold up. Ubuntu's objdump (binutils 2.42)
is multi-target and reads aarch64 ELFs from an amd64 runner, so the symbol
version lookup is not silently falling back for arm64. And switching suites
at an identical version does replace the package, so --reinstall is not
needed; both were checked in containers.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
All four carry a shebang and are meant to be run directly.
tests/automation/bcon-test-input had lost its executable bit, which breaks
the symlink-into-PATH workflow described in tests/automation/README.md.
CI only runs `bash -n` on it, so nothing would have caught this.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@sanohiro
sanohiro merged commit 26fffff into main Sep 27, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Ubunntu 22.04 Not Work

1 participant