From 3a316c65ca4b255f85fe0e9ed319c92e61402af3 Mon Sep 17 00:00:00 2001 From: sunrisepeak Date: Thu, 20 Aug 2026 18:49:31 +0800 Subject: [PATCH] =?UTF-8?q?fix(riscv-virt-rt):=20=E6=8A=8A=E7=9B=AE?= =?UTF-8?q?=E6=A0=87=20C=20=E5=BA=93=E7=9A=84=E5=AE=89=E8=A3=85=E6=9C=9F?= =?UTF-8?q?=E4=BE=9D=E8=B5=96=E8=BE=B9=E5=8A=A0=E5=9B=9E=20deps?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 0.3.0(#220)从三个平台块里删掉了 `xim:picolibc-riscv@1.8.12`,理由写在 当时的注释里:目标的 C 库「不是这个包的,mcpp 会像解析编译器那样从目标行 解析它」。那句话把两件事折成了一件,而只有第一件是对的: * **构建期** —— 板子不该点名 picolibc:不写 include 路径、不写库名、 不带自己的链接脚本,全部由 mcpp 从目标行推导。0.3.0 在这一点上是对的, 保持不变。 * **安装期** —— 总得有什么让那份载荷**存在**。mcpp 解析编译器走的是会 安装的那条调用;目标 C 库它只在磁盘上**查找**,不在场就静默地不加任何 路径。没有任何代码会去装它。 编译器那个类比正是让这次删除看起来安全的原因。事后在冷 runner 上实测: 整份 CI 日志里 `picolibc` 一次都没出现——glibc 和 llvm 都下载了,它没有 ——随后每次构建都死在指向本包内部的 `'stdio.h' file not found`。重建也没 用,因为第二遍查的还是同一个空位置。 安装期依赖边正是 `xpm.<平台>.deps` 的用途,所以它应该在那里。 ⚠️ 判据是「拿走再装回来」,而且**两个一起拿走**:先只把 qemu 藏起来, 构建报 `Cached riscv-virt-rt`、什么都没装——这条边只在**包自己被安装**时 触发。把包和 qemu 一起藏起来再构建,日志里 `Downloading mcpplibs.riscv-virt-rt` 之后紧跟 `Downloading xim:qemu-riscv@9.2.4-1`,两者都装了回来。机制成立。 ⚠️ 没有给 std-freestanding 加同样的边,而它的描述符注释解释了原因:那个包 服务任意 freestanding 目标,声明一个 RISC-V 专属的 C 库会把它钉死在一个 架构上。这条边属于板级包——它本来就是 RISC-V 加 picolibc。 --- pkgs/r/riscv-virt-rt.lua | 44 +++++++++++++++++++++++++++++++--------- 1 file changed, 34 insertions(+), 10 deletions(-) diff --git a/pkgs/r/riscv-virt-rt.lua b/pkgs/r/riscv-virt-rt.lua index a857526..1e51bf0 100644 --- a/pkgs/r/riscv-virt-rt.lua +++ b/pkgs/r/riscv-virt-rt.lua @@ -9,13 +9,37 @@ -- link against nothing. Pointing at the manifest moves the root inside the -- wrap layer, where both the manifest and the program live. -- --- ⚠️ `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. +-- ⚠️ `deps` NAMES THE TARGET'S C LIBRARY AGAIN, AND REMOVING IT WAS A +-- REGRESSION THAT TOOK FIVE VERSIONS TO SURFACE. +-- +-- 0.3.0 dropped `xim:picolibc-riscv` from these three lines, reasoning that the +-- target's C library "is not this package's: mcpp resolves it from the target's +-- own row, the way it resolves the compiler". Two different statements were +-- folded into one there, and only the first is true: +-- +-- BUILD TIME the board must not name picolibc — no include path, no library +-- name, no linker script of its own. mcpp derives all of it from +-- the target row. 0.3.0 was right about this and it stands. +-- INSTALL TIME something has to make the payload EXIST. mcpp resolves the +-- compiler through an installing call; the target's C library it +-- only looks UP on disk, and when absent it silently adds no +-- paths. Nothing installs it. +-- +-- The compiler comparison is what made the removal look safe. Measured on a +-- cold runner afterwards: `picolibc` appears nowhere in the entire CI log — +-- glibc and llvm download, it does not — and every build then dies on +-- `'stdio.h' file not found` pointing inside this package. Rebuilding does not +-- help, because the second build looks in the same empty place as the first. +-- +-- An install-time edge is exactly what `xpm..deps` is, so that is +-- where it belongs. It is at the PLATFORM level rather than in the package's +-- own `[xlings]` because mcpp materializes `[xlings] deps` for the ROOT project +-- only — a consumer running `mcpp add riscv-virt-rt` would otherwise get a +-- board package with neither a C library nor a way to start an image. +-- +-- ⚠️ The criterion for this edge is "take it away and put it back": on a +-- machine that already has the payload, its presence and its absence look +-- identical. -- ⚠️ 0.4.0's `nolibc` template generates a project that does not run. The -- scaffolder injects the template's own package as a dependency, and this -- package's module includes — so on a target with no C library the @@ -38,7 +62,7 @@ package = { -- published is a version someone may have pinned. xpm = { linux = { - deps = { "xim:qemu-riscv@9.2.4-1" }, + 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", @@ -76,7 +100,7 @@ package = { }, }, macosx = { - deps = { "xim:qemu-riscv@9.2.4-1" }, + 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", @@ -114,7 +138,7 @@ package = { }, }, windows = { - deps = { "xim:qemu-riscv@9.2.4-1" }, + 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",