Haskell GHCをソースからビルドする手順

はじめに
=======

HaskellのコンパイラであるGHCについて、ソースコードからビルドするための手順を記載します。
（以前より、手順が少し簡単になっています。）

以下は、~~Ubuntu 16.04 LTS~~ Ubuntu 18.04 LTS環境にて、 ~~GHC8.0から8.2世代相当~~ GHC8.6をビルドする場合の手順例です。
（Docker環境下で作業すれば、現在のPC環境を汚さないで何度でも試すことができると思います。　また、Windows環境の場合にも、Docker環境を使用すると手軽に始められると思います。）

GHCのビルドに関する公式情報は以下等にあります。最新情報については、随時そちらを参照してください。

  * https://ghc.haskell.org/trac/ghc/wiki/Building
  * https://ghc.haskell.org/trac/ghc/wiki/Building/Preparation/Linux
  * https://ghc.haskell.org/trac/ghc/wiki/Building/GettingTheSources
  * https://ghc.haskell.org/trac/ghc/wiki/Building/QuickStart
  * https://ghc.haskell.org/trac/ghc/wiki/Building/Using
  * https://ghc.haskell.org/trac/ghc/wiki/Building/StandardTargets



ビルド手順
=========

### 1. ビルド用ツールのインストール

ツール等の導入トラブルを回避するために、念の為に、以下の環境変数を設定しておきます。

```
$ export LANG=C.UTF-8
$ export LC_ALL=C.UTF-8
$ export LANGUAGE=C.UTF-8
```

ビルドに必要なパッケージを、apt-getを使用してインストールします。
（管理者権限でない場合は、sudoを使用してコマンドを実行してください。）

```
$ apt-get update
$ apt-get install git autoconf automake libtool make gcc g++ libgmp-dev ncurses-dev libtinfo-dev python3 xz-utils
```



### 2. ブートストラップ用GHCとAlexとHappyのインストール

さらに、ビルドに使用するブートストラップ用のGHCと、Alex（lex相当）とHappy（yacc相当）を用意します。
ブートストラップ用のGHCのバージョンは、ビルド対象のGHCのバージョンから２世代以内のバージョンである必要があります。
（例えば、GHC8.6をビルドする場合には、ブートストラップ用のGHCとしては、GHC8.2またはGHC8.4が必要です。）

