From 13c915106243abf819ca09a1e626fc0145faf458 Mon Sep 17 00:00:00 2001 From: speak-agent Date: Wed, 19 Aug 2026 12:57:36 +0800 Subject: [PATCH 1/3] =?UTF-8?q?feat:=20std-freestanding=200.1.0=20?= =?UTF-8?q?=E2=80=94=20the=20freestanding=20subset=20of=20the=20standard?= =?UTF-8?q?=20library?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `import std;` is one module over the whole library, so there is no subset of IT to build without an OS — mcpp turns it off on a freestanding target and says so. But libc++'s HEADERS are almost entirely freestanding-capable already; what stops them is one per-target file, `__config_site`, which the toolchain ships only for its own host triple. Synthesising that file is this package's job. 103 of libc++'s 110 headers compile for riscv64-none-elf. The other 7 (generator, hazard_pointer, rcu, spanstream, stacktrace, stdfloat, text_encoding) fail on an x86_64 host with full libc++ and glibc too — they are headers libc++ has not implemented, so the freestanding loss at compile time is zero. The package's regeneration script prints that control group on every run. Verified running under qemu: array, span, optional, atomic, string_view, and ranges::sort with a projection. `xim:llvm` is an install-time dependency because that is where libc++'s headers live. Nothing is linked from it — the package includes them privately and exports a module — but without the payload there is nothing to include, and the failure would surface as "file not found" inside a module compile instead of as a missing dependency. Requires mcpp >= 2026.8.19.4: earlier versions do not put `-fno-exceptions` on a freestanding target, and `std::optional::value()` alone then pulls in `__cxa_throw` and three more symbols that cannot exist without an unwinder. --- pkgs/s/std-freestanding.lua | 60 +++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 pkgs/s/std-freestanding.lua diff --git a/pkgs/s/std-freestanding.lua b/pkgs/s/std-freestanding.lua new file mode 100644 index 0000000..6a42ea7 --- /dev/null +++ b/pkgs/s/std-freestanding.lua @@ -0,0 +1,60 @@ +-- std-freestanding — the freestanding subset of the C++ standard library. +-- +-- Form A, and `deps` at the xpm PLATFORM level, for the same two reasons as +-- riscv-virt-rt: the package ships a `build.mcpp` (which mcpp looks for at the +-- package ROOT, so Form B would leave it one level down inside the tarball's +-- wrap directory and unfound), and mcpp materializes `[xlings] deps` for the +-- ROOT project only, so a consumer would otherwise get the package with +-- neither the target C library nor the toolchain whose payload carries +-- libc++'s headers. +-- +-- ⚠️ `xim:llvm` is a dependency because that is where libc++'s HEADERS live. +-- The package does not link anything from it — it privately includes the +-- headers and exports a module — but without the payload there is nothing to +-- include, and the failure would arrive as "file not found" deep inside a +-- module compile rather than as a missing dependency. +package = { + spec = "1", + namespace = "mcpplibs", + name = "std-freestanding", + description = "The freestanding subset of the C++ standard library as one module — import mcpplibs.std.freestanding", + licenses = {"Apache-2.0"}, + repo = "https://github.com/mcpplibs/std-freestanding", + type = "package", + + xpm = { + linux = { + deps = { "xim:picolibc-riscv@1.8.12", "xim:llvm" }, + ["0.1.0"] = { + url = { + GLOBAL = "https://github.com/mcpplibs/std-freestanding/archive/refs/tags/0.1.0.tar.gz", + CN = "https://gitcode.com/mcpp-res/std-freestanding/releases/download/0.1.0/std-freestanding-0.1.0.tar.gz", + }, + sha256 = "b93b46d9267004eb409aa55fa8042173f93e71c68604969d54c1930baaf65abe", + }, + }, + macosx = { + deps = { "xim:picolibc-riscv@1.8.12", "xim:llvm" }, + ["0.1.0"] = { + url = { + GLOBAL = "https://github.com/mcpplibs/std-freestanding/archive/refs/tags/0.1.0.tar.gz", + CN = "https://gitcode.com/mcpp-res/std-freestanding/releases/download/0.1.0/std-freestanding-0.1.0.tar.gz", + }, + sha256 = "b93b46d9267004eb409aa55fa8042173f93e71c68604969d54c1930baaf65abe", + }, + }, + windows = { + deps = { "xim:picolibc-riscv@1.8.12", "xim:llvm" }, + ["0.1.0"] = { + url = { + GLOBAL = "https://github.com/mcpplibs/std-freestanding/archive/refs/tags/0.1.0.tar.gz", + CN = "https://gitcode.com/mcpp-res/std-freestanding/releases/download/0.1.0/std-freestanding-0.1.0.tar.gz", + }, + sha256 = "b93b46d9267004eb409aa55fa8042173f93e71c68604969d54c1930baaf65abe", + }, + }, + }, + + -- The package's own manifest, inside the tarball's wrap directory. + mcpp = "*/mcpp.toml", +} From 4f48c55ce5c006141b7abde6a1e24f01e9a28655 Mon Sep 17 00:00:00 2001 From: speak-agent Date: Wed, 19 Aug 2026 13:21:47 +0800 Subject: [PATCH 2/3] =?UTF-8?q?feat:=20std-freestanding=200.2.0=20+=20risc?= =?UTF-8?q?v-virt-rt=200.3.0=20=E2=80=94=20the=20target=20owns=20its=20C?= =?UTF-8?q?=20library?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Both packages declared `xim:picolibc-riscv@1.8.12`, and the standard-library subset also declared `xim:llvm`. That pinned a board package and an implementation-neutral library alike to one C library, one architecture, one toolchain and one version of each — none of which is a property of either. mcpp 2026.8.19.4 resolves the target's C library from the target's own row, the way it resolves the compiler: a hosted project never declared glibc, and a bare-metal one no longer declares picolibc. So: * std-freestanding 0.2.0 declares NOTHING. It asks mcpp where the toolchain's headers are, and the target's C headers are already on the compile line. * riscv-virt-rt 0.3.0 declares only the emulator, which is the one xim package that really is a board fact. Its linker line is bare names now, because the search path is there before it says anything. riscv-virt-rt 0.1.0 and 0.2.0 stay listed — published versions someone may have pinned. std-freestanding 0.1.0 is replaced rather than kept: it never reached this index, and it is wrong by construction. Both new versions require mcpp >= 2026.8.19.4. --- pkgs/r/riscv-virt-rt.lua | 41 ++++++++++++++++++++++-------- pkgs/s/std-freestanding.lua | 50 +++++++++++++++++-------------------- 2 files changed, 54 insertions(+), 37 deletions(-) diff --git a/pkgs/r/riscv-virt-rt.lua b/pkgs/r/riscv-virt-rt.lua index 6da525e..d339d82 100644 --- a/pkgs/r/riscv-virt-rt.lua +++ b/pkgs/r/riscv-virt-rt.lua @@ -9,13 +9,13 @@ -- link against nothing. Pointing at the manifest moves the root inside the -- wrap layer, where both the manifest and the program live. -- --- ⚠️ `deps` is at the xpm PLATFORM level, not in the mcpp segment. The two --- entries are xim packages (an emulator and a target sysroot), not mcpp --- packages, so they travel on xim's install-time dependency edge. This matters --- more than it looks: mcpp materializes `[xlings] deps` for the ROOT project --- only, so a consumer that just runs `mcpp add riscv-virt-rt` would otherwise --- get the board package with neither a libc nor an emulator, and find out at --- build.mcpp time. +-- ⚠️ `deps` names the EMULATOR and nothing else. The target's C library is not +-- here because it is not this package's: mcpp resolves it from the target's +-- own row, the way it resolves the compiler. What is left is the one xim +-- package that really is a board fact — how to run an image — and it is at the +-- xpm PLATFORM level because mcpp materializes `[xlings] deps` for the ROOT +-- project only, so a consumer running `mcpp add riscv-virt-rt` would otherwise +-- get a board package with no way to start it. package = { spec = "1", namespace = "mcpplibs", @@ -30,7 +30,7 @@ package = { -- published is a version someone may have pinned. xpm = { linux = { - deps = { "xim:picolibc-riscv@1.8.12", "xim:qemu-riscv@9.2.4-1" }, + deps = { "xim:qemu-riscv@9.2.4-1" }, ["0.1.0"] = { url = { GLOBAL = "https://github.com/mcpplibs/riscv-virt-rt/archive/refs/tags/0.1.0.tar.gz", @@ -45,9 +45,16 @@ package = { }, sha256 = "79f1dc4415a59ba828048eb8706322957723f8a6fd84bde3faba6a377e48242b", }, + ["0.3.0"] = { + url = { + GLOBAL = "https://github.com/mcpplibs/riscv-virt-rt/archive/refs/tags/0.3.0.tar.gz", + CN = "https://gitcode.com/mcpp-res/riscv-virt-rt/releases/download/0.3.0/riscv-virt-rt-0.3.0.tar.gz", + }, + sha256 = "71fc43daa4903d4f3037c204bd2b3be9aea56371b123a4529cc8c0c8c9b7f525", + }, }, macosx = { - deps = { "xim:picolibc-riscv@1.8.12", "xim:qemu-riscv@9.2.4-1" }, + deps = { "xim:qemu-riscv@9.2.4-1" }, ["0.1.0"] = { url = { GLOBAL = "https://github.com/mcpplibs/riscv-virt-rt/archive/refs/tags/0.1.0.tar.gz", @@ -62,9 +69,16 @@ package = { }, sha256 = "79f1dc4415a59ba828048eb8706322957723f8a6fd84bde3faba6a377e48242b", }, + ["0.3.0"] = { + url = { + GLOBAL = "https://github.com/mcpplibs/riscv-virt-rt/archive/refs/tags/0.3.0.tar.gz", + CN = "https://gitcode.com/mcpp-res/riscv-virt-rt/releases/download/0.3.0/riscv-virt-rt-0.3.0.tar.gz", + }, + sha256 = "71fc43daa4903d4f3037c204bd2b3be9aea56371b123a4529cc8c0c8c9b7f525", + }, }, windows = { - deps = { "xim:picolibc-riscv@1.8.12", "xim:qemu-riscv@9.2.4-1" }, + deps = { "xim:qemu-riscv@9.2.4-1" }, ["0.1.0"] = { url = { GLOBAL = "https://github.com/mcpplibs/riscv-virt-rt/archive/refs/tags/0.1.0.tar.gz", @@ -79,6 +93,13 @@ package = { }, sha256 = "79f1dc4415a59ba828048eb8706322957723f8a6fd84bde3faba6a377e48242b", }, + ["0.3.0"] = { + url = { + GLOBAL = "https://github.com/mcpplibs/riscv-virt-rt/archive/refs/tags/0.3.0.tar.gz", + CN = "https://gitcode.com/mcpp-res/riscv-virt-rt/releases/download/0.3.0/riscv-virt-rt-0.3.0.tar.gz", + }, + sha256 = "71fc43daa4903d4f3037c204bd2b3be9aea56371b123a4529cc8c0c8c9b7f525", + }, }, }, diff --git a/pkgs/s/std-freestanding.lua b/pkgs/s/std-freestanding.lua index 6a42ea7..dc96c0d 100644 --- a/pkgs/s/std-freestanding.lua +++ b/pkgs/s/std-freestanding.lua @@ -1,18 +1,17 @@ -- std-freestanding — the freestanding subset of the C++ standard library. -- --- Form A, and `deps` at the xpm PLATFORM level, for the same two reasons as --- riscv-virt-rt: the package ships a `build.mcpp` (which mcpp looks for at the --- package ROOT, so Form B would leave it one level down inside the tarball's --- wrap directory and unfound), and mcpp materializes `[xlings] deps` for the --- ROOT project only, so a consumer would otherwise get the package with --- neither the target C library nor the toolchain whose payload carries --- libc++'s headers. +-- Form A because the package ships a `build.mcpp`, which mcpp looks for at the +-- package ROOT: Form B would leave it one level down inside the tarball's wrap +-- directory, unfound, and the package would resolve and compile and then link +-- against nothing. -- --- ⚠️ `xim:llvm` is a dependency because that is where libc++'s HEADERS live. --- The package does not link anything from it — it privately includes the --- headers and exports a module — but without the payload there is nothing to --- include, and the failure would arrive as "file not found" deep inside a --- module compile rather than as a missing dependency. +-- ⚠️ NO `deps`, and that is the design. This package needs libc++'s headers +-- and the target's C headers, and it gets both by ASKING mcpp +-- (`mcpp::toolchain_dir()`, and the target's libc which mcpp already puts on +-- the compile line) rather than by declaring who provides them. Declaring +-- pinned it to one standard-library implementation, one C library, one +-- architecture and one version of each — none of which it has any business +-- knowing about. package = { spec = "1", namespace = "mcpplibs", @@ -24,33 +23,30 @@ package = { xpm = { linux = { - deps = { "xim:picolibc-riscv@1.8.12", "xim:llvm" }, - ["0.1.0"] = { + ["0.2.0"] = { url = { - GLOBAL = "https://github.com/mcpplibs/std-freestanding/archive/refs/tags/0.1.0.tar.gz", - CN = "https://gitcode.com/mcpp-res/std-freestanding/releases/download/0.1.0/std-freestanding-0.1.0.tar.gz", + GLOBAL = "https://github.com/mcpplibs/std-freestanding/archive/refs/tags/0.2.0.tar.gz", + CN = "https://gitcode.com/mcpp-res/std-freestanding/releases/download/0.2.0/std-freestanding-0.2.0.tar.gz", }, - sha256 = "b93b46d9267004eb409aa55fa8042173f93e71c68604969d54c1930baaf65abe", + sha256 = "c0026e6aa85d207b3dd00c3f2fe2674174c2e25d86a162f64fe70742420efb00", }, }, macosx = { - deps = { "xim:picolibc-riscv@1.8.12", "xim:llvm" }, - ["0.1.0"] = { + ["0.2.0"] = { url = { - GLOBAL = "https://github.com/mcpplibs/std-freestanding/archive/refs/tags/0.1.0.tar.gz", - CN = "https://gitcode.com/mcpp-res/std-freestanding/releases/download/0.1.0/std-freestanding-0.1.0.tar.gz", + GLOBAL = "https://github.com/mcpplibs/std-freestanding/archive/refs/tags/0.2.0.tar.gz", + CN = "https://gitcode.com/mcpp-res/std-freestanding/releases/download/0.2.0/std-freestanding-0.2.0.tar.gz", }, - sha256 = "b93b46d9267004eb409aa55fa8042173f93e71c68604969d54c1930baaf65abe", + sha256 = "c0026e6aa85d207b3dd00c3f2fe2674174c2e25d86a162f64fe70742420efb00", }, }, windows = { - deps = { "xim:picolibc-riscv@1.8.12", "xim:llvm" }, - ["0.1.0"] = { + ["0.2.0"] = { url = { - GLOBAL = "https://github.com/mcpplibs/std-freestanding/archive/refs/tags/0.1.0.tar.gz", - CN = "https://gitcode.com/mcpp-res/std-freestanding/releases/download/0.1.0/std-freestanding-0.1.0.tar.gz", + GLOBAL = "https://github.com/mcpplibs/std-freestanding/archive/refs/tags/0.2.0.tar.gz", + CN = "https://gitcode.com/mcpp-res/std-freestanding/releases/download/0.2.0/std-freestanding-0.2.0.tar.gz", }, - sha256 = "b93b46d9267004eb409aa55fa8042173f93e71c68604969d54c1930baaf65abe", + sha256 = "c0026e6aa85d207b3dd00c3f2fe2674174c2e25d86a162f64fe70742420efb00", }, }, }, From b7f198b4e2303108690fd23b353d9c6d53820136 Mon Sep 17 00:00:00 2001 From: speak-agent Date: Thu, 20 Aug 2026 03:07:12 +0800 Subject: [PATCH 3/3] feat: openkal 0.1.0 and openkal-linux 0.1.0 openkal is a portable kernel application binary interface. The specification package carries the normative declarations and no definitions; the implementation package supplies the definitions for Linux and is maintained as the worked example other implementations follow. A consuming project declares both. The first dependency fixes the version of the contract the project is written against; the second selects an implementation and is ordinarily conditional on the target, so that changing implementation is a change to one line of the manifest and to no line of the source. [dependencies] openkal = "0.1.0" [target.'cfg(os = "linux")'.dependencies] openkal-linux = "0.1.0" Neither descriptor declares xim dependencies. The specification package needs no payload because it defines nothing, and the implementation uses the host C library that mcpp already supplies for a hosted target. --- pkgs/o/openkal-linux.lua | 52 ++++++++++++++++++++++++++++++++++++++++ pkgs/o/openkal.lua | 50 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 102 insertions(+) create mode 100644 pkgs/o/openkal-linux.lua create mode 100644 pkgs/o/openkal.lua diff --git a/pkgs/o/openkal-linux.lua b/pkgs/o/openkal-linux.lua new file mode 100644 index 0000000..e8c80a0 --- /dev/null +++ b/pkgs/o/openkal-linux.lua @@ -0,0 +1,52 @@ +-- openkal-linux --- the reference implementation. +-- +-- No `deps`. The implementation uses the C library of the host, which mcpp +-- already supplies for a hosted target; nothing further is required. +-- +-- The package is listed for every platform because a descriptor's platform +-- table describes availability rather than applicability. A project selects +-- this implementation with a conditional dependency on `cfg(os = "linux")`, +-- and a project that selects it elsewhere fails at compile time, which is the +-- correct place for that failure. +package = { + spec = "1", + namespace = "mcpplibs", + name = "openkal-linux", + description = "The reference implementation of openkal for Linux, maintained as a worked example", + licenses = {"Apache-2.0"}, + repo = "https://github.com/mcpplibs/openkal-linux", + type = "package", + + xpm = { + linux = { + ["0.1.0"] = { + url = { + GLOBAL = "https://github.com/mcpplibs/openkal-linux/archive/refs/tags/0.1.0.tar.gz", + CN = "https://gitcode.com/mcpp-res/openkal-linux/releases/download/0.1.0/openkal-linux-0.1.0.tar.gz", + }, + sha256 = "ea00efa54c5bb3f62b29a9cfd5c8f8f3f32d8ddc6a1da75477893e2c7aca7223", + }, + }, + macosx = { + ["0.1.0"] = { + url = { + GLOBAL = "https://github.com/mcpplibs/openkal-linux/archive/refs/tags/0.1.0.tar.gz", + CN = "https://gitcode.com/mcpp-res/openkal-linux/releases/download/0.1.0/openkal-linux-0.1.0.tar.gz", + }, + sha256 = "ea00efa54c5bb3f62b29a9cfd5c8f8f3f32d8ddc6a1da75477893e2c7aca7223", + }, + }, + windows = { + ["0.1.0"] = { + url = { + GLOBAL = "https://github.com/mcpplibs/openkal-linux/archive/refs/tags/0.1.0.tar.gz", + CN = "https://gitcode.com/mcpp-res/openkal-linux/releases/download/0.1.0/openkal-linux-0.1.0.tar.gz", + }, + sha256 = "ea00efa54c5bb3f62b29a9cfd5c8f8f3f32d8ddc6a1da75477893e2c7aca7223", + }, + }, + }, + + -- The package's own manifest, inside the tarball's wrap directory. + mcpp = "*/mcpp.toml", +} diff --git a/pkgs/o/openkal.lua b/pkgs/o/openkal.lua new file mode 100644 index 0000000..269bf20 --- /dev/null +++ b/pkgs/o/openkal.lua @@ -0,0 +1,50 @@ +-- openkal --- the specification package. +-- +-- Form A because the package is described by its own mcpp.toml. +-- +-- No `deps`. This package declares and does not define; it needs neither a +-- toolchain payload nor a target sysroot, and the implementation that supplies +-- the definitions is selected by the consuming project as a conditional +-- dependency rather than by this descriptor. +package = { + spec = "1", + namespace = "mcpplibs", + name = "openkal", + description = "openkal: a portable kernel ABI specification, and the C++ modules that declare it", + licenses = {"Apache-2.0"}, + repo = "https://github.com/mcpplibs/openkal", + type = "package", + + xpm = { + linux = { + ["0.1.0"] = { + url = { + GLOBAL = "https://github.com/mcpplibs/openkal/archive/refs/tags/0.1.0.tar.gz", + CN = "https://gitcode.com/mcpp-res/openkal/releases/download/0.1.0/openkal-0.1.0.tar.gz", + }, + sha256 = "81952cf4c608cb7ffe4f01c01b0d28a6c606f28ea30b2840de33834917c54f36", + }, + }, + macosx = { + ["0.1.0"] = { + url = { + GLOBAL = "https://github.com/mcpplibs/openkal/archive/refs/tags/0.1.0.tar.gz", + CN = "https://gitcode.com/mcpp-res/openkal/releases/download/0.1.0/openkal-0.1.0.tar.gz", + }, + sha256 = "81952cf4c608cb7ffe4f01c01b0d28a6c606f28ea30b2840de33834917c54f36", + }, + }, + windows = { + ["0.1.0"] = { + url = { + GLOBAL = "https://github.com/mcpplibs/openkal/archive/refs/tags/0.1.0.tar.gz", + CN = "https://gitcode.com/mcpp-res/openkal/releases/download/0.1.0/openkal-0.1.0.tar.gz", + }, + sha256 = "81952cf4c608cb7ffe4f01c01b0d28a6c606f28ea30b2840de33834917c54f36", + }, + }, + }, + + -- The package's own manifest, inside the tarball's wrap directory. + mcpp = "*/mcpp.toml", +}