diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a90581ea..9de5c28e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -17,7 +17,7 @@ on: workflow_dispatch: env: - MCPP_VERSION: 2026.8.19.4 + MCPP_VERSION: 2026.8.24.4 XLINGS_VERSION: v2026.8.17.2 XLINGS_NON_INTERACTIVE: '1' @@ -107,61 +107,6 @@ jobs: xlings install xim:qemu-riscv -y XLINGS_HOME="$HOME/.mcpp/registry" xlings install xim:qemu-riscv -y - # ⚠️ THE BUILD TOOL IS BUILT FROM A BRANCH, AND THAT IS TEMPORARY. - # - # This step needs four decisions that no released mcpp makes yet, each of - # which belongs to the tool rather than to this package: - # - # `import std` is gated on whether a package PROVIDES a standard - # library for the target rather than on whether the target is - # freestanding; a package may carry its own std module source; - # `-fno-exceptions` / `-fno-rtti` / `-ffreestanding` come off when the - # graph supplies a C++ runtime built for the target; and unwind tables - # go on, because the compiler turns them off for this kind of target - # and a partial set of tables stops the walk rather than degrading it. - # - # They are on mcpp-community/mcpp#486. Until that is released this job - # builds the tool the same way every other dependency here is taken — - # from the branch — so the criterion below is actually enforced instead - # of being a comment saying it was verified once on a laptop. - # - # ⇒ When #486 ships, delete this step and raise MCPP_VERSION. - - name: The build tool, from the branch that has what this needs - if: matrix.toolchain == 'llvm@22.1.8' - run: | - set -euo pipefail - git clone --depth 1 -b feat/import-std-capability \ - https://github.com/mcpp-community/mcpp "$RUNNER_TEMP/mcpp-src" - cd "$RUNNER_TEMP/mcpp-src" - # ⚠️ THE CLONE CARRIES A WORKSPACE PIN, AND IT NAMES A VERSION THE - # INDEX NO LONGER HAS. - # - # xlings: version '2026.8.17.1' not found for 'mcpp' - # available: 2026.8.19.4 - # - # `.xlings.json` at a repository root says which mcpp a build in that - # tree uses, and mcpp's own bootstrap pin does not move when mcpp is - # released — it is the version that was current when the pin was last - # touched. Cloning the branch therefore imports a pin that is only - # valid inside that repository's own CI, where the same file selects - # what gets installed. - # - # Rewriting it to the version this job already installed is what makes - # the two agree. It changes nothing about what is being tested: the - # pin selects the tool that BUILDS mcpp, and what is under test is the - # mcpp that comes out. - printf '{\n "workspace": {\n "mcpp": "%s"\n }\n}\n' "$MCPP_VERSION" > .xlings.json - # ⚠️ `--dev` AND NOT `--release`. What is under test is a set of - # decisions the tool makes about compile flags; an optimisation level - # changes none of them. Measured: the release self-build took over - # half an hour of a sixty-minute job on a two-core runner, which is - # most of the budget spent on something the test does not observe. - mcpp build --dev - BUILT=$(find target -type f -name mcpp -perm -u+x | head -1) - [ -n "$BUILT" ] || { echo "::error::mcpp did not build"; exit 1; } - echo "$(cd "$(dirname "$BUILT")" && pwd)" >> "$GITHUB_PATH" - "$BUILT" --version - - name: The same source on bare metal, with exceptions if: matrix.toolchain == 'llvm@22.1.8' run: | @@ -175,7 +120,18 @@ jobs: grep -q '"qemu-system-riscv64"' mcpp.toml \ || { echo "::error::the manifest no longer carries the bare emulator name"; exit 1; } sed -i "s|\"qemu-system-riscv64\"|\"$Q\"|" mcpp.toml - mcpp run 2>&1 | tee out.log + # ⚠️ `--target riscv64-none-elf`, AND THE FLAG IS THE WHOLE STEP. + # + # This manifest carries no `[build] target`, so a bare `mcpp run` + # builds for the HOST and passes — the four lines below appear either + # way, which is the manifest's own claim and not an accident. A step + # named "on bare metal" that omits the flag therefore reports green + # over a host build and has never once reached OpenSBI. Measured + # 2026-08-24: the artefact was `target/x86_64-linux-gnu/…`. + mcpp run --target riscv64-none-elf 2>&1 | tee out.log + # The emulator's own banner, so a run that never left the host cannot + # satisfy this step by printing the four application lines. + grep -q 'Boot HART' out.log # firmware ran; this is OpenSBI grep -q 'sorted: 2 4 7' out.log # containers + algorithms + the allocator grep -q 'caught: 42' out.log # the unwinder found the handler grep -q 'unwound: true' out.log # ⭐ and ran a destructor on the way @@ -195,8 +151,16 @@ jobs: cd examples/same-source && mcpp run 2>&1 | tee host.log grep -q 'import std over openkal: ok' host.log # The four lines are the same four lines. - diff <(grep -E '^(sorted|caught|unwound|import std over openkal):' out.log) \ - <(grep -E '^(sorted|caught|unwound|import std over openkal):' host.log) + # + # ⚠️ `tr -d '\r'` ON BOTH SIDES, AND IT IS NOT COSMETIC. The bare-metal + # run reaches the console through an emulated 16550 UART, and a serial + # console terminates lines with CRLF; the native run does not. Without + # this the diff reports four differing lines whose visible text is + # identical, which reads as a failure of the claim being tested rather + # than of the transport carrying it. The assertion is about what the + # program printed, not about how the bytes arrived. + diff <(grep -E '^(sorted|caught|unwound|import std over openkal):' out.log | tr -d '\r') \ + <(grep -E '^(sorted|caught|unwound|import std over openkal):' host.log | tr -d '\r') # ⭐⭐ AND THE SAME SOURCE FOR TWO MACHINES THIS ONE IS NOT. # @@ -398,25 +362,6 @@ jobs: mcpp toolchain install llvm 22.1.8 mcpp toolchain default 'llvm@22.1.8' - # ⚠️ Same temporary step as the Linux job: the decisions this exercises are - # on mcpp#486 and not in any release. When that ships, this goes and - # MCPP_VERSION rises. See the long note in the `runtime` job. - - name: The build tool, from the branch that has what this needs - run: | - set -euo pipefail - git clone --depth 1 -b feat/import-std-capability \ - https://github.com/mcpp-community/mcpp "$RUNNER_TEMP/mcpp-src" - cd "$RUNNER_TEMP/mcpp-src" - printf '{\n "workspace": {\n "mcpp": "%s"\n }\n}\n' "$MCPP_VERSION" > .xlings.json - mcpp build --dev - # ⚠️ Named exactly, and `-perm` is not used. On Windows every file - # reads as executable, so a permission test selects nothing useful; - # `mcpp.exe` is the name there and `mcpp` everywhere else. - BUILT=$(find target -type f \( -name 'mcpp' -o -name 'mcpp.exe' \) | head -1) - [ -n "$BUILT" ] || { echo "::error::mcpp did not build"; exit 1; } - echo "$(cd "$(dirname "$BUILT")" && pwd)" >> "$GITHUB_PATH" - "$BUILT" --version - - name: Every target, from this host run: | set -euo pipefail diff --git a/mcpp.toml b/mcpp.toml index 51417bdb..3aaa7b76 100644 --- a/mcpp.toml +++ b/mcpp.toml @@ -18,39 +18,47 @@ repo = "https://github.com/mcpplibs/openkal-llvm-runtime" # The older spelling is kept beside the current one so that an engine # predating the layer vocabulary still recognises this package. Both name the # same layer; a newer engine reads the second and ignores the first. -provides = ["hosted-standard-library", "mcpp:c++-abi=libc++"] +provides = [ + "hosted-standard-library", + "mcpp:c++-abi=libc++", + # ⚠️ THE LARGER HALF OF THIS PACKAGE, AND IT IS NOT A C++ THING. + # + # Of the 729 objects built here, 498 are compiler-rt's builtins and 21 are + # libunwind's. Those are what a C PROGRAM needs — `__udivti3` and its + # relatives have nothing to do with C++ — so declaring them under the C++ + # layer would say this package supplies something it does not and conceal + # something it does. + "mcpp:compiler-runtime=compiler-rt", +] -# ⚠️ THE COMPILER RUNTIME IS THE LARGER HALF OF THIS PACKAGE AND IS NOT YET -# DECLARED, BECAUSE DECLARING IT WOULD MAKE THIS MANIFEST UNREADABLE TO EVERY -# RELEASED BUILD TOOL. -# -# Measured: of the 729 objects built here, 498 are compiler-rt's builtins and 21 -# are libunwind's. Those are what a C PROGRAM needs — `__udivti3` and its -# relatives have nothing to do with C++ — so declaring them under the C++ layer -# says this package supplies something it does not and conceals something it -# does. -# -# The layer is named `mcpp:compiler-runtime` from mcpp 2026.8.24.2, and a build -# tool released before that reports: -# -# error: `provides = ["mcpp:compiler-runtime=compiler-rt"]` names no -# capability mcpp knows. -# -# ⚠️ That refusal is itself fixed in 2026.8.24.2 — an unknown layer name in a -# DEPENDENCY's manifest is now ignored with a warning rather than refused — but -# the fix cannot apply retroactively to tools already released. -# -# ⚠️ AND THE CRITERION IS NOT THIS PACKAGE'S FLOOR. It is what the index serves, -# because that is what a reader of this file actually has. Measured 2026-08-24 -# against the two keys, with a dependency declaring each and a build tool taken -# from the version the index named `latest`: -# -# requires = ["mcpp:compiler=llvm"] 2026.8.24.1 exit 0, ignored -# provides = ["mcpp:compiler-runtime=…"] 2026.8.24.1 exit 2, refused -# -# So `requires` is safe to publish today and the layer declaration is not. The -# gate on adding it is that the index's `latest` be at 2026.8.24.2 or above — -# not that a newer mcpp exists, and not that this package's floor was raised. +# ── The floor this declaration puts under the package ─────────────────────── +# +# `mcpp:compiler-runtime` is a layer name mcpp learned in 2026.8.24.2. Measured +# 2026-08-24, one dependency declaring one key, each build tool taken from a +# published release: +# +# requires = ["mcpp:compiler=llvm"] 2026.8.19.4 exit 0 not validated +# 2026.8.24.1 exit 0 not validated +# provides = ["mcpp:compiler-runtime=…"] 2026.8.19.4 exit 0 not validated +# 2026.8.24.1 exit 2 REFUSED +# 2026.8.24.3 exit 0 resolved +# +# ⚠️ THE TWO ZEROES AT 2026.8.19.4 ARE NOT THE SAME KIND OF SUCCESS AS THE ONE +# AT 2026.8.24.3. That tool predates the layer vocabulary and ignores the whole +# array, so it neither refuses the declaration nor reads it. A CI pinned there +# would report green over a manifest whose central claim was never examined, +# which is why this package's `MCPP_VERSION` moves in the same change that adds +# the line. It moves to 2026.8.24.4 rather than .3: raising the pin made the +# bare-metal step below reach OpenSBI for the first time, and the step AFTER it +# then failed — `mcpp run --target X` had been recording X's build under the +# host's cache key, so the next bare `mcpp run` exec'd the cross artefact. The +# defect predates this package and was found only because a step that claimed to +# test bare metal started doing so. Fixed in mcpp-community/mcpp#498. +# +# The window that REFUSES is 2026.8.24.1 alone — between the release that began +# validating the `mcpp:` prefix and the one that learned this layer. Publishing +# into it was deferred until the index served a tool past it; the index reached +# 2026.8.24.3 on 2026-08-24 and these packages have no installed base behind it. # What this package needs of the layer it does not supply. #