Skip to content

Pin Ubuntu libstdc++ runtime before dist-upgrade and make stdlib version check major-series based#521

Draft
phlax with Copilot wants to merge 6 commits into
mainfrom
copilot/pin-libstdc-6-to-gcc-13
Draft

Pin Ubuntu libstdc++ runtime before dist-upgrade and make stdlib version check major-series based#521
phlax with Copilot wants to merge 6 commits into
mainfrom
copilot/pin-libstdc-6-to-gcc-13

Conversation

Copilot AI commented May 7, 2026

Copy link
Copy Markdown
Contributor

install_base was allowing dist-upgrade to pull libstdc++6 from newer GCC series in ubuntu-toolchain-r/test, while the image intent is GCC 13 tooling and a stable runtime expectation. This made ensure_stdlibcc brittle and caused recurring failures when the PPA advanced.

  • Apt pinning added before dist-upgrade

    • Introduced pin_libstdcxx in docker/linux/ubuntu/fun.sh and called it in install_base after repo setup/update and before package install/upgrade.
    • Writes /etc/apt/preferences.d/99-libstdcxx-13 to pin:
      • libstdc++6
      • libgcc-s1
      • gcc-13-base (kept at 13.*)
    • Default pin is 13.*; when no 13.* candidate exists, runtime pin format is derived from the current candidate major/version style to avoid hard failure.
  • Stdlib verification kept diagnostic and less brittle

    • Preserved diagnostic output in ensure_stdlibcc (expected + installed package line).
    • Switched matching to a major-series style expectation with literal grep semantics.
  • Expected version default relaxed

    • Updated docker/linux/ubuntu/Dockerfile:
      • LIBSTDCXX_EXPECTED_VERSION=13.1LIBSTDCXX_EXPECTED_VERSION=13.

Example of the new pinning path:

pin_libstdcxx () {
    candidate_version="$(apt-cache policy libstdc++6 | awk '/Candidate:/ {print $2}')"
    libstdcxx_pin="13.*"
    # fallback when no 13.* is published by the active distro/PPA combo
    ...
    cat > /etc/apt/preferences.d/99-libstdcxx-13 <<EOF
Package: libstdc++6
Pin: version ${libstdcxx_pin}
Pin-Priority: 1001

Package: libgcc-s1
Pin: version ${libstdcxx_pin}
Pin-Priority: 1001

Package: gcc-13-base
Pin: version 13.*
Pin-Priority: 1001
EOF
}
Original prompt

Context

The Ubuntu build image's install_base step in docker/linux/ubuntu/fun.sh adds the ubuntu-toolchain-r/test PPA, then runs apt-get -qq dist-upgrade -y. That PPA ships the latest libstdc++6 (currently 16-20260315-1ubuntu1~20~ppa1 from gcc 16), so dist-upgrade silently upgrades libstdc++6 past the gcc-13 series we actually want.

