编程语言编译器语言运行时标准库开发工具【免费下载链接】sdkThe Dart SDK, including the VM, JS and Wasm compilers, analysis, core libraries, and more.项目地址https://gitcode.com/gh_mirrors/sdk1/sdk点击查看免费下载在 x64 开发机上验证 Dart 编译器对全部 6 种支持架构的改动时Dart SDK 提供了 ARM 与 RISC-V 模拟器sim 架构但 FFI 场景要求运行时与外部库架构一致只能靠交叉编译加 QEMU 用户态模拟解决。本文基于仓库文档 runtime/docs/qemu.md完整讲解如何用tools/build.py交叉构建dartvm、如何在 QEMU 下运行与 GDB 调试、以及如何通过tools/test.py --use-qemu一键跑通整个 FFI 测试套件并结合 tools/gn.py 与 pkg/test_runner/lib/src/runtime_configuration.dart 的源码解释背后的架构命名与 QEMU 调度逻辑。1. 为什么模拟器不够sim 架构与 FFI 的架构一致性要求Dart VM 实现了 ARM 和 RISC-V 的模拟器让 x64 机器上的开发者可以本地测试编译器在所有 6 种支持架构上的行为。但这些模拟器只模拟已编译的 Dart 代码运行时本身仍然运行在 x64 上。这意味着编译出的 Dart 代码ARM/RISC-V与任何外部动态库x64架构不一致Dart 的 FFI 机制不支持这种架构错配。因此要测试 FFI必须让运行时和外部库都处于目标架构ARM/RISC-V下再在 x64 机器上通过 QEMU 用户态模拟执行。1.1 sim 架构的命名规则与工具链映射SDK 构建系统对这类“模拟器构建”有专门的命名约定可以从 tools/gn.py 中确认simarm64_x64形式的架构名中下划线后的部分是宿主host架构模拟器二进制本身在宿主架构上编译运行而 Dart 编译目标仍是 ARM。例如simarm64_x64表示在 x64 上运行的 arm64 模拟器HostCpuForArchtools/gn.py#L65-L96按优先级为每个目标架构选择 C 编译器宿主架构同架构优先其次是同字长架构ARM/RISC-V 有模拟器的情况最后才是跨字长的 AOT 场景TargetCpuForArchtools/gn.py#L100-L138对sim前缀架构按后缀决定 C 目标_x64返回x64_arm64返回arm64以此类推DartTargetCpuForArch则统一剥离sim前缀和c后缀得到 Dart 编译器真正使用的目标架构。这套映射解释了后文测试命令中simarm64_arm64的用法它表示 arm64 模拟器构建、arm64 宿主用于模拟器与运行时同架构部署的场景而simarm_x64表示 x64 宿主机上的 32 位 ARM 模拟器。2. 手动交叉构建并在 QEMU 中运行以下命令序列来自 runtime/docs/qemu.md环境前提为 Debian/Ubuntu 系发行版的 x64 机器# 安装 QEMU 用户态模拟器和 arm64 交叉运行库 $ sudo apt install qemu-user libc6-arm64-cross # 交叉构建 arm64 的运行时与预编译运行时 $ tools/build.py --arch arm64 runtime runtime_precompiled # 通过 QEMU 运行已编译好的 Dart 程序 $ QEMU_LD_PREFIX/usr/aarch64-linux-gnu/ qemu-aarch64 out/DebugXARM64/dartvm hello.dart.dill Hello, world!要点说明tools/build.py是 SDK 的构建入口--arch arm64触发针对 arm64 目标的交叉编译构建产物位于按“模式架构”命名的输出目录如out/DebugXARM64/dartvm是 VM 的二进制可执行文件hello.dart.dill是已编译好的 Dart kernel 文件直接绕过dart命令行工具链可以省掉 QEMU 内不必要的启动开销QEMU_LD_PREFIX/usr/aarch64-linux-gnu/指向libc6-arm64-cross包提供的 arm64 用户态库libc 等所在位置。使用环境变量而非 QEMU 的-L命令行参数是因为涉及子进程的场景不会显式地通过 QEMU 启动子进程并把-L传递下去而环境变量会自然继承。3. 用 GDB 调试 QEMU 中的 Dart VMQEMU 用户态模拟支持 GDB Stub 协议可以在 x64 宿主机上用gdb-multiarch远程调试 QEMU 内运行的 arm64dartvm# 额外安装 gdb-multiarch $ sudo apt install qemu-user libc6-arm64-cross gdb-multiarch # 在 9090 端口开启 GDB 服务并启动 VM $ QEMU_LD_PREFIX/usr/aarch64-linux-gnu/ qemu-aarch64 -g 9090 out/DebugXARM64/dartvm hello.dart.dill # 另一终端 $ gdb-multiarch (gdb) set sysroot /usr/aarch64-linux-gnu/ (gdb) target remote localhost:9090 (gdb) continueqemu-aarch64 -g 9090让 QEMU 监听 9090 端口的 GDB 调试协议set sysroot /usr/aarch64-linux-gnu/告诉 GDB 目标进程的用户态库位置。文档特别建议显式使用set sysroot可以显著减少 GDB 从目标端读取文件内容的传输量避免调试会话因慢速文件传输而卡顿。4. 通过 test.py 一键运行 FFI 测试套件仓库的测试入口 tools/test.py 本身只是薄封装它把参数原样转发给pkg/test_runner/bin/test_runner.dart执行并负责把 Android platform-tools若存在加入PATH。真正解析--use-qemu等选项的是 pkg/test_runner/lib/src/options.dartuse-qemu别名use_qemu运行配置则由 pkg/test_runner/lib/src/runtime_configuration.dart 负责。运行 FFI 测试tests/ffi/的完整命令序列# 安装三组交叉运行库32 位 ARM、64 位 ARM、64 位 RISC-V $ sudo apt install qemu-user libc6-armhf-cross libc6-arm64-cross libc6-riscv64-cross # 先用 x64 宿主的 32 位 ARM 模拟器构建 gen_snapshot $ ./tools/build.py --arch simarm_x64 gen_snapshot # 交叉构建四种架构的运行时32/64 位 ARM、RISC-V64、arm64 宿主模拟器 $ ./tools/build.py --arch arm,arm64,riscv64,simarm64_arm64 runtime runtime_precompiled # 在 QEMU 中跑 FFI 测试dartkkernel 解释/编译与 dartkp预编译 AOT两种编译器 $ ./tools/test.py --arch arm,arm64,riscv64,simarm64_arm64 --use-qemu \ --compiler dartk,dartkp --gen-snapshot-format elf --timeout 500 ffi参数含义参数作用--arch arm,arm64,riscv64,simarm64_arm64测试矩阵覆盖的目标架构列表--use-qemu让 test runner 通过 QEMU 用户态模拟器执行目标二进制--compiler dartk,dartkp分别覆盖 kernel 编译路径dartk与 AOT 预编译路径dartkp--gen-snapshot-format elf指定gen_snapshot产出 ELF 可执行文件而不是dill便于 QEMU 直接加载--timeout 500放大单测试超时QEMU 下执行显著变慢默认超时不够4.1 源码层面的 QEMU 调度逻辑在 pkg/test_runner/lib/src/runtime_configuration.dart 中QemuConfig枚举把每个目标架构映射到具体的 QEMU 可执行文件、CPU 模型和 ELF 解释器前缀enum QemuConfig { ia32._(qemu-i386, max, /usr/lib/i386-linux-gnu/), x64._(qemu-x86_64, max, /usr/lib/x86_64-linux-gnu/), arm._(qemu-arm, max, /usr/arm-linux-gnueabihf/), arm64._(qemu-aarch64, max, /usr/aarch64-linux-gnu/), riscv32._(qemu-riscv32, max, /usr/riscv32-linux-gnu/), riscv64._(qemu-riscv64, rva23u64,zbcon,zacason,zabhaon, /usr/riscv64-linux-gnu/); ... }可以看到simarm64_arm64、arm64、arm64c统一映射到qemu-aarch64而 RISC-V64 使用了带zbc/zacas/zabha扩展的rva23u64CPU 模型与libc6-riscv64-cross提供的用户态库匹配。当useQemu开启时DartVmRuntimeConfiguration 会在命令构造处把 VM 二进制dartvm或预编译产物从可执行位置挪到参数首位并把 QEMU 可执行文件替换为实际入口等价于文档里手动执行的qemu-aarch64 dartvm ...。同时 DartVmRuntimeConfiguration 的超时乘数逻辑 会在 QEMU 模式下把默认超时再乘以 2这也解释了为何测试命令中还需要显式给出--timeout 500进一步放宽。另外第一步单独构建--arch simarm_x64 gen_snapshot的原因在于AOT 编译dartkp路径需要gen_snapshot生成 ELF 快照放在 x64 宿主上以 sim 架构构建可以比在 QEMU 里直接做 AOT 编译快得多——这正是文档 Tips 建议的“把 kernel 与 AOT 编译放在 QEMU 之外”的落地方式。5. 实用技巧与已知限制文档 Tips 章节给出的经验结合仓库实现可作如下解读速度很慢尽量在 QEMU 外做编译kernel 编译和 AOT 编译gen_snapshot都在宿主机上完成QEMU 内只运行最终的dartvm。直接运行dartvm而不是dartCLI可省去 QEMU 中解析命令行包装逻辑的开销。GDB 场景用set sysroot避免 GDB 频繁从 QEMU 端读取文件内容造成的慢速传输。优先用QEMU_LD_PREFIX而非-L涉及子进程时子进程不会自动经由 QEMU 启动并继承-L参数环境变量则天然向下传递。进程挂死时按CtrlA进入 QEMU monitor 界面再处理不响应CtrlC的进程。qemu-user包只提供模拟器本体guest 架构的 libc 等运行库由libc6-arch-cross系列包提供两者必须同时安装。32 位 RISC-V 无法覆盖gclient sync下载的 Clang 不支持 32 位 RISC-V 目标且 Debian/Ubuntu 也没有提供libc6-riscv32-cross之类的包因此当前测试矩阵只覆盖到riscv64QemuConfig中虽有riscv32条目但在主流发行版上无法走通完整 FFI 测试。6. 小结在 Dart SDK 仓库中QEMU 是 x64 开发者本地验证 ARM/RISC-V 目标 FFI 行为的唯一可行路径先用tools/build.py交叉构建各架构运行时用QEMU_LD_PREFIXqemu-aarch64手动运行和gdb-multiarch远程调试最后用tools/test.py --use-qemu把 tests/ffi/ 套件纳入自动化测试。理解 tools/gn.py 中 sim 架构的宿主/目标映射与 pkg/test_runner/lib/src/runtime_configuration.dart 中的QemuConfig调度逻辑可以帮助你在扩展测试矩阵或排查 QEMU 环境问题交叉库缺失、RISC-V 位宽限制时快速定位配置源头。赞分享编程语言编译器语言运行时标准库开发工具【免费下载链接】sdkThe Dart SDK, including the VM, JS and Wasm compilers, analysis, core libraries, and more.项目地址https://gitcode.com/gh_mirrors/sdk1/sdk点击查看免费下载相关推荐Dart SDK 面向 ARM 与 RISC-V 的交叉编译构建指南Building Dart SDK for ARM or RISC-VDart SDK 面向 ARM 与 RISC V 的交叉编译构建指南Building Dart SDK for ARM or RISC V Dart VM编程语言编译器语言运行时标准库开发工具EDK II RISC-V调试QEMU与GDB联合调试环境搭建EDK II RISC V调试QEMU与GDB联合调试环境搭建 引言RISC V固件调试的痛点与解决方案 在RISC V架构精简指令集计算机第五代架构的固件操作系统驱动开发嵌入式RISC-V虚拟机测试QEMU运行Home Assistant OSRISC V虚拟机测试QEMU运行Home Assistant OS 引言智能家居系统的RISC V探索 你是否正在寻找一种高效、低成本的方式来测试Home操作系统嵌入式物联网智能硬件上一篇parallel: 在Mac上运行多线程任务的简单工具下一篇Redis-rb: 一个用于操作Redis的Ruby gem创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考