以下では、[Haskell Platform](https://www.haskell.org/platform/)をインストールして、ブートストラップ用のGHCとAlexとHappyを用意する方法を紹介します。
Haskell Platformは、グローバルの共通環境（/usr/loocal/bin および/usr/local/haskell以下）に、コマンドをインストールします。

なお、Haskell Platformをインストールすることを望まない場合は、Stackを用いてブートストラップ用のGHCとAlexとHappyをインストールすることもできます。Stackを用いる方法については、[YoshikuniJujoさんの記事](https://qiita.com/YoshikuniJujo/items/980775598e65fda36d33#stack%E3%81%A8ghc%E3%81%AE%E5%B0%8E%E5%85%A5)を参考にしてください。

それでは、以下のコマンドによりHaskell Platformをインストールします。
（./install-haskell-platform.shの実行には、root権限が必要です。このコマンド実行により、ブートストラップに使用するghcとalexとhappyコマンドが/usr/local/bin以下にインストールされます。）

```
$ mkdir tmp.haskell-platform
$ cd tmp.haskell-platform
$ wget https://haskell.org/platform/download/8.4.3/haskell-platform-8.4.3-unknown-posix--core-x86_64.tar.gz
$ tar xzf haskell-platform-8.4.3-unknown-posix--core-x86_64.tar.gz
$ ./install-haskell-platform.sh
```

さらに、GHCのビルド時に発生するPIC関連のエラーを避けるために、Haskell Platformの設定変更が必要です。
具体的には以下のコマンドにより、settingsファイルの該当行を"NO"から"YES"に変更します。

```
$ cd /usr/local/haskell/ghc-8.4.3-x86_64/lib/ghc-8.4.3
$ sed -ie 's/^, ("C compiler supports -no-pie","NO")/, ("C compiler supports -no-pie","YES")/' settings
```



### 3. GHCソースコードの入手

masterブランチを取得する場合は、以下のようにします。

```
$ git clone --recursive git://git.haskell.org/ghc.git
```

特定のブランチ、例えば安定版の8.6ブランチを取得する場合は、以下のようにします。

```
$ git clone -b ghc-8.6 --recursive git://git.haskell.org/ghc.git ghc-8.6
$ cd ghc-8.6
$ git checkout ghc-8.6
$ git submodule update --init
```
環境により、数分〜数十分程度かかります。



### 4. ビルド条件の設定

次の様にして、ビルド条件設定ファイル`mk/build.mk` を用意します。
サンプル（`build.mk.sample`）をコピーしてから、`BuildFlavour = quick`の行を作ります。`quick`は、ビルドを高速に行うための設定です。
（あらかじめコメントアウトされている、`#BuildFlavour = quick`の行の先頭の`#`を削除します。）

次の様に、sedなどで置換するか、

```
$ cd mk
$ sed -e 's/^#BuildFlavour = quick$/BuildFlavour = quick/' build.mk.sample > build.mk
```

viやemacs等を使って、該当の行（`#BuildFlavour = quick`）を直接編集します。

```
$ cd mk
$ cp build.mk.sample build.mk
$ vi build.mk
```

これにより、ビルド時には、`quick`設定用の`mk/flavours/quick.mk`が読み込まれます。
（ビルドの目的に応じて、`quick`以外の`devel2`等の設定にしても良いでしょう。）



### 5. bootとconfigureコマンドの実行

トップディレクトリで、boot と configure コマンドをそれぞれ実行します。

```
$ ./boot
$ ./configure
```



### 6. ビルド実行

トップディレクトリで、make コマンドを実行してビルドします。

```
$ make
```

論理CPUが複数あるPCの場合は、並列数を指定すると、ビルドを高速化できます。
以下は、論理CPUが８個の場合です。（CPU個数に+1したものを指定します。）

```
$ make -j 9
```

PC環境により10分〜２時間程度かかります。
実行時に、`make 2>&1 | tee xxx.log` のようにログを出力しておくと、あとからログを参照できて便利です。



### 7. 出来上がったghcを試す

ビルドされたghcは、`inplace/bin/ghc-stage2`として生成されています。
試してみましょう。

```
$ inplace/bin/ghc-stage2 --version
The Glorious Glasgow Haskell Compilation System, version XXX
```

```
$ inplace/bin/ghc-stage2 --interactive
Prelude> 1+2
3
```
出来ました。

ソースコードを色々と改変して、ビルドしてみましょう。
例えば、`ghc/driver/ghc-usage.txt`を修正して、`make`でビルドし直すと、`ghc --help` で修正が反映されたことを確認できます。



補足
=========

### ドキュメントもビルドする場合

ドキュメントをビルドする場合は、予め以下のパッケージもインストールしておきます。

```
$ apt-get install python-sphinx texlive-xetex texlive-fonts-recommended fonts-lmodern
```

その上で、`mk/build.mk`に以下の行を追加したうえで、`./configure` および `make`を実行します。 

user's guideを生成する場合には、`mk/build.mk`に以下の行を追加します。

```
BUILD_SPHINX_HTML  = YES
```

Haddockドキュメントを生成する場合には、`mk/build.mk`に以下の行を追加します。

```
HADDOCK_DOCS = YES
EXTRA_HADDOCK_OPTS += --hyperlinked-source
```


詳しくは、https://ghc.haskell.org/trac/ghc/wiki/Building/Docs を参照してください。



### Validationも行う場合

ビルドしたghcバイナリに対して、validation（テストプログラムによる検証）を行う場合は、次のパッケージをインストールしておきます。

```
$ apt-get install python3
$ apt-get install linux-tools-generic xutils-dev
```

その上で、validationコマンドを実行します。以下は論理CPUが８個ある場合です。
環境により、実行には数時間かかります。
詳しくは、https://ghc.haskell.org/trac/ghc/wiki/TestingPatches を参照してください。

```
$ THREADS=9 ./validate
```



### Docker用ファイル

以上のビルド手順を簡単に試せるように、Dockerfileを以下に置いておきました。
* https://github.com/takenobu-hs/ghc-build-docker

以下にも、DebianをベースとしたDockerfileが用意されています。こちらを使用すると、Phabricatorを使用するための arcanistの環境も準備できます。
* https://github.com/gregwebs/ghc-docker-dev

以上です。