经过了数月的等待之后,新世界工具链与LLVM终于完善到了足以提供GHC支持的程度,目前已经完成了GHC编译器在新世界上的编译和测试,补丁已提交上游,但近期内合并的希望不大,因此在这里给出如何在LoongArch上完成GHC编译的详细指南,希望能够帮助到有需要的人。
GHC LoongArch 分支:Files · loongarch-patch · lrzlin / GHC · GitLab (haskell.org)
LLVM GHC 后端补丁:⚙ D137495 [LoongArch] Add GHC Calling Convention (llvm.org)
交叉工具链:loongarch64-clfs-6.3-cross-tools-gcc-full.tar.xz
使用以下命令将 GHC LoongArch 分支克隆至本地
git clone -b loongarch-patch --recurse-submodules https://gitlab.haskell.org/lrzlin/ghc.git
GHC Unregisterised 版本编译
首先需要交叉编译GHC Unregisterised 版本
根据 CLFS 文档中的指南配置好交叉工具链后 找到 ghc/m4/ghc_unregisteried.m4
并将其中的 loongarch64
删除
将 ghc/libffi-tarballs
和 ghc/libraries/ghc-bignum/gmp/gmp-tarballs
中 libffi
和 gmp
的压缩包替换为支持 LoongArch 的版本
之后回到GHC根目录 输入
./boot
./configure CC=$SYSDIR/cross-tools/bin/loongarch64-unknown-linux-gnu-gcc --target=loongarch64-unknown-linux-gnu LD=$SYSDIR/cross-tools/bin/loongarch64-unknown-linux-gnu-ld
配置完成后 输入
hadrian/build -j4
进行编译
如果在编译中碰到缺少 ncurses
库的报错,请自行编译并将其安装至交叉编译工具链中
编译完成后,输入
hadrian/build binary-dist
` 打包二进制分发包,至此 GHC Unregisterised 版本编译完成,可以将其拷贝至 LoongArch 架构机器安装使用。
GHC Registerised 编译
GHC Unregistered 即可满足大多数情况下的使用需要,但如果需要更高的运行效率、更完善的库支持和更完整的功能,则需要编译 GHC Registerised 版本,由于该版本需要 LLVM 后端的支持,而 LLVM 主分支尚未合并 GHC 后端补丁,因此需要自行下载补丁并编译 LLVM。
注:以下操作均在 LoongArch 机器上完成
首先需要安装之前编译完成的 GHC Unregisterised 版本
./configure
hadrian/build install
之后需要编译并安装 LLVM
克隆 LLVM 主线源码并打上 GHC 后端补丁之后 使用如下命令编译安装
cmake .. -G Ninja -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=Release \
-DBUILD_SHARED_LIBS:BOOL=OFF -DLLVM_ENABLE_LIBCXX:BOOL=OFF \
-DLLVM_LIBDIR_SUFFIX=64 \
-DCMAKE_C_FLAGS="-DNDEBUG" -DCMAKE_CXX_FLAGS="-DNDEBUG" \
-DLLVM_BUILD_RUNTIME:BOOL=ON -DLLVM_ENABLE_RTTI:BOOL=ON \
-DLLVM_ENABLE_ZLIB:BOOL=ON -DLLVM_ENABLE_FFI:BOOL=ON \
-DLLVM_ENABLE_TERMINFO:BOOL=OFF \
-DLLVM_BUILD_LLVM_DYLIB:BOOL=ON \
-DLLVM_LINK_LLVM_DYLIB:BOOL=ON -DLLVM_BUILD_EXTERNAL_COMPILER_RT:BOOL=ON \
-DLLVM_INSTALL_TOOLCHAIN_ONLY:BOOL=OFF \
-DLLVM_TARGET_ARCH=LoongArch -DLLVM_DEFAULT_TARGET_TRIPLE=loongarch64-unknown-linux-gnu
ninja && ninja install
由于 GHC 尚不支持最新的 LLVM 16 版本 因此需要对进行如下修改:
GHC LoongArch 分支代码:
[
(0, "-passes=module(default<O0>,function(mem2reg),globalopt,function(lower-expect))"),
(1, "-passes=module(default<O1>,globalopt)"),
(2, "-passes=module(default<O2>)")
]
- 将
ghc/compiler/GHC/Driver/Pipeline/Execute.hs
第 902 行中的 -tbaa
删除
在 ghc/utils/genapply/Main.hs
中添加 #undef UnregisterisedCompiler
-- We improperly include *HOST* macros for our target...
#include "../../rts/include/ghcconfig.h"
-- If the bootstrap compiler is unregisterised it defines
-- UnregisterisedCompiler, which implies NO_REGS. But we only want to
-- define NO_REGS if building an unregisterised compiler.
#undef UnregisterisedCompiler
-- ...so that this header defines the right stuff. It is the RTS's host, but
-- our target, as we are generating code that uses that RTS.
#include "../../rts/include/stg/MachRegsForHost.h"
由于 GHC 在最新的主线移除了对 make 工具的支持,因此我们还需要编译并安装 cabal-install
请自行参考 Cabal Bootstrap 指南进行编译,完成编译后,请注意需要执行一次 cabal update
之后即可进入 GHC 根目录并使用以下指令编译安装 GHC Registerised 版
./boot
./configure
hadrian/build -j4
hadrian/build install
TODO: TableNextToCode 支持