From 539d49edd83145cf7f2f69abc559e9bcdd3f7720 Mon Sep 17 00:00:00 2001 From: speak-agent Date: Wed, 19 Aug 2026 09:30:26 +0800 Subject: [PATCH 1/2] =?UTF-8?q?feat:=20riscv-virt-rt=200.1.0=20=E2=80=94?= =?UTF-8?q?=20board=20support=20for=20QEMU's=20RISC-V=20virt=20machine?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The first bare-metal package in this index. With it, a firmware project is an ordinary mcpp project: mcpp add riscv-virt-rt@0.1.0 mcpp build --target riscv64-none-elf # + .bin, .map, a size summary mcpp run --target riscv64-none-elf # boots in qemu mcpp test --target riscv64-none-elf and its manifest names no linker script, load address, libc, -nostdlib or emulator — there is no [target.*] section at all. Verified end to end against this tree as a path index: added, downloaded, built and booted, printing from the firmware. Two descriptor choices are load-bearing, both measured rather than assumed: * Form A (`mcpp = "*/mcpp.toml"`), because the package ships a build.mcpp and mcpp looks for that at the package ROOT. Form B leaves the root at the extract dir and absorbs the tarball's wrap layer inside each source glob, which would leave build.mcpp one level down and unfound — the package would resolve and compile, then link against nothing. * `deps` at the xpm PLATFORM level, carrying xim:picolibc-riscv and xim:qemu-riscv. mcpp materializes `[xlings] deps` for the ROOT project only, so the package's own declaration does not reach a consumer. Verified by removing picolibc from the store: `mcpp add` + `mcpp build` reinstalled it and linked; without this edge the build stops at build.mcpp saying the sysroot is declared but not installed. Requires mcpp >= 2026.8.19.2 (build.mcpp calls `mcpp::runner`). No workspace member under tests/examples/: those run on all three platforms with no capability gate, and this one needs an emulator and a target sysroot. The package's own repo CI installs both and boots rv64 and rv32 on every push. --- pkgs/r/riscv-virt-rt.lua | 63 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 pkgs/r/riscv-virt-rt.lua diff --git a/pkgs/r/riscv-virt-rt.lua b/pkgs/r/riscv-virt-rt.lua new file mode 100644 index 0000000..e1b3f74 --- /dev/null +++ b/pkgs/r/riscv-virt-rt.lua @@ -0,0 +1,63 @@ +-- riscv-virt-rt — board support for QEMU's RISC-V `virt` machine. +-- +-- Form A (`mcpp = "*/mcpp.toml"`) rather than an inline Form B table, and the +-- choice is load-bearing rather than stylistic: this package ships a +-- `build.mcpp`, and mcpp looks for that at the PACKAGE ROOT. Form B leaves the +-- root at the extract dir and absorbs the tarball's `riscv-virt-rt-/` wrap +-- layer inside each source glob — which would leave `build.mcpp` one level +-- down, unfound, and the package would resolve, compile its module, and then +-- 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. +package = { + spec = "1", + namespace = "mcpplibs", + name = "riscv-virt-rt", + description = "Board support for QEMU's RISC-V virt machine — picolibc, startup, memory layout and the emulator", + licenses = {"Apache-2.0"}, + repo = "https://github.com/mcpplibs/riscv-virt-rt", + type = "package", + + xpm = { + linux = { + deps = { "xim:picolibc-riscv@1.8.12", "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", + CN = "https://gitcode.com/mcpp-res/riscv-virt-rt/releases/download/0.1.0/riscv-virt-rt-0.1.0.tar.gz", + }, + sha256 = "8afb5ff2e9593b59f1f90029f57d577df454c78cdeff80760894c72aac7e5168", + }, + }, + macosx = { + deps = { "xim:picolibc-riscv@1.8.12", "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", + CN = "https://gitcode.com/mcpp-res/riscv-virt-rt/releases/download/0.1.0/riscv-virt-rt-0.1.0.tar.gz", + }, + sha256 = "8afb5ff2e9593b59f1f90029f57d577df454c78cdeff80760894c72aac7e5168", + }, + }, + windows = { + deps = { "xim:picolibc-riscv@1.8.12", "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", + CN = "https://gitcode.com/mcpp-res/riscv-virt-rt/releases/download/0.1.0/riscv-virt-rt-0.1.0.tar.gz", + }, + sha256 = "8afb5ff2e9593b59f1f90029f57d577df454c78cdeff80760894c72aac7e5168", + }, + }, + }, + + -- The package's own manifest, inside the tarball's wrap directory. + mcpp = "*/mcpp.toml", +} From f81edbed32fda4ba1efdd8a5a4fd33f89cfeecc4 Mon Sep 17 00:00:00 2001 From: speak-agent Date: Wed, 19 Aug 2026 09:34:38 +0800 Subject: [PATCH 2/2] =?UTF-8?q?riscv-virt-rt=200.2.0=20=E2=80=94=20the=20v?= =?UTF-8?q?ersion=20that=20ships=20the=20project=20template?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 0.2.0 adds templates/blinky, so `mcpp new --template riscv-virt-rt` produces a firmware project that builds, boots and tests unmodified. The template ships with the package rather than with mcpp, whose builtin registry is frozen at `bin`; `mcpp new` writes the dependency line at the version it resolved, so the two cannot drift. 0.1.0 stays listed: a version that has been published is a version someone may have pinned. --- pkgs/r/riscv-virt-rt.lua | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/pkgs/r/riscv-virt-rt.lua b/pkgs/r/riscv-virt-rt.lua index e1b3f74..6da525e 100644 --- a/pkgs/r/riscv-virt-rt.lua +++ b/pkgs/r/riscv-virt-rt.lua @@ -25,6 +25,9 @@ package = { repo = "https://github.com/mcpplibs/riscv-virt-rt", type = "package", + -- 0.2.0 adds the project template (`mcpp new --template + -- riscv-virt-rt`); 0.1.0 stays listed because a version that has been + -- published is a version someone may have pinned. xpm = { linux = { deps = { "xim:picolibc-riscv@1.8.12", "xim:qemu-riscv@9.2.4-1" }, @@ -35,6 +38,13 @@ package = { }, sha256 = "8afb5ff2e9593b59f1f90029f57d577df454c78cdeff80760894c72aac7e5168", }, + ["0.2.0"] = { + url = { + GLOBAL = "https://github.com/mcpplibs/riscv-virt-rt/archive/refs/tags/0.2.0.tar.gz", + CN = "https://gitcode.com/mcpp-res/riscv-virt-rt/releases/download/0.2.0/riscv-virt-rt-0.2.0.tar.gz", + }, + sha256 = "79f1dc4415a59ba828048eb8706322957723f8a6fd84bde3faba6a377e48242b", + }, }, macosx = { deps = { "xim:picolibc-riscv@1.8.12", "xim:qemu-riscv@9.2.4-1" }, @@ -45,6 +55,13 @@ package = { }, sha256 = "8afb5ff2e9593b59f1f90029f57d577df454c78cdeff80760894c72aac7e5168", }, + ["0.2.0"] = { + url = { + GLOBAL = "https://github.com/mcpplibs/riscv-virt-rt/archive/refs/tags/0.2.0.tar.gz", + CN = "https://gitcode.com/mcpp-res/riscv-virt-rt/releases/download/0.2.0/riscv-virt-rt-0.2.0.tar.gz", + }, + sha256 = "79f1dc4415a59ba828048eb8706322957723f8a6fd84bde3faba6a377e48242b", + }, }, windows = { deps = { "xim:picolibc-riscv@1.8.12", "xim:qemu-riscv@9.2.4-1" }, @@ -55,6 +72,13 @@ package = { }, sha256 = "8afb5ff2e9593b59f1f90029f57d577df454c78cdeff80760894c72aac7e5168", }, + ["0.2.0"] = { + url = { + GLOBAL = "https://github.com/mcpplibs/riscv-virt-rt/archive/refs/tags/0.2.0.tar.gz", + CN = "https://gitcode.com/mcpp-res/riscv-virt-rt/releases/download/0.2.0/riscv-virt-rt-0.2.0.tar.gz", + }, + sha256 = "79f1dc4415a59ba828048eb8706322957723f8a6fd84bde3faba6a377e48242b", + }, }, },