.NET 生态系统中 LoongArch 与 RISC-V 的整合深度分析

摘要

随着全球计算架构逐渐从 x64/ARM 的双寡头垄断向更加多元化的方向演进,开源指令集架构(ISA)RISC-V 与中国自主研发的 LoongArch(龙架构)正迅速成为嵌入式系统、物联网(IoT)及服务器领域不可忽视的力量。微软.NET 平台作为跨平台应用开发的基石,在迈向.NET 10 的演进过程中,虽然对主流架构的支持愈发稳固,但对这两个新兴架构的支持却呈现出一种复杂且微妙的“半官方”状态。

本文旨在对这一现状进行详尽的技术调研与战略分析。研究发现,尽管.NET 核心代码库(CoreCLR、CoreFX)已在主分支中包含了对 RISC-V 和 LoongArch 的大量上游支持代码,但由于微软严格的分层支持策略(Tiered Support Policy),这两个架构目前仍处于“社区支持(Tier 3)”层级。这意味着官方 NuGet.org 并不提供针对 linux-riscv64 或 linux-loongarch64 的预编译运行时包(Runtime Packs),导致开发者无法通过标准的 dotnet publish 流程直接构建应用。

目前的生态系统依赖于非官方的“补给线”:RISC-V 领域主要依靠 Filip Navara 等核心贡献者维护的社区构建与 GitHub Actions 流水线;而 LoongArch 则呈现出一种由龙芯中科(Loongson Technology)主导的“旧世界”与开源社区推动的“新世界”ABI(应用程序二进制接口)并存的割裂局面,龙芯中科重点转向支持“新世界”ABI 2.0,主要依赖 nuget.loongnix.cn 等专用源。本文将深入剖析这些非官方解决方案的技术细节、跨平台编译(Cross-Compilation)的构建链挑战、Native AOT(本机提前编译)在嵌入式场景下的具体实施路径,以及企业在采用这些架构时必须考量的供应链安全风险。

1. 新兴架构在.NET 战略版图中的定位

1.1 架构多元化的驱动力

.NET 10 的发布周期正值计算硬件发生深刻变革的时期。RISC-V 凭借其模块化和免许可费的特性,正在重新定义边缘计算和微控制器市场;而 LoongArch 则承载着特定地域市场对计算自主可控的战略需求,正试图从桌面端向高性能服务器端突围。对于.NET 生态而言,支持这些架构不仅是技术上的扩展,更是保持平台普适性和生命力的关键 。

然而,这种支持并非一蹴而就。微软在.NET 10 的官方发布说明中,虽然强调了运行时(Runtime)在 JIT 内联、栈分配优化以及对 AVX10.2 的支持,但对于 RISC-V 和 LoongArch 的提及主要集中在代码层面的兼容性,而非产品层面的交付 。这种差异揭示了微软对于架构支持的严谨态度:代码合并意味着技术可行性的验证,而官方二进制发布则意味着商业承诺与服务等级协议(SLA)的绑定。

1.2 “半官方”状态的深层含义

“半官方”一词准确地概括了当前的局面。从代码仓库的角度看,dotnet/runtime 已经接受并合并了由三星(Samsung)、龙芯中科以及社区开发者提交的大量针对 RISC-V 和 LoongArch 的代码 。这些架构的代码与 x64 代码并存于同一个仓库中,甚至共享部分测试基础设施。

但是,从交付物的角度看,它们完全缺席。微软的构建基础设施(CI/CD)虽然在一定程度上涵盖了这些架构(例如通过 QEMU 仿真或合作伙伴提供的有限硬件),但并不生成发布到 NuGet.org 的官方包。这意味着:

  • 缺乏官方 SDK 安装器:用户无法在微软官网下载到针对 LoongArch 或 RISC-V 的.NET SDK 安装包 。
  • NuGet 供应链断裂:标准的 dotnet build 或 dotnet publish 命令会尝试从 NuGet.org 拉取如 Microsoft.NETCore.App.Runtime.linux-riscv64 的包,由于该包不存在,构建过程会直接失败 。
  • 依赖社区修补:开发者必须手动配置 NuGet.config 以指向第三方源,或者自行编译整个运行时,这大大提高了入门门槛 。

