Repository navigation
RFC: mcpp 对裸机/freestanding target 的支持(riscv64-none-elf 类,toy_kernel 用例) #403
Description
背景
用 mcpp 构建一个 RISC-V 64 裸机(freestanding)内核(toy_kernel:无 OS、无 libc、qemu virt 机 -kernel 启动),发现 mcpp 目前没有裸机/freestanding 概念,被迫用大量 hack 才能工作。希望 RFC 讨论 mcpp 如何原生支持这类目标。
关联:#276 讨论的是 hosted 嵌入式 Linux SDK(Buildroot/Yocto,有 libc/sysroot);本文讨论的是无 OS 的裸机(
riscv64-none-elf类,无 libc、无动态链接器),是 #276 未覆盖的另一条线。官方嵌入式设计(.agents/docs/2026-07-24-embedded-platform-support-design.md)决策 #15 曾将 freestanding 推迟,这里重新开放讨论。
具体痛点(toy_kernel 实测)
项目:toy_kernel,RISC-V 64 freestanding 内核,qemu virt 机。
痛点 1:mcpp 无法表达"裸机 target"(最核心)
mcpp.toml 被迫写成这样:
[toolchain]
default = "llvm@22.1.8"
[build]
static_stdlib = false
cxxflags = [
"-ffreestanding", "-nostdlib",
"-fno-rtti", "-fno-exceptions",
"-march=rv64gc", "-mcmodel=medany",
"-mstrict-align",
"-fPIE", "-fno-omit-frame-pointer",
]mcpp 把项目当 x86_64 宿主处理(没有"target 是裸机 riscv64"的概念),-march=rv64gc/-mcmodel=medany 被按宿主架构解析,默认 mcpp build 直接失败:
error: unsupported argument 'medany' to option '-mcmodel=' for target 'x86_64-unknown-linux-gnu'
error: unsupported option '-mstrict-align' for target 'x86_64-unknown-linux-gnu'
error: unknown target CPU 'rv64gc'
痛点 2:mcpp 无法做裸机链接(link.ld + -nostdlib + 无 libc)
裸机链接需要自定义链接脚本 + 无 CRT/libc。Makefile 被迫手动做:
riscv64-linux-gnu-g++ -nostartfiles -nostdlib -static -T link.ld \
-o build/toy_kernel.elf libtoy_kernel.a -lgccmcpp 的链接模型只有 hosted(libc/crt/动态链接器),无自定义链接脚本、无 freestanding 链接模式。
痛点 3:mcpp 无法 run/debug 裸机产物
mcpp run 假设 hosted 可执行文件。裸机需要:
qemu-system-riscv64 -machine virt -cpu max -m 256M \
-nographic -bios default -kernel build/toy_kernel.elf
# 调试: qemu -s -S + gdb 远程Makefile 被迫手写 run/debug/test。
痛点 4:产物目录错乱
--target riscv64-linux-musl(hosted musl)与裸机 hack 混在 target/:
target/x86_64-linux-gnu/.../bin/libtoy_kernel.a # 旧 hack 产物
target/riscv64-linux-musl/.../bin/libtoy_kernel.a # hosted musl 产物
Makefile 靠 find target -name "*.a" | head -1 取第一个,取到哪个全看运气。
痛点 5:汇编 .S 的裸机 flag 靠 glob 透传,脆弱
flags = [{ glob = "src/**/*.S", asmflags = ["-march=rv64gc"] }]mcpp 把汇编也按宿主处理时同样解析错。
可能的讨论方向(开放)
- 裸机 target 的表达:
riscv64-none-elf(无 OS 段)进 kKnownTargets?还是[target.'cfg(freestanding)']谓词? - 链接模型:
CLibMode::None(linkmodel.cppm 已有此枚举)在裸机下如何接自定义-T link.ld+-nostdlib? - run/debug:
mcpp run是否能支持"qemu -kernel"类裸机运行器,或至少提供可配置的 run 命令模板? - import std:裸机无 libc,
import std不可用——是否需要import std降级/关断?freestanding modules 是更大的特性(官方已推迟),但裸机 C++(无 RTTI/异常)是现实的。 - 工具链:
riscv64-none-elf类裸机工具链(newlib/picolibc)在 xim 生态的打包。
期望
- 明确 mcpp 对裸机/freestanding 的定位(支持 / 明确不支持 / 部分支持)。
- 如果是"部分支持",最小可落地形态是什么(比如:让
[target]能表达裸机 triple + 链接脚本 + run 命令模板,先覆盖 RISC-V qemu 场景)。 - toy_kernel 可作为持续验证用例。
环境
- mcpp 2026.8.8.4
- 工具链:llvm@22.1.8(宿主)+ riscv64-linux-musl-gcc 16.1.0(交叉,PR examples: each one writes the rule edge and nothing else #585)
- qemu-system-riscv64 11.0.3
Activity
lildengzi commentedon Aug 10, 2026
当前目标只是记录 toy_kernel 的裸机使用场景,不期望近期实现,供后续设计参考
Sunrisepeak commentedon Aug 20, 2026
xlings 最新版本 已经支持 freestanding 相关开发, 可以更新到最新版本进行尝试