FEATURED · 精选文章

Julia 在 RISC-V (Linux) 上的编译与交叉编译指南

发布时间 / 2026/9/18 19:30:48
来源 / 创域科博编辑部
栏目 / 资讯中心
Julia 在 RISC-V (Linux) 上的编译与交叉编译指南 Julia 在 RISC-V (Linux) 上的编译与交叉编译指南【免费下载链接】juliaThe Julia Programming Language项目地址: https://gitcode.com/gh_mirrors/ju/julia本指南以 Julia 官方开发文档 doc/src/devdocs/build/riscv.md 为主体系统讲解如何在 64 位 RISC-VRV64Linux 设备上原生编译 Julia以及如何在 x86 等更快的主机上通过交叉编译产出 RISC-V 版本。读完本文你将掌握MARCH/MCPU/JULIA_CPU_TARGET等核心构建变量的正确设置方式并能独立搭建 riscv-gnu-toolchain QEMU 的交叉编译环境完成 Julia 在如 StarFive VisionFive2 等开发板上的完整构建。RISC-V 支持现状与前提Julia 目前对运行 Linux 的 64 位 RISC-VRV64处理器提供**实验性experimental**支持。这意味着构建与运行链路已经打通但某些功能仍可能存在缺陷或性能问题社区维护着一份针对 RISC-V 的已知问题列表对应 Julia 官方问题追踪器中的system:riscv标签在动手之前可以先查阅官方建议如果遇到困难在提交 issue 时务必附上cat /proc/cpuinfo的输出以便维护者确认你的 CPU 型号与 ISA 扩展情况。与 ARM 等架构不同RISC-V 是开放指令集架构ISA同一款芯片厂商可以自由裁剪指令扩展。因此面向 RISC-V 编译并不像 x86 那样有一个相对统一的指令基线构建前必须明确告诉编译器目标 ISA 字符串rv64gc等与可选的 CPU 型号sifive-u74等这是整个 RISC-V 构建流程的第一原则。原生编译通过Make.user指定架构与 CPUJulia 的构建系统通过根目录下的 Make.inc 定义了大量可配置变量并约定用户可以将自定义项写入Make.user该文件不会被 git 跟踪。在 RISC-V 上编译 Julia核心是设置以下两个变量变量作用是否必填取值来源MARCH指定 RISC-V ISA 字符串即指令集架构决定允许编译器使用哪些指令扩展必填设备文档或/proc/cpuinfo可用gcc -marchhelp查看编译器支持的 flagsMCPU针对具体 CPU 型号进一步优化生成代码可选gcc --target-help可查看支持的值列表不确定时建议留空为什么MARCH在 RISC-V 上是硬性要求从 Make.inc 的源码可以看到构建系统的默认策略在未显式设置任何相关变量时x86 等架构默认使用MARCHnative、MTUNEnative而 AArch64 默认使用MCPUnative。但对于 RISC-V 则直接触发构建错误else ifneq (,$(findstring riscv64,$(ARCH))) # RISC-V doesnt have a native option $(error Building for RISC-V requires a specific MARCH to be set))也就是说RISC-V 没有native这一选项因为编译器无法从运行中的处理器可靠探测出完整的 ISA 扩展集合ARCH检测到riscv64时若未提供MARCHmake会直接报错终止。这正是文档要求必须手动指定架构的底层原因。MARCH/MCPU如何传导到编译过程Make.inc 中展示了这两个变量对编译器的传导方式# Set MARCH-specific flags ifneq ($(MARCH),) CC -march$(MARCH) CXX -march$(MARCH) FC -march$(MARCH) # On RISC-V, dont forward the MARCH ISA string to JULIA_CPU_TARGET, # as its always incompatible with LLVMs CPU target name parser. ifeq (,$(findstring riscv64,$(ARCH))) JULIA_CPU_TARGET ? $(MARCH) endif endif # Set MCPU-specific flags ifneq ($(MCPU),) CC -mcpu$(MCPU) CXX -mcpu$(MCPU) FC -mcpu$(MCPU) JULIA_CPU_TARGET ? $(MCPU) endif可以看到MARCH和MCPU会被拼接到 C、C 与 Fortran 编译器CC/CXX/FC的调用参数上从而影响所有 C/Fortran 依赖如 OpenBLAS、libuv 等以及 Julia 运行时本身的编译。同时构建系统默认会把它们同步到 JIT 侧的系统镜像目标JULIA_CPU_TARGET——唯一的例外是 RISC-V 上的MARCH由于 RISC-V 的 ISA 字符串如rv64gc与 LLVM 的 CPU target 名称解析器不兼容代码中特意跳过了这一步见 Make.inc。这正是文档中可移植构建示例需要手动补充JULIA_CPU_TARGET的原因。具体设备示例StarFive VisionFive2文档给出的示例是 StarFive VisionFive2 开发板它搭载的 JH7110 处理器基于 SiFive U74 核心设计。对这类已知 CPU可以同时设置 ISA 字符串与 CPU 型号以获得针对性优化# Make.user MARCH : rv64gc_zba_zbb MCPU : sifive-u74其中rv64gc_zba_zbbrv64gc是 RV64 的通用组合i整数、m乘除、a原子、f单精度浮点、d双精度浮点、c压缩指令外加zicsr/zifencei_zba_zbb追加了位操作bit-manipulation扩展U74 核心支持这些扩展sifive-u74告诉编译器按 SiFive U74 的微架构做指令调度与优化。如何确认你的设备应当使用哪些扩展两种途径查阅芯片/开发板官方文档中的 ISA 描述直接查看运行中系统的/proc/cpuinfo其中会列出内核识别的 ISA 扩展。可移植构建不锁定特定 CPU如果你希望产出的 Julia 二进制能够在更广泛的 RISC-V 设备上运行而不是只为某一款 CPU 特化可以采用可移植配置# Make.user MARCH : rv64gc # also set JULIA_CPU_TARGET to the expanded form of rv64gc # (it normally copies the value of MCPU, which we dont set) JULIA_CPU_TARGET : generic-rv64,i,m,a,f,d,zicsr,zifencei,c这里的关键点是MARCH : rv64gc将 ISA 基线收敛到最通用的组合任何支持 RV64GC 的芯片都能运行由于 RISC-V 上MARCH不会自动转发为JULIA_CPU_TARGET且这里也没有设置MCPU按文档建议留空因此必须手动把rv64gc的展开形式写入JULIA_CPU_TARGET告诉 LLVM JIT 生成什么样的指令。generic-rv64,i,m,a,f,d,zicsr,zifencei,c是rv64gc逐项展开后的 LLVM 特性列表其中generic-rv64是 LLVM 侧的通用 64 位 RISC-V 目标逗号后依次列出各指令扩展。补充说明JULIA_CPU_TARGET的默认值在 Make.inc 中定义为native因此在 RISC-V 交叉/特化构建场景下显式设置它是保证系统镜像sysimage与运行时 JIT 目标一致的必要手段。关于该变量的更通用讨论可参见构建分发文档 doc/src/devdocs/build/distributing.md 与 Linux 构建文档 doc/src/devdocs/build/linux.md 中的 Architecture Customization 一节ARM 平台的类似做法可参考 doc/src/devdocs/build/arm.md。交叉编译在高速主机上为 RISC-V 构建RISC-V 开发板尤其是初代单板计算机的计算能力通常有限在板子上原生编译 Julia 可能耗时极长。官方支持在一台更快的机器上进行交叉编译整体分三步走。第一步准备 RISC-V 交叉编译工具链需要一套同时支持C、C 和 Fortran的 RISC-V 交叉工具链Julia 的构建依赖大量 C/Fortran 数值库。官方推荐的方式是获取 riscv-gnu-toolchain 源码仓库并自行构建sudo mkdir /opt/riscv sudo chown $USER /opt/riscv ./configure --prefix/opt/riscv --with-languagesc,c,fortran make linux -j$(nproc)要点安装到/opt/riscv后续所有路径均以此为基准--with-languagesc,c,fortran必不可少缺少 Fortran 会导致 OpenBLAS 等依赖无法交叉编译make linux目标构建的是 Linux 用户态工具链而非裸机newlib版本这是运行 Linux 的 RISC-V 开发板所需要的。第二步配置 QEMU 用户态模拟与 binfmt交叉编译出的 RISC-V 二进制无法直接在主机上运行而 Julia 的构建过程需要在主机上执行部分目标架构的程序例如构建系统会用目标二进制做探测、生成代码等。解决方案是安装 QEMU 用户态模拟器并启用binfmt支持使主机内核能够自动把 RISC-V 可执行文件交给 QEMU 执行具体安装步骤随发行版而异。以 Arch Linux 为例需要安装qemu-user-static与qemu-user-static-binfmt两个软件包binfmt注册表会让内核按 ELF 头自动识别 RISC-V 二进制并调用对应的模拟器QEMU 执行 RISC-V 程序时需要能够找到 RISC-V 的系统根目录sysroot这是通过QEMU_LD_PREFIX环境变量指定的指向工具链安装路径下的根文件系统/opt/riscv/sysroot。第三步配置 Julia 的交叉构建变量在 Make.inc 中交叉编译通过XC_HOST变量启用设置后构建系统会自动给所有工具链命令加上$(XC_HOST)-前缀即CROSS_COMPILE机制并用它推导目标三元组triplet。在之前的Make.user基础上追加# Make.user追加内容 XC_HOSTriscv64-unknown-linux-gnu OSLinux export QEMU_LD_PREFIX/opt/riscv/sysrootXC_HOSTriscv64-unknown-linux-gnu指定交叉工具链前缀make会调用riscv64-unknown-linux-gnu-gcc、riscv64-unknown-linux-gnu-g、riscv64-unknown-linux-gnu-gfortran等OSLinux由于是从非 Linux 或未自动识别环境交叉编译需要显式声明目标操作系统为 LinuxXC_HOST非空时 Makefile 要求显式设置OS参见 Make.inc 的相关错误处理逻辑export QEMU_LD_PREFIX让 QEMU 找到 RISC-V 系统库。启动构建时需要确保PATH中包含交叉工具链例如PATH/opt/riscv/bin:$PATH make -j$(nproc)补充系统库以 zlib 为例官方文档特别提醒我们使用的 RISC-V sysroot 往往非常精简barrenJulia 构建系统期望的一些系统级库在 sysroot 中可能不存在。文档给出的例子是libz——当前构建依赖于系统提供的 zlib因此需要把 Julia 构建出的 zlib 拷贝进 sysrootmake -C deps install-zlib cp -v usr/lib/libz.* /opt/riscv/sysroot/usr/lib cp -v usr/include/z*.h /opt/riscv/sysroot/usr/include这里make -C deps install-zlib调用的是 Julia 依赖子系统的 zlib 构建目标定义于 deps/zlib.mk其中install-zlib由staged-install宏生成另有get-zlib、extract-zlib、configure-zlib、compile-zlib、clean-zlib等配套目标。在交叉编译阶段Julia 自身会先把 zlib 交叉编译出来并安装到本地的usr/目录随后再将其产物复制到/opt/riscv/sysroot下供后续链接阶段使用。如果你的交叉构建还遇到其他找不到系统库的问题可以沿用同一思路先用make -C deps install-库名构建对应依赖再把库与头文件补齐到 sysroot 中。这是 RISC-V 精简 sysroot 环境下常见的解决路径。构建流程原理小结把整条链路串起来看Julia 在 RISC-V 上的构建涉及三层目标决策ISA 与微架构层MARCHISA 字符串与MCPUCPU 型号决定 C/C/Fortran 侧所有代码的生成质量与兼容性其中MARCH在 RISC-V 上是强制的JIT 与系统镜像层JULIA_CPU_TARGET决定 LLVM JIT 为 Julia 代码生成什么指令RISC-V 上需要手动给出rv64gc的展开形式交叉执行层XC_HOST驱动工具链前缀切换QEMU_LD_PREFIXbinfmt解决目标二进制在主机上的运行问题OSLinux保证目标平台判定正确。此外构建系统对 riscv64 还有一些自动化的默认处理例如自动设置OPENBLAS_DYNAMIC_ARCH1与BINARY64见 Make.inc并在生成二进制发行包名时使用riscv64作为架构标识Make.inc这些无需用户干预。常见问题与排障建议make报错 Building for RISC-V requires a specific MARCH to be set说明MARCH未设置。在Make.user中补上MARCH : rv64gc或更具体的 ISA 字符串后重试。不知道自己的 CPU 支持哪些扩展执行cat /proc/cpuinfo查看内核识别的 ISA用gcc -marchhelp查看编译器支持的 RISC-V flag 列表用gcc --target-help查看可用的-mcpu取值。交叉编译时目标二进制无法执行确认已安装 QEMU 用户态模拟与binfmt支持并已export QEMU_LD_PREFIX/opt/riscv/sysroot。链接时找不到系统库按上文 zlib 的示例通过make -C deps install-库名构建依赖后补齐 sysroot。提交问题报告遇到编译或运行问题时在官方问题追踪器的system:riscv标签下查找是否已有相同问题新建 issue 时请附上cat /proc/cpuinfo输出以及你使用的Make.user内容。【免费下载链接】juliaThe Julia Programming Language项目地址: https://gitcode.com/gh_mirrors/ju/julia创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED — 相关阅读

相关资讯

LATEST — 最新资讯

最新发布

TODAY — 本日精选

新闻

WEEKLY — 本周精选

新闻

MONTHLY — 本月精选

新闻