5
Help us understand the problem. What are the problem?

posted at

updated at

Apple Silicon MacでのHaskell/GHCの現状・2021年末編

この記事は Haskell Advent Calendar 2021 の21日目の記事です。

昨年発表されたApple Silicon (Arm) Macは、今年も新製品と新チップ “M1 Pro/Max” が登場し、ますます勢いを増しています。Mac使いの皆さんはもう手にされましたか?

新しいアーキテクチャーにはハードウェアだけではなくソフトウェアの対応も重要です。この記事では、2021年末時点のApple Silicon MacへのHaskellエコシステムの対応状況をまとめます。

この記事では、なるべくRosetta 2を使わず、Armネイティブに動作する環境を構築することを目指します。

インストールにどれを使うか

UnixでHaskell環境を構築する場合、

  • パッケージマネージャーを使う
  • GHCupを使う
  • Stackを使う

の3つの選択肢があるかと思います。

Mac向けのパッケージマネージャーと言えばHomebrewやMacPortsです。HomebrewはArmネイティブなGHCのインストールに対応しています。一方、MacPortsでGHCをインストールするとIntel版のGHCがインストールされるようです(当該Portfile)。

GHCupはArmネイティブなGHC等のインストールに対応しています。現時点で最もおすすめな方法です。

後述しますが、原稿執筆時点でのstackの最新版 (2.7.3) はArmネイティブなGHC等のインストールに対応していません。なので、現時点では「環境構築」には使えないことになります。

GHC

Macに限らない最近のGHCの動向については以前記事を書きました:

ここではArmあるいはMac特有のGHCの事情について書いていきます。

GHC 8.10系

GHC 8.10系は8.10.5以降でApple Siliconに対応しています。

最新のGHC 8.10.7は2021年8月27日にリリースされました。現時点ではこれが一番安定した選択肢だと思います

実行ファイルの生成にはLLVMの opt コマンドと llc コマンドが必要になります。これについてはGHCupの項目で説明します。

8.10.7の既知の問題:

GHC 9.0系

GHC 9.0系は9.0.2以降でApple Siliconに対応しています。

最新のGHC 9.0.2は2021年12月25日にリリースされました。

実行ファイルの生成にはLLVMの opt コマンドと llc コマンドが必要になります。これについてはGHCupの項目で説明します。

9.0.2の既知の問題:

GHC 9.2系

GHC 9.2.1が2021年10月29日にリリースされました。

9.2系は最初からApple Siliconに対応しています。また、AArch64 NCGが実装されているためLLVMがなくても実行ファイルを生成できます(GHCのバックエンドについてはこの記事を参照)。

ただ、9.2.1のAArch64 NCGには深刻な問題があるので、プロダクションでは使わないのが吉です(テスト目的にはガンガン使ってやりましょう、というかalpha版やRCの時点でそうすべきだった)。プロダクションには9.2.2以降を待ちましょう。

9.2.1の既知の問題:

9.2.1の問題はHadrian(GHC自身をビルドするための、Makeに代わるビルドシステム)絡みやsized primitive(Word8# 等)絡みのものが多いようです。GHC 9.0も難産でしたが、9.2もなかなか大変です。

GHCup

公式ページの手順

curl --proto '=https' --tlsv1.2 -sSf https://get-ghcup.haskell.org | sh

に従うとArmネイティブなGHCupがインストールされます。そこでインストールされるツール類もArmネイティブなものになります。

もしもRosetta 2でx86_64なGHCupを導入したい場合は、

curl --proto '=https' --tlsv1.2 -sSf https://get-ghcup.haskell.org | arch -x86_64 sh

という風に実行すると良いでしょう(arch -x86_64 に注意)。

GHCupをすでにインストール済みで、自分がどちらを使っているか確認したい場合は、

file ~/.ghcup/bin/ghcup

を実行すると良いでしょう。Armネイティブな場合は Mach-O 64-bit executable arm64 という風に表示されるはずです。もしもIntel版のGHCupがインストール済みで、Arm版のGHCupを入れ直したい場合は ~/.ghcup 以下を全削除するか ghcup nuke コマンドを実行してから、改めてインストールしましょう。

LLVMのセットアップ

GHC 8.10系とGHC 9.0系でArmネイティブな実行ファイルを出力するにはLLVMの opt コマンドと llc コマンドが必要です。HomebrewやMacPortsでLLVM 9〜12を入れましょう。

opt コマンドと llc コマンドにPATHが通っていれば良いのですが、HomebrewやMacPortsのデフォルトではPATHが通っていなかったり、コマンド名にサフィックスがついたりしています。その場合、GHCの実行時に -pgmlo / -pgmlc コマンドでコマンド名を教えてあげるというのが一つの方法ですが、毎回それをするのは面倒なのでセットアップ時に環境変数で指定するのが良いでしょう。

Homebrewの場合は brew install llvm@12 して

# GHC 8.10.7を入れる場合
OPT=/opt/homebrew/opt/llvm@12/bin/opt LLC=/opt/homebrew/opt/llvm@12/bin/llc ghcup install ghc 8.10.7 --force

# GHC 9.0.2を入れる場合
OPT=/opt/homebrew/opt/llvm@12/bin/opt LLC=/opt/homebrew/opt/llvm@12/bin/llc ghcup install ghc 9.0.2 --force

という感じで、MacPortsの場合は sudo port install llvm-12 して

# GHC 8.10.7を入れる場合
OPT=/opt/local/bin/opt-mp-12 LLC=/opt/local/bin/llc-mp-12 ghcup install ghc 8.10.7 --force

# GHC 9.0.2を入れる場合
OPT=/opt/local/bin/opt-mp-12 LLC=/opt/local/bin/llc-mp-12 ghcup install ghc 9.0.2 --force

という感じで ghcup を実行します。--force オプションにより、すでに当該バージョンのGHCがインストール済みであっても新しい設定で再インストールを行うことができます。

再インストールするとデフォルトのGHCの設定がリセットされるので、適宜

ghcup set ghc 8.10.7 # または ghcup set ghc 9.0.2

を実行しましょう。

cabalコマンド (cabal-install)

GHCupで3.4.0.0以降のcabalコマンドを導入できます。

haskell-language-server

GHCupを使うことで1.4.0以降のhaskell-language-serverコマンドを導入できます。

なお、現時点ではVisual Studio CodeのHaskell拡張でHLSを自動インストールさせるとIntel版のHLSが入るようです。

関連Issue:

Stack

Stack 2.7.3の時点ではMac向けの公式バイナリーはIntel版しかありません。公式のインストール方法

curl -sSL https://get.haskellstack.org/ | sh

ではIntel版のstackが入ります。

一方、ArmネイティブなGHCupやHomebrewを使うとArm版のstackをインストールすることができます。

なお、Stack本体のアーキテクチャーと関係なく、 --arch x86_64, --arch aarch64 のオプションで使用するGHCのアーキテクチャーを選択することができます。

しかし、現行のstack 2.7.3ではArmネイティブなGHCのインストールができません。Arm版のGHCが使用される状態で stack setup もしくは適当なプロジェクトのビルドを試すと

I don't know how to install GHC for (OSX,AArch64), please install manually

というメッセージが出てきます。GHCup等の他の方法でGHCをインストール済みであれば --system-ghc オプションを使うことでプロジェクトのビルドができるようになります。

Stackの次期バージョンではArmネイティブなGHCのインストールに対応する見込みです:

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
5
Help us understand the problem. What are the problem?