forked from NixOS/nixpkgs
-
Notifications
You must be signed in to change notification settings - Fork 0
Open
Description
一、主要现状
-
Haskell 包组与版本定义
- 默认的
haskellPackages版本定义在:
https://github.com/NixOS/nixpkgs/blob/79bb2afde2f184c85b2d3c40f140a7a48b78869c/pkgs/top-level/all-packages.nix#L6312-L6350 - 整体 Haskell 包组的定义在:
https://github.com/NixOS/nixpkgs/blob/master/pkgs/top-level/haskell-packages.nix - GHC 各版本的 Nixpkgs 定义位置:
https://github.com/NixOS/nixpkgs/tree/master/pkgs/development/compilers/ghc
- 默认的
-
交叉编译与工具链讨论
- RISC-V 上本地编译 GHC 的工具链讨论(与龙芯面临同样问题):
native riscv64-linux: error: cannot bootstrap GHC on this platform ('riscv64-linux' with libc 'defaultLibc') NixOS/nixpkgs#231537 - Nixpkgs Haskell 维护者
sterni在上游的相关讨论:
https://gitlab.haskell.org/ghc/ghc/-/issues/22006 - 上游官方 GHC 交叉编译文档:
https://gitlab.haskell.org/ghc/ghc/-/wikis/building/cross-compiling - 龙芯社区已有成员利用交叉编译构建过 GHC:
https://bbs.loongarch.org/d/150-ghc-loongarch
- RISC-V 上本地编译 GHC 的工具链讨论(与龙芯面临同样问题):
-
相关组件说明
- GHC:Haskell 的官方编译器
- native-bignum:替代 GMP 的 Haskell 库
- hadrian:替代 GNU Make 的构建系统
-
GHC 后端方案
- LLVM
- NCG(用 Haskell 编写,目前不支持 LoongArch64)
- Unregisterised(先编译成 C,再由 C 编译器处理;性能较低,用于 bootstrap)
-
LoongArch64 支持与版本现状
- GHC 从 9.6 起支持 LoongArch64,配合 LLVM 16 使用(需绕过 LLVM 15 限制并做适当改动,详见链接 1 中注释)。
- Nixpkgs 中默认 GHC 版本为 9.6.6,在
staging-next分支中已更新至 9.8.4:
haskellPackages: Stackage LTS 22 -> 23; ghc: 9.6.6 -> 9.8.4 NixOS/nixpkgs#371032 - 当前 Nixpkgs 的 Haskell 构建方式:导入官方 bindist tarball,再编译源码(即上游包中的
-binary流程)。
-
当前目标
在 x86_64-linux Hydra 上,构建面向 LoongArch64 的 bindist tarball,并由 Infrastructure Team 上传至tarball.nixos.org,以与其他受支持架构保持一致的本地构建流程。
二、交叉编译问题
-
GHC 的三阶段构建流程
- Configure 阶段 → Hadrian 构建:
- stage0、stage1、stage2 三个阶段一次性完成
- 输入的 Platform Triple 中,
build和host都是本地架构,target是目标架构(即输入 configure 的为 stage0 的 triple)
- Configure 阶段 → Hadrian 构建:
-
Nixpkgs 中的 Platform Triple 差异
pkgsCross.loongarch64-linux.haskell.compilers.ghc984三元组为(x86_64, loongarch64, loongarch64)- GHC 期望的顺序应为
(build=x86_64, host=x86_64, target=loongarch64) - 因此,需要退一步使用:
pkgsCross.loongarch64-linux.pkgsBuildHost.haskell.compilers.ghc984- 或者
pkgsCross.loongarch64-linux.haskell.packages.ghc984.ghc
(两者均未完全验证,但准备的 triple 满足 GHC 要求)
-
绕过libffi编译错误
libffi在 stage0 提前介入,导致编译失败:- 阶段使用的 libffi 头文件期望 gcc 定义
__loongarch__,但此时的 gcc 尚未打好宏 - 原因可能是
configureFlags中传入的 libffi 来自targetPlatform
- 阶段使用的 libffi 头文件期望 gcc 定义
- 当前对策:使用ghc自带
libffi:libffi = null
-
示例 Derivation 片段
libffi = null;且暂不开启 LLVM,启用 unregisterised:callPackage ../development/compilers/ghc/9.8.4.nix { bootPkgs = bb.packages.ghc963Binary; # 以 GHC 9.6 binary 为 bootPkgs inherit (buildPackages.python3Packages) sphinx; inherit (buildPackages.darwin) xattr autoSignDarwinBinariesHook; buildTargetLlvmPackages = pkgsBuildTarget.llvmPackages_15; llvmPackages = pkgs.llvmPackages_15; useLLVM = false; libffi = null; enableUnregisterised = true; }
这样在haskell-packages.nix修改ghc 9.8.4理论上就可以开始编译。
-
在
common-hadrian.nix中的调整- 将默认
finalStage从 stage1 改为 stage2 - 判断条件为:
stdenv.hostPlatform.canExecute stdenv.targetPlatform
- stage1 通常可完成,能生成在 x86_64 上运行、可编译 LoongArch64 二进制的 GHC
- 问题出在 stage2:后续重复构建时,无法正确“喂”入对应的工具链和库,导致 libs-install 和 stage2 阶段失败
- 将默认
-
问题归因与展望
- 上游(456)暗示,直接交叉编译 GHC 主体存在困难
- 龙芯社区已有成功案例,说明可能是构建流程或 Nixpkgs 假设不匹配所致
- 解决此处问题,有望同时破解 RISC-V 平台的本地编译难题
Metadata
Metadata
Assignees
Labels
No labels