The trailing ensure_stdlibcc check then greps for LIBSTDCXX_EXPECTED_VERSION (currently 13.1, with open PRs #518 / #519 trying to bump to 13.3), which never matches and fails the build silently. The diagnostic-output change merged via PR #520 confirms the actually-installed version is now 16-....

Bumping the expected version is a treadmill — it will break again every time the PPA advances. The image is meant to ship gcc-13 + the matching libstdc++ runtime, so we should pin libstdc++6 to the gcc-13 series via apt preferences and stop letting dist-upgrade pull in newer libstdc++6 from the toolchain PPA.

Task

Update docker/linux/ubuntu/fun.sh so that, before apt-get dist-upgrade -y runs in install_base, an apt-preferences pin is created that holds libstdc++6 (and friends — see notes) to the gcc-13 series from the toolchain PPA, preventing it from being upgraded to gcc-14/15/16 versions.

Suggested approach:

  1. After add_apt_repos "${APT_REPOS_ENV[@]}" and the subsequent apt-get -qq update, write an apt preferences file that pins libstdc++6 to versions starting with 13.. For example:

    pin_libstdcxx_13 () {
        cat > /etc/apt/preferences.d/99-libstdcxx-13 <<'EOF'
    Package: libstdc++6
    Pin: version 13.*
    Pin-Priority: 1001
    
    Package: gcc-13-base libgcc-s1
    Pin: version 13.*
    Pin-Priority: 1001
    EOF
    }

    Call pin_libstdcxx_13 before the apt_install "${DEV_PACKAGES[@]}" / apt-get -qq dist-upgrade -y lines in install_base.

    Notes:

    • Pin-Priority: 1001 is required to allow downgrades if a newer version is somehow already installed. Priority >1000 permits downgrades; ≤1000 only prevents upgrades.
    • Pinning gcc-13-base and libgcc-s1 to the same series is recommended because they ship together and are co-versioned with libstdc++6. If only libstdc++6 is pinned, dist-upgrade may produce conflicts.
    • If a version glob like 13.* does not behave as expected with this PPA's version strings (e.g. 13.3.0-2ubuntu1~20.04), use Pin: release o=LP-PPA-ubuntu-toolchain-r-test plus Pin: version 13.* combined, or fall back to apt-mark hold after explicitly installing libstdc++6=13.* from the PPA. Pick whichever reliably yields libstdc++6 at a 13.* version after dist-upgrade.
  2. After this change, ensure_stdlibcc's grep for LIBSTDCXX_EXPECTED_VERSION should be updated to match whatever the gcc-13 series resolves to on the PPA at build time. A good default is LIBSTDCXX_EXPECTED_VERSION=13. (note the trailing dot) so any 13.x.y-... version satisfies the check without the treadmill of bumping minors. Make this update wherever LIBSTDCXX_EXPECTED_VERSION is currently set (search the repo for it — likely in a Dockerfile ARG/ENV).

  3. Do not remove the diagnostic output added in ensure_stdlibcc by PR fix(ensure_stdlibcc): surface installed libstdc++6 version in CI logs #520 — keep it so future regressions are easy to debug.

Acceptance criteria

  • install_base succeeds end-to-end on the current ubuntu-toolchain-r/test PPA state (where the latest libstdc++6 is from gcc 16).
  • After install_base completes, apt list --installed libstdc++6 shows a 13.* version (e.g. 13.3.0-...), not 14.* / 15.* / 16.*.
  • ensure_stdlibcc passes (i.e. installed libstdc++6 matches the new LIBSTDCXX_EXPECTED_VERSION).
  • The change is confined to docker/linux/ubuntu/fun.sh and whichever file currently defines LIBSTDCXX_EXPECTED_VERSION (likely a Dockerfile under docker/linux/ubuntu/). Do not change behaviour for non-Ubuntu images.
  • Diagnostic output added by PR fix(ensure_stdlibcc): surface installed libstdc++6 version in CI logs #520 is preserved.

The following is the prior conversation context from the user's chat exploration (may be truncated):

User: ```
(Reading database ... 12223 files and directories currently installed.)
#8 58.93 Preparing to unpack .../archives/apt_2.0.11_amd64.deb ...
#8 58.96 Unpacking apt (2.0.11) over (2.0.10) ...
#8 59.11 Setting up apt (2.0.11) ...
#8 59.38 Processing triggers for libc-bin (2.31-0ubuntu9.18) ...
#8 59.40 update-alternatives: using /usr/bin/gcc-13 to provide /usr/bin/gcc (gcc) in auto mode
#8 59.41
#8 59.41 WARNING: apt does not have a stable CLI interface. Use with caution in scripts.
#8 59.41
#8 ERROR: process "/bin/bash -ec . ./ubuntu/fun.sh && install_base" did not complete successfully: exit code: 1

[env 2/2] RUN --mount=type=tmpfs,target=/var/cache/apt --mount=type=tmpfs,target=/var/lib/apt/lists --mount=type=bind,source=/common_fun.sh,target=/common_fun.sh --mount=type=bind,source=/ubuntu/fun.sh,target=/ubuntu/fun.sh . ./ubuntu/fun.sh && install_base:
58.90 Setting ...

This pull request was created from Copilot chat.

Copilot AI changed the title [WIP] Pin libstdc++6 to gcc-13 series to prevent upgrade issues Pin Ubuntu libstdc++ runtime before dist-upgrade and make stdlib version check major-series based May 7, 2026
Copilot AI requested a review from phlax May 7, 2026 17:26
Copilot finished work on behalf of phlax May 7, 2026 17:26
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.

2 participants