Skip to content

feat(toolchain): dimensional ABI compatibility model (fix glibc C-lib under libc++)#178

Merged
Sunrisepeak merged 1 commit into
mainfrom
feat/abi-compat-dimensional-model
Jun 27, 2026
Merged

feat(toolchain): dimensional ABI compatibility model (fix glibc C-lib under libc++)#178
Sunrisepeak merged 1 commit into
mainfrom
feat/abi-compat-dimensional-model

Conversation

@Sunrisepeak

Copy link
Copy Markdown
Member

Problem

The capability-driven ABI check (added in 0.0.54) derives a single tcAbi string where stdlibId == "libc++" short-circuits before the glibc fallback:

tcAbi = triple.find("musl") ? "musl"
      : stdlibId == "libc++" ? "libc++"   // ← conflation
      : compiler == MSVC     ? "msvc" : "glibc";

So a clang+libc++ toolchain on x86_64-unknown-linux-gnu — which is glibc at the libc level — is labelled abi=libc++ and rejects any dependency declaring abi:glibc, even pure C libraries like glfw (libc++ is a C++ stdlib, not a libc replacement; it links glibc fine). This blocks building glfw, and anything pulling it, under the llvm toolchain (e.g. the imgui-m module package, which pins llvm@20.1.7).

Full root-cause + reproduction: .agents/docs/2026-06-27-glfw-abi-glibc-vs-libcxx-conflation-analysis.md.

Fix — model ABI as the orthogonal axes it is

dimension values source
libc glibc / musl / msvcrt / macos target triple
cxxStdlib libstdc++ / libc++ / msvc-stl compiler / stdlibId
arch, os target triple
cxxAbi itanium / msvc compiler

A dependency constrains only the dimension(s) it cares about; unspecified dimensions are don't-care. Legacy abi:glibc → the libc dimension only (zero descriptor changes); a new abi:<dim>=<val> form expresses other axes.

Design (single-PR scope, with the L3 reselection seam): .agents/docs/2026-06-27-abi-compat-model-single-pr-design.md.

Changes

  • new src/toolchain/abi.cppmAbiProfile + abi_profile() (single derivation site), parse_abi_capability(), abi_check() (per-dimension, don't-care).
  • src/build/prepare.cppm — replace the conflated tcAbi block with the dimensional check; precise per-dimension diagnostics.
  • src/doctor.cppm — show abi(libc)/cxxstdlib/arch/os instead of one fused string.
  • tests/unit/test_abi.cpp — 11 cases incl. the regression lock.
  • version → 0.0.68 (mcpp.toml + fingerprint.cppm).

Verification (local, fresh 0.0.68)

  • glfw under gcc@16.1.0Finished (no regression)
  • glfw under llvm@20.1.7Finished ✅ (the fix)
  • glfw under --target x86_64-linux-musl → still errors: requires libc=glibc … provides libc=musl (genuine incompatibility, now naming the dimension)
  • mcpp test: 27 unit binaries pass incl. new test_abi
  • doctor: abi(libc)=glibc cxxstdlib=libc++ arch=x86_64 os=linux

Once released, mcpp-index can move the glfw/imgui-module GL smokes back into the blocking CI set.

… under libc++); v0.0.68

The capability-driven ABI check (added 0.0.54) derived a single `tcAbi`
string in which `stdlibId == "libc++"` short-circuited before the glibc
fallback. So a clang+libc++ toolchain on `x86_64-unknown-linux-gnu` (glibc at
the libc level) was labelled abi=libc++ and wrongly rejected dependencies that
declare `abi:glibc` — even pure C libraries like glfw, which link glibc fine
under libc++. This blocked building glfw (and any glibc C lib) under the llvm
toolchain (e.g. the imgui-m module package, which pins llvm@20.1.7).

Model ABI compatibility as the orthogonal axes it actually is:
  libc (glibc/musl/msvcrt/macos)  ← target triple
  cxxStdlib (libstdc++/libc++/…)  ← compiler/stdlibId
  arch / os                       ← target triple
  cxxAbi (itanium/msvc)           ← compiler
A dependency constrains only the dimension(s) it cares about; unspecified
dimensions are don't-care. Legacy `abi:glibc` maps to the libc dimension only;
a new `abi:<dim>=<val>` form expresses other axes. No descriptor changes
needed.

- new src/toolchain/abi.cppm: AbiProfile + abi_profile() (single derivation),
  parse_abi_capability(), abi_check() (per-dim, don't-care).
- prepare.cppm: replace the conflated tcAbi block with the dimensional check;
  precise per-dimension diagnostics.
- doctor.cppm: show abi(libc)/cxxstdlib/arch/os instead of one fused string.
- tests/unit/test_abi.cpp: 11 cases incl. the regression (glibc C-lib under
  libc++ is compatible; glibc dep under musl still mismatches on libc).

Verified locally: glfw builds under BOTH gcc@16.1.0 and llvm@20.1.7; a musl
target still correctly errors ("requires libc=glibc … provides libc=musl").

Design: .agents/docs/2026-06-27-abi-compat-model-single-pr-design.md
Analysis: .agents/docs/2026-06-27-glfw-abi-glibc-vs-libcxx-conflation-analysis.md
@Sunrisepeak Sunrisepeak merged commit 54f3893 into main Jun 27, 2026
5 checks passed
@Sunrisepeak Sunrisepeak deleted the feat/abi-compat-dimensional-model branch June 27, 2026 12:18
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.

1 participant