这种状态将持续到.NET 10 及其后续版本,直到这些架构的硬件普及率、稳定性以及 CI 基础设施的可靠性达到微软认定为 Tier 2 或 Tier 1 的标准 。

2. LoongArch(龙架构):主权、割裂与生态重构

LoongArch 是一个独特的案例,它不仅是一个新的指令集,更代表了一个完整的、由单一厂商强力推动的软件生态系统。在.NET 的支持路径上,LoongArch 面临着比技术本身更为复杂的生态割裂问题,即所谓的“旧世界”与“新世界”之争。

2.1 ABI 鸿沟:旧世界 vs. 新世界

理解 LoongArch 上的.NET 支持,首先必须理解其 ABI(二进制接口)的演进。

  • 旧世界(Old World / ABI 1.0):这是龙芯早期为了快速兼容 MIPS 生态遗留软件而定义的接口。龙芯自家的操作系统 Loongnix 以及早期的.NET Core 3.1、.NET 6/7 移植工作主要基于此 ABI。由于它是龙芯专有的,并未被上游 Linux 社区广泛接受 。
  • 新世界(New World / ABI 2.0):这是经过标准化并被 Linux 内核(5.19+)、GCC(12+)、LLVM(16+)等上游社区正式接纳的规范。它是 LoongArch 的未来,但与旧世界二进制不兼容 。

这一分裂直接冲击了.NET 开发者。目前,.NET 8 的主要支持力量仍集中在“旧世界”环境(Loongnix),这主要是为了满足存量商业软件的需求。然而,随着.NET 9 和.NET 10 的推进,社区(以及未来的官方支持)正坚决地转向“新世界”ABI。这意味着开发者在 Loongnix 上编译的.NET 应用程序,可能无法在安装了最新 Arch Linux 或 Debian 的 LoongArch 机器上运行,反之亦然 。

2.2 龙芯社区的应对策略与 NuGet 源

为了弥补官方支持的缺失,龙芯开源社区构建了一套独立的基础设施。这不仅仅是一个 GitHub 仓库,而是一个完整的镜像生态。

2.2.1 专用 NuGet 源:nuget.loongnix.cn

这是目前在 LoongArch 平台上开发.NET 应用的生命线。由于微软官方 NuGet 源中没有 LoongArch 的运行时包(Runtime Packs),龙芯团队维护了这个私有源。

  • 功能:该源托管了经过修改并适配 LoongArch 的 Microsoft.NETCore.App.Runtime 包。

  • 配置:开发者必须在项目根目录添加或修改 NuGet.config 文件,显式加入该源。根据调研,典型的配置如下:
    XML
    <?xml version="1.0" encoding="utf-8"?>
    <configuration>
    <packageSources>
    <add key="loongnix" value="https://nuget.loongnix.cn/v3/index.json" />
    <add key="nuget.org" value="https://api.nuget.org/v3/index.json" protocolVersion="3" />
    </packageSources>
    </configuration>

    此配置的优先级至关重要。如果 nuget.org 排在前面且包含同名但不兼容的包(虽然目前概率较低,但未来可能发生),可能会导致还原错误。通过明确指定源,构建系统能够正确拉取 LoongArch 的特定依赖 9。

2.2.2 非官方自动化构建(Unofficial Builds)

除了 NuGet 源,龙芯社区还在 GitHub 上维护了一个名为 dotnet-unofficial-build 的仓库。该仓库定期发布预编译的.NET SDK 二进制包(tar.gz 格式)。

  • 版本策略:这些构建通常紧跟.NET 的上游发布节奏(如.NET 8.0.x, 9.0.x),但存在一定的时间滞后。
  • 使用方式:这是一种“旁路”安装方式。开发者下载压缩包后,将其解压到 /opt/dotnet 或 $HOME/dotnet,并手动设置 DOTNET_ROOT 和 PATH 环境变量。这是在 LoongArch 物理机上进行原生开发的最直接途径 14。

