Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 58 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ jobs:
runs-on: ubuntu-24.04
timeout-minutes: 40
env:
MCPP_VERSION: 2026.8.26.2
MCPP_VERSION: 2026.8.27.1
XLINGS_VERSION: v2026.8.17.2
XLINGS_NON_INTERACTIVE: '1'
# The branch of the specification this backend is verified against. It
Expand Down Expand Up @@ -78,6 +78,34 @@ jobs:
echo "the index has not caught up yet (attempt $attempt of 6); waiting 60s"
sleep 60
done
# ⚠️⚠️ TRANSITION: GIVE THE BOOTSTRAP THE glibc ITS BINDING NAMES.
#
# `xim:glibc`'s `latest` moved from `2.44` to `2.44.2`. A payload
# directory is named after the version a request RESOLVED to, while a
# RuntimeBinding carries the version that was DECLARED — and the xlings
# a released mcpp vendors into its own sandbox still declares `2.44`.
# So a clean machine installs `2.44.2`, the toolchain fixup asks for
# `2.44`, and the build stops before anything is compiled:
#
# error: selected RuntimeBinding glibc@2.44 requires payload
# '…/xpkgs/xim-x-glibc/2.44', but it is not installed
#
# ⚠️ On every NEW machine and on none that already existed, which is why
# it is invisible from a developer's own. Measured on `main` as readily
# as on any branch — the index records the same failure verbatim in
# `pkgs/g/glibc.lua` and states the rule it broke: "The index is DATA
# and the client is a PROGRAM: the consumer ships first."
#
# ⭐ REMOVE THIS once a released mcpp resolves it. `mcpp 2026.8.27.1`
# accepts an installed payload whose version REFINES the requested one
# (`payload_dir_for_version`), so a bootstrap from it needs nothing
# here. Until then the missing payload is simply installed.
if [ -x "$HOME/.mcpp/registry/bin/xlings" ]; then
XLINGS_HOME="$HOME/.mcpp/registry" XLINGS_NON_INTERACTIVE=1 \
"$HOME/.mcpp/registry/bin/xlings" install glibc@2.44 -y -g \
>/dev/null 2>&1 || true
echo "glibc payloads present: $(ls "$HOME/.mcpp/registry/data/xpkgs/xim-x-glibc" 2>/dev/null | tr '\n' ' ')"
fi
mcpp --version
mcpp self config --mirror GLOBAL
# ⭐⭐ CROSS-VALIDATION: BUILD THE mcpp UNDER REVIEW AND USE THAT ONE.
Expand Down Expand Up @@ -246,7 +274,7 @@ jobs:
run:
shell: bash
env:
MCPP_VERSION: 2026.8.26.2
MCPP_VERSION: 2026.8.27.1
XLINGS_VERSION: v2026.8.17.2
XLINGS_NON_INTERACTIVE: '1'
steps:
Expand Down Expand Up @@ -307,6 +335,34 @@ jobs:
echo "the index has not caught up yet (attempt $attempt of 6); waiting 60s"
sleep 60
done
# ⚠️⚠️ TRANSITION: GIVE THE BOOTSTRAP THE glibc ITS BINDING NAMES.
#
# `xim:glibc`'s `latest` moved from `2.44` to `2.44.2`. A payload
# directory is named after the version a request RESOLVED to, while a
# RuntimeBinding carries the version that was DECLARED — and the xlings
# a released mcpp vendors into its own sandbox still declares `2.44`.
# So a clean machine installs `2.44.2`, the toolchain fixup asks for
# `2.44`, and the build stops before anything is compiled:
#
# error: selected RuntimeBinding glibc@2.44 requires payload
# '…/xpkgs/xim-x-glibc/2.44', but it is not installed
#
# ⚠️ On every NEW machine and on none that already existed, which is why
# it is invisible from a developer's own. Measured on `main` as readily
# as on any branch — the index records the same failure verbatim in
# `pkgs/g/glibc.lua` and states the rule it broke: "The index is DATA
# and the client is a PROGRAM: the consumer ships first."
#
# ⭐ REMOVE THIS once a released mcpp resolves it. `mcpp 2026.8.27.1`
# accepts an installed payload whose version REFINES the requested one
# (`payload_dir_for_version`), so a bootstrap from it needs nothing
# here. Until then the missing payload is simply installed.
if [ -x "$HOME/.mcpp/registry/bin/xlings" ]; then
XLINGS_HOME="$HOME/.mcpp/registry" XLINGS_NON_INTERACTIVE=1 \
"$HOME/.mcpp/registry/bin/xlings" install glibc@2.44 -y -g \
>/dev/null 2>&1 || true
echo "glibc payloads present: $(ls "$HOME/.mcpp/registry/data/xpkgs/xim-x-glibc" 2>/dev/null | tr '\n' ' ')"
fi
mcpp --version
mcpp self config --mirror GLOBAL
# ⭐⭐ CROSS-VALIDATION: BUILD THE mcpp UNDER REVIEW AND USE THAT ONE.
Expand Down
13 changes: 13 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,19 @@ scheduler, and clause 6.2 says the remedy for an operation that cannot be
provided is that its absence be expressed by its absence rather than by a
run-time refusal.

The five interfaces version 0.8 adds are absent for the same reason and by the
same rule. This machine has no network, so `net` and `datagram` are not provided.
It has no memory management unit to copy an address space with, so `space` is
not. It has no second execution context to bound a wait against, so `timeout` is
not: an operation here either completes or does not, and a bound upon it would
report an expiry that could never occur. `terminal` is absent because the console
is a serial line whose settings this firmware does not expose; a stream is
reported as interactive and nothing acts upon that fact.

None of the five is a deviation. Clause 6.1 makes an interface an implementation
does not provide absent at the link, so a program requiring one is refused when
it is built rather than when it runs.

⚠️ **`time` used to be on that list, with a reason, and the reason was wrong.**

It read: SBI can arm a timer interrupt, which is a mechanism for a kernel rather
Expand Down
12 changes: 11 additions & 1 deletion examples/hello/mcpp.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,15 @@ runner = ["qemu-system-riscv64", "-machine", "virt", "-nographic",
"-no-reboot", "-bios", "default", "-kernel"]

[dependencies]
openkal = "0.7.0"
# ⚠️ THE FORM MUST MATCH THE ONE THE IMPLEMENTATION USES, not merely the
# version. mcpp refuses a graph in which one package reaches a dependency by
# version and another by git:
#
# dependency 'mcpplibs.openkal' is requested as both a version dep
# (by 'hello') and a git dep (by 'mcpplibs.openkal-opensbi@path').
#
# That is the right refusal --- two forms can name two different trees --- and
# it means an example inside a repository follows that repository's own
# declaration while a change is in flight.
openkal = "0.8.0"
openkal-opensbi = { path = "../.." }
4 changes: 2 additions & 2 deletions mcpp.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
[package]
namespace = "mcpplibs"
name = "openkal-opensbi"
version = "0.1.5"
version = "0.2.0"
description = "An implementation of openkal on the RISC-V Supervisor Binary Interface, portable across every machine whose firmware provides one"
license = "Apache-2.0"

Expand All @@ -33,7 +33,7 @@ repo = "https://github.com/mcpplibs/openkal-opensbi"
# The contract, not an implementation of it. Declaring it turns a version
# mismatch into a resolution-time message rather than a link-time one.
[dependencies]
openkal = "0.7.0"
openkal = "0.8.0"

# ⭐ WHAT RECEIVES CONTROL, WHICH IS A STATEMENT ABOUT THE PROGRAM.
#
Expand Down
Loading