2.3 技术挑战与现状

尽管有了这些工具,LoongArch 的.NET 支持仍面临挑战:

  • JIT 优化滞后:虽然 LoongArch64 的 JIT 后端已能正常工作,但针对其特有的 LSX/LASX 向量指令集的优化尚未完全并在.NET 10 的早期预览版中普及,这导致其在密集计算任务下的性能可能不如经过高度优化的 x64 平台 。
  • 调试工具缺失:官方的诊断工具(如 dotnet-sos, dotnet-dump)往往依赖于特定的原生库构建。调研显示,LoongArch 平台的这些诊断工具包并未完全发布或集成到标准发布流程中,这使得生产环境下的故障排查变得异常困难 。

3. RISC-V:分布式协作与跨平台构建的艺术

与 LoongArch 由单一厂商主导不同,RISC-V 在.NET 生态中的崛起是典型的分布式开源协作成果。三星(Samsung)、阿里巴巴(Alibaba)以及个人开发者(如 Filip Navara)共同构成了这一生态的支柱。

3.1 社区驱动的开发模式

目前,RISC-V 的.NET 移植工作主要由三星的 Tizen 团队领衔,重点在于确保运行时(Runtime)和基类库(BCL)在 RISC-V 64位架构(RV64GC)上的功能完整性。

  • CI 基础设施:不同于微软 Azure 上庞大的 x64 服务器市场,RISC-V 的持续集成测试依赖于 VisionFive 2 等单板计算机(SBC)以及 QEMU 仿真器。这种硬件资源的限制是其未能进入 Tier 1 支持的主要瓶颈之一 。
  • 目标平台:主要的移植目标是通用的 Linux 环境(linux-riscv64),这使得其比 LoongArch 更容易融入现有的 Linux 发行版生态(如 Ubuntu, Debian, Fedora)。

3.2 Filip Navara 与 dotnet-riscv

在缺乏官方二进制包的情况下,Filip Navara 的 GitHub 仓库 dotnet-riscv 成为了 RISC-V.NET 开发者的事实标准。

  • 角色定位:该项目不仅仅是一个代码分支,更是一个构建农场。它利用 GitHub Actions 自动从上游 dotnet/runtime 同步代码,并执行交叉编译,生成可用的 SDK 和运行时包 16。
  • 本地源模式(Local Feed Pattern):由于微软不允许非官方构建上传至 NuGet.org,Navara 推荐的解决方案是“本地 NuGet 源”。开发者下载他发布的 NuGet 包(.nupkg 文件),将其放入本地文件夹,然后在 NuGet.config 中将该文件夹配置为包源。这种方法绕过了 NuGet.org 的限制,使得 dotnet restore 能够找到 runtime.linux-riscv64.Microsoft.NETCore.App 包 。

3.3 跨平台编译的必要性

RISC-V 设备(如 Lichee Pi, StarFive)的性能虽然在提升,但编译大型项目(特别是.NET 运行时本身)仍然极其缓慢。因此,交叉编译(Cross-Compilation) 成为了主流工作流。这引入了极高的复杂性,核心在于“Sysroot”的构建。

  • Sysroot 困境:要在 x64 主机上编译出能在 RISC-V 上运行的代码,编译器必须链接到目标系统的基础库(libc, libstdc++, openssl 等)。如果主机使用的 Sysroot(例如基于 Debian Sid)与目标设备(例如基于 Alpine Linux)不匹配,程序将在运行时崩溃(如 glibc 版本错误)17。

4. 技术实施指南:构建、部署与 Native AOT

本节将基于调研收集的技术片段,整合出一套针对.NET 10 环境下 LoongArch 和 RISC-V 的操作实施指南。

4.1 托管应用部署(Managed Deployment)

对于标准的.NET 应用程序(依赖 JIT),部署的核心在于获取正确的运行时包。

LoongArch 实施步骤

  1. 环境准备:在开发机上安装.NET SDK(x64版本即可,利用 SDK 的跨平台发布功能)。

  2. 配置源:在项目目录创建 NuGet.config,加入 nuget.loongnix.cn。

  3. 发布
    Bash
    dotnet publish -r linux-loongarch64 --self-contained

    该命令会触发 SDK 从龙芯源下载 LoongArch 特定的运行时包,并将其打包到输出目录。注意,由于 ABI 问题,需确保所选的 NuGet 包版本与目标系统的 Loongnix 版本兼容(旧世界 vs. 新世界)11。

RISC-V 实施步骤

  1. 获取包:从 filipnavara/dotnet-riscv 的 Releases 页面下载最新的 .nupkg 文件。

  2. 建立本地源
    Bash
    mkdir -p local-feed
    cp *.nupkg local-feed/

  3. 发布
    Bash
    dotnet publish -r linux-riscv64 --self-contained -s./local-feed -s https://api.nuget.org/v3/index.json

    通过 -s 参数显式指定本地源,确保 SDK 能找到 RISC-V 的运行时资产 7。

4.2 Native AOT(本机提前编译)深度解析

Native AOT 是嵌入式场景的“圣杯”,它能显著减少启动时间和内存占用,且无需在目标设备上安装.NET 运行时。然而,在 RISC-V 和 LoongArch 上启用 Native AOT 面临严峻的工具链挑战。

核心挑战:链接器与 ObjCopy

.NET SDK 默认假定使用宿主机的工具链。在交叉编译时,必须强制指定目标架构的工具。调研发现,常见的错误包括 NU1102(找不到包)和链接错误(invalid linker name)8。

关键 MSBuild 属性

为了成功进行 Native AOT 交叉编译,必须在 .csproj 或命令行中覆盖以下属性 19:

属性名称 作用 典型值 (RISC-V 示例) 典型值 (LoongArch 示例)
PublishAot 启用 AOT 编译 true true
CppCompilerAndLinker 指定 C++ 编译器 clang (需支持 riscv64) gcc (LoongArch 版)
ObjCopyName 指定 ObjCopy 工具 llvm-objcopy loongarch64-linux-gnu-objcopy
SysRoot 指定目标系统根文件系统路径 /crossrootfs/riscv64 /crossrootfs/loongarch64
LinkerFlavor 指定链接器类型 lld (推荐配合 Clang) bfd 或 ld
StripSymbols 是否剥离符号(减小体积) true true

构建 Sysroot 的官方脚本

微软在 dotnet/runtime 仓库中提供了一个鲜为人知但至关重要的脚本:eng/common/cross/build-rootfs.sh。这是构建高可用 Sysroot 的标准方法。

./build-rootfs.sh riscv64 noble --rootfsdir /tmp/riscv-sysroot
```
该脚本会利用 debootstrap 或 apt 下载目标架构的 .deb 包并解压,生成一个包含正确头文件和库文件的目录结构。这是 Native AOT 交叉编译成功的基石 18。

4.3 容器化构建策略

鉴于本地配置交叉编译工具链极其繁琐且容易出错(“Dependency Hell”),最稳健的策略是使用 Docker。微软维护了包含所需工具链的构建镜像(例如 mcr.microsoft.com/dotnet-buildtools/prereqs 系列),但针对 RISC-V 的镜像通常需要社区自行构建或从 VMR(虚拟单体仓库)流程中获取。Filip Navara 的 GitHub Actions 配置文件即展示了如何利用容器环境来标准化这一流程,确保每次构建的环境一致性 23。

5. 供应链安全与风险评估

在依赖“半官方”支持时,供应链安全是一个无法回避的问题。

5.1 非官方源的信任链断裂

使用 nuget.loongnix.cn 或个人 GitHub Release 中的二进制包意味着绕过了微软的代码签名和安全扫描机制。

  • 风险:如果 nuget.loongnix.cn 被劫持,攻击者可以注入恶意的运行时代码,而在构建过程中开发者几乎无法察觉。
  • 缓解措施:企业级用户应避免直接连接外部非官方源。建议搭建内部 NuGet 代理(如 Artifactory 或 Azure Artifacts),将需要的第三方包下载、扫描并上传至内部源,从而切断构建环境与不可信外部源的实时连接。

5.2 版本碎片化

社区构建往往无法做到与微软官方版本严格同步。这可能导致安全补丁(CVE 修复)在 LoongArch 或 RISC-V 平台上的发布滞后数周甚至数月。对于面向公网的服务器应用,这种滞后是不可接受的安全隐患。

6. 总结与展望

.NET 10 对 LoongArch 和 RISC-V 的支持现状,是技术理想与商业现实妥协的产物。

技术层面看,障碍已基本扫清。核心运行时已能在这两个架构上稳定运行,Native AOT 更是为其在嵌入式领域的应用打开了广阔大门。dotnet/runtime 仓库中活跃的提交记录证明了这一点。

产品层面看,“半官方”的状态仍将持续。微软严格的 Tier 分级制度决定了在缺乏大规模商业用户和稳定硬件基础设施之前,这两个架构只能作为 Tier 3 存在。这意味着开发者必须具备更高的技术能力——能够驾驭交叉编译、管理自定义 NuGet 源,甚至在必要时自行修补运行时代码。

战略建议

  1. 对于 LoongArch 用户:紧跟“新世界”ABI 的发展,尽量避免在.NET 10+ 的新项目中使用旧的 Loongnix 环境。利用 dotnet-unofficial-build 获取 SDK,但需对生产环境的依赖包进行本地化管理。
  2. 对于 RISC-V 用户:拥抱 Native AOT。鉴于 RISC-V 硬件通常性能有限,AOT 带来的启动速度和内存优势至关重要。务必掌握 build-rootfs.sh 脚本的使用,构建稳定可靠的交叉编译 Sysroot。
  3. 对于企业决策者:认识到目前的支持仍属于“实验性”或“社区级”。在关键任务系统中引入这些架构时,必须预留资源用于维护内部的构建管道,不能完全依赖外部社区的免费劳动成果。

未来,随着.NET 11 及后续版本的演进,我们有理由期待随着国产硬件的成熟和 RISC-V 服务器级芯片的普及,这些架构能最终晋升为 Tier 2,享受到与 x64/ARM64 同等的官方待遇。但在那之前,非官方源与社区解决方案仍将是通往新架构的唯一桥梁。

引用的链接

  1. What's new in .NET 10 - Microsoft Learn, 访问时间为 十二月 5, 2025, https://learn.microsoft.com/en-us/dotnet/core/whats-new/dotnet-10/overview
  2. RISC-V Support · Issue #1380 · microsoft/dotnet - GitHub, 访问时间为 十二月 5, 2025, https://github.com/microsoft/dotnet/issues/1380
  3. Port .NET Runtime to RISC-V - Home - RISE Project Confluence Wiki, 访问时间为 十二月 5, 2025, https://lf-rise.atlassian.net/wiki/spaces/HOME/pages/8587597/LR_04_001+Port+.NET+Runtime+to+RISC-V
  4. loongson-community/dotnet-runtime: .NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps. - GitHub, 访问时间为 十二月 5, 2025, https://github.com/loongson-community/dotnet-runtime
  5. NET and .NET Core official support policy, 访问时间为 十二月 5, 2025, https://dotnet.microsoft.com/en-us/platform/support/policy/dotnet-core
  6. .NET SDKs for Visual Studio | .NET - Microsoft .NET, 访问时间为 十二月 5, 2025, https://dotnet.microsoft.com/en-us/download/visual-studio-sdks
  7. RISC-V architecture support · Issue #49594 · dotnet/sdk - GitHub, 访问时间为 十二月 5, 2025, https://github.com/dotnet/sdk/issues/49594
  8. Illegal instruction on SAMA5D35 (ARMv7, VFPv3-D16) due to VMOV d16 usage · Issue #115641 · dotnet/runtime - GitHub, 访问时间为 十二月 5, 2025, https://github.com/dotnet/runtime/issues/115641
  9. 在龙芯loongnix上编译玩开源红警OpenRA - LA UOSC, 访问时间为 十二月 5, 2025, https://bbs.loongarch.org/d/227-loongnixopenra
  10. When will the community release the LoongArch64's SDK package with ARM32/64 and X86/64? · Issue #116293 · dotnet/runtime - GitHub, 访问时间为 十二月 5, 2025, https://github.com/dotnet/runtime/issues/116293
  11. How can Avalonia UI use .NET 9 to create nuget packages? #18557 - GitHub, 访问时间为 十二月 5, 2025, https://github.com/AvaloniaUI/Avalonia/discussions/18557
  12. The unofficial yet comprehensive FAQ for LoongArch (last updated 2022-11-23) | write(2), 访问时间为 十二月 5, 2025, https://blog.xen0n.name/en/posts/tinkering/loongarch-faq/
  13. 龙芯下如何进行.net core程序开发部署转载 - CSDN博客, 访问时间为 十二月 5, 2025, https://blog.csdn.net/woaimx_1314/article/details/131166131
  14. Releases · loongson-community/dotnet-unofficial-build - GitHub, 访问时间为 十二月 5, 2025, https://github.com/loongson-community/dotnet-unofficial-build/releases
  15. Unofficial automated builds of .NET SDK for LoongArch - GitHub, 访问时间为 十二月 5, 2025, https://github.com/loongson-community/dotnet-unofficial-build
  16. filipnavara/dotnet-riscv - GitHub, 访问时间为 十二月 5, 2025, https://github.com/filipnavara/dotnet-riscv
  17. Publish NativeAOT on Ubuntu doesn't work with -r linux-musl-x64 #92294 - GitHub, 访问时间为 十二月 5, 2025, https://github.com/dotnet/runtime/issues/92294
  18. runtime/eng/common/cross/build-rootfs.sh at main - GitHub, 访问时间为 十二月 5, 2025, https://github.com/dotnet/runtime/blob/master/eng/common/cross/build-rootfs.sh
  19. NativeAOT: change used linker for cross compiling : r/dotnet - Reddit, 访问时间为 十二月 5, 2025, https://www.reddit.com/r/dotnet/comments/1ei4pek/nativeaot_change_used_linker_for_cross_compiling/
  20. Cross-compilation - .NET - Microsoft Learn, 访问时间为 十二月 5, 2025, https://learn.microsoft.com/en-us/dotnet/core/deploying/native-aot/cross-compile
  21. This repo is a sample of an Android JNI library compilated using NativeAOT - GitHub, 访问时间为 十二月 5, 2025, https://github.com/josephmoresena/NativeAOT-AndroidHelloJniLib
  22. Port CoreCLR PAL to linux-riscv64 · Issue #75749 · dotnet/runtime - GitHub, 访问时间为 十二月 5, 2025, https://github.com/dotnet/runtime/issues/75749
  23. dkurt/dotnet_riscv: Build .NET SDK for RISC-V - GitHub, 访问时间为 十二月 5, 2025, https://github.com/dkurt/dotnet_riscv
  24. Create a build validation GitHub workflow - .NET | Microsoft Learn, 访问时间为 十二月 5, 2025, https://learn.microsoft.com/en-us/dotnet/devops/dotnet-build-github-action
posted @ 2025-12-05 07:42  张善友  阅读(152)  评论(1)    收藏  举报