GHCのHEADをビルドする(CentOS編)

Haskellの言語自体に興味があって、思いつきでGHCのHEADでもビルドしてみるかなと軽い気持ちで始めたら大変めんどくさいことになったので手順メモ。今では反省している。


以下、環境準備周りの失敗した箇所含めて説明してるので最短距離ではなく若干無駄が多い手順かもしんないですが、同じエラーでハマった人の何かの役に立てばと思い、徒然なるままにダラダラ書き留めておきます。(以下長文)


環境はMac上のDockerでCentOS 6.5で構築します。Dockerだとミスったらそのままコンテナ捨てられる安心感があるので、こういうお試し環境作るのに精神衛生上よいです。ディストリビューションは好みの問題なんだけど、仕事柄RHELを触ってることが多いのでLinuxならCentOSというかんじでやったものの、結果論だけ言うとHaskellに関してはたぶんDebian系の方が簡単そう。
GHCの公式サイト見るとDebianUbuntuだとapt-getでghchaskell-platformが入るようで開発チームはDebian使いが多いのでしょうかねぇ。


公式のGHC Developer Wikiにビルドガイドがあるので、これを参考に進めます。
Building – GHC

docker使う場合は以下で。その他自前で用意する人は適宜読み替えてください。

$ docker pull centos
$ docker run -i -t centos /bin/bash
# cat /etc/centos-release 
CentOS release 6.5 (Final)
  • ghcのビルドに必要な依存パッケージのインストール

以下に依存パッケージなどが記載されてます。CentOSは特に言及されていないので依存パッケージなどはRedhat系のFedoraを参考にして入れます。
Building/Preparation/Linux – GHC


で、まずここでghcをビルドするのにghcが必要という罠が。
CentOSリポジトリghcとhappyとalexがないのでghcとhappyとalexは後で入れるとして、まずはその他の依存パッケージを入れる。

# yum update -y
# yum install -y glibc-devel ncurses-devel gmp-devel autoconf automake libtool gcc make perl python git docbook-utils docbook-utils-pdf docbook-style-xsl strace patch
  • 踏み台となるghc7.6.3をインストールする

ghcビルドするのにghcが必要で、いきなりHEADに行けないので一旦踏み台に古い版のバイナリが必要なのだけど、ghcのビルドに必要なghcのバージョンは以下に記載あり。
Building/Preparation/Tools – GHC

ghcの7.6系をビルドするのに7.0.1以上が必要とあり、現在のHEADは7.9系で特に記載はないけど、まぁ最新の安定版バイナリ7.6.3を入れておけば間違いないだろう。

とりあえずCentOSリポジトリghcがないのでGHCの公式サイトのダウンロードリンクからビルド済みのバイナリを探したところ以下に
GHC 7.6.3 download — The Glasgow Haskell Compiler
「Generic amd64 Linux」というバイナリがあり。

Debian6.0でビルドしたよーって書いてあるのに一抹の不安を覚えつつとりあえずこれで問題ないっぽい。
インストール方法はこの辺を参考にした↓
CentOS6.3に Haskell環境 をインストール - Λ Takuya71 の日記 Λ 💻

# cd /usr/local/src
# wget http://www.haskell.org/ghc/dist/7.6.3/ghc-7.6.3-x86_64-unknown-linux.tar.bz2
# tar xvfj ghc-7.6.3-x86_64-unknown-linux.tar.bz2
# cd ghc-7.6.3
# ./configure --prefix=/usr/local/haskell/ghc/7.6.3
# make install

パスを通す

# vi ~/.bashrc
export PATH=/usr/local/haskell/ghc/7.6.3/bin:$PATH
# . ~/.bashrc
# ghc --version
The Glorious Glasgow Haskell Compilation System, version 7.6.3

これで踏み台となるGHCの7.6.3のインストールまでできた。

  • Haskell Platform 2013.2.0.0をインストールする

happyとalexはソースのtarballからビルドする場合は不要とあるのでghcだけ入れればよさそうにも読めるけど、gitにあるソースを直接ビルドするのに必要。cabalとかも何かと使うのでHaskell Platformを入れる。これもCentOS向けにはバイナリがなくこれも自前でビルドする。

# wget http://www.haskell.org/platform/download/2013.2.0.0/haskell-platform-2013.2.0.0.tar.gz
# tar xvfz haskell-platform-2013.2.0.0.tar.gz
# cd haskell-platform-2013.2.0.0
# ./configure --prefix=/usr/local/haskell/haskell-platform/2013.2.0.0
configure: error: The zlib C library is required

zlibがないと怒られるのでzlibを入れる

# yum install -y zlib-devel
# ./configure --prefix=/usr/local/haskell/haskell-platform/2013.2.0.0
configure: error: The OpenGL C library is required

こんどはOpenGLがないと怒られるのだけど、これはググったところ以下を入れればよいらしい。

# yum install -y freeglut-devel freeglut
# ./configure --prefix=/usr/local/haskell/haskell-platform/2013.2.0.0
# make && make install

無事にHaskell Platformがインストールできたのでパスに追加しておく。

# vi ~/.bashrc
export PATH=/usr/local/haskell/haskell-platform/2013.2.0.0/bin:/usr/local/haskell/ghc/7.6.3/bin:$PATH
# . ~/.bashrc
# ghc --version
The Glorious Glasgow Haskell Compilation System, version 7.6.3
# which ghc
/usr/local/haskell/ghc/7.6.3/bin/ghc
# which alex
/usr/local/haskell/haskell-platform/2013.2.0.0/bin/alex
# which happy
/usr/local/haskell/haskell-platform/2013.2.0.0/bin/happy

cabalが1.16系で微妙に古いので1.18系にアップデートしておく
(特に必須ではないかも?)

# cabal update
# cabal install cabal-install

これだけだと$HOMEの下に追加されて微妙にパスが通っていないので以下のパスを追加する

# vi ~/.bashrc
export PATH=$HOME/.cabal/bin:/usr/local/haskell/haskell-platform/2013.2.0.0/bin:/usr/local/haskell/ghc/7.6.3/bin:$PATH
# . ~/.bashrc
# cabal --version
cabal-install version 1.18.0.3
using version 1.18.1.3 of the Cabal library
# cabal update

happyとalexも一緒に入ってるんだけど、微妙にバージョンが古くて後の方でアップデートしてます。

  • GHCのHEADのソースの準備

やっと本題のghcのHEADのソースをgitからダウンロード。
準備長かったー。と思うけどまだここからもまだまだ依存関係でハマります。

# mkdir /usr/local/src/ghc-HEAD
# cd /usr/local/src/ghc-HEAD
# git clone git://git.haskell.org/ghc.git
# cd ghc
# ./sync-all get
== libffi-tarballs: running git config --local core.ignorecase true
error: unknown option `local'

git failed: 33024 at ./sync-all line 122.
== Checking for old haddock repo
== Checking for old binary repo
== Checking for old mtl repo
== Checking for old Cabal repo
== Checking for old time from tarball
============================
ATTENTION!

You have an old time package in your GHC tree!

Please remove it (e.g. "rm -r libraries/time"), and then run
"./sync-all get" to get the new repository.

timeパッケージが古いので消せと言われるので指示どおり消す。

# rm -r libraries/time
# ./sync-all get
== libffi-tarballs: running git config --local core.ignorecase true
error: unknown option `local'

git configに--localオプションとかないんやけどエラーは消えない。
どうやらCentOSに入ってるgitが古いようなのでgitのバージョンアップする。

# git --version
git version 1.7.1
# yum remove -y git
# cd /usr/local/src
# wget https://git-core.googlecode.com/files/git-1.9.0.tar.gz
# tar zxvf git-1.9.0.tar.gz
# cd git-1.9.0
# ./configure --prefix=/usr/local
# make && make install
/usr/bin/perl Makefile.PL PREFIX='/usr/local' INSTALL_BASE='' --localedir='/usr/local/share/locale'
Can't locate ExtUtils/MakeMaker.pm in @INC (@INC contains: /usr/local/lib64/perl5 /usr/local/share/perl5 /usr/lib64/perl5/vendor_perl /usr/share/perl5/vendor_perl /usr/lib64/perl5 /usr/share/perl5 .) at Makefile.PL line 3.
BEGIN failed--compilation aborted at Makefile.PL line 3.
make[1]: *** [perl.mak] Error 2
make: *** [perl/perl.mak] Error 2

今度はMakeMaker.pmがないとか言われる。

# yum install -y perl-ExtUtils-MakeMaker
# make clean
# ./configure --prefix=/usr/local
# make && make install
    * new locations or Tcl/Tk interpreter
    GEN git-gui
    INDEX lib/
    * tclsh failed; using unoptimized loading
    MSGFMT    po/bg.msg make[1]: *** [po/bg.msg] Error 127
make: *** [all] Error 2

今度はtclshがないと言われる。ググったところgettextを入れればよいらしい。

# yum install -y gettext
# make clean
# ./configure --prefix=/usr/local
# make && make install
# which git
/usr/local/bin/git
# git --version
bash: /usr/bin/git: No such file or directory
# /usr/local/bin/git --version
git version 1.9.0

無事にgitは入ったが、パスはあってそうだがなんかキャッシュに残ってるのかなんかおかしいのでexportし直しておく。

# export PATH=$HOME/.cabal/bin:/usr/local/haskell/haskell-platform/2013.2.0.0/bin:/usr/local/haskell/ghc/7.6.3/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
# which git
/usr/local/bin/git
# git --version
git version 1.9.0

うん。問題なさそう。


さて、気を取り直してghcのソースに戻る。

# cd /usr/local/src/ghc-HEAD
# ./sync-all get

sync-allできた。これでソースの準備はOK。

  • GHCのmakeの準備

ここからmakeの準備

# perl boot
# ./configure --prefix=/usr/local/haskell/ghc-HEAD
checking for happy... /usr/local/haskell/haskell-platform/2013.2.0.0/bin/happy
checking for version of happy... 1.18.10
configure: error: Happy version 1.19 or later is required to compile GHC.

どうやらhappyのバージョンが古いらしい。

# happy --version
Happy Version 1.18.10 Copyright (c) 1993-1996 Andy Gill, Simon Marlow (c) 1997-2005 Simon Marlow
# cabal install happy
# export PATH=$HOME/.cabal/bin:/usr/local/haskell/haskell-platform/2013.2.0.0/bin:/usr/local/haskell/ghc/7.6.3/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
# happy --version
Happy Version 1.19.3 Copyright (c) 1993-1996 Andy Gill, Simon Marlow (c) 1997-2005 Simon Marlow

happyのバージョンアップ完了。

# make clean
# perl boot
# ./configure --prefix=/usr/local/haskell/ghc-HEAD
checking for alex... /usr/local/haskell/haskell-platform/2013.2.0.0/bin/alex
checking for version of alex... 3.0.5
configure: error: Alex version 3.1.0 or later is required to compile GHC.

alexお前もか。。。

# alex --version
Alex version 3.0.5, (c) 2003 Chris Dornan and Simon Marlow
# cabal install alex
# export PATH=$HOME/.cabal/bin:/usr/local/haskell/haskell-platform/2013.2.0.0/bin:/usr/local/haskell/ghc/7.6.3/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
# alex --version
Alex version 3.1.3, (c) 2003 Chris Dornan and Simon Marlow

今度こそ

# make clean
# perl boot
# ./configure --prefix=/usr/local/haskell/ghc-HEAD

configure通った。

準備長かった。。。ではmakeしちゃいますか。

# make && make install

makeは超時間がかかるので気長に待ちましょう。
2時間makeし続けてエラーで落ちたorz

make[1]: *** [compiler/stage2/doc/html/ghc/ghc.haddock] Killed
make[1]: *** Deleting file `compiler/stage2/doc/html/ghc/ghc.haddock'
make: *** [all] Error 2

エラーメッセージをググったところOOM Killerで落ちたっぽい。

# dmesg | tail     
[  654]     0   654   192701        0      42     3650             0 docker
[  655]  1000   655      616        0       5       34             0 sh
[  754]     0   754      605        0       5       21             0 udhcpc
[  889]     0   889     2871        0      11      101             0 bash
[21000]     0 21000     2871        1      11       96             0 bash
[13368]     0 13368     1106        0       8       75             0 make
[ 7225]     0  7225    13599        1      31    12550             0 make
[ 6206]     0  6206   418170   162877     822   215978             0 haddock
Out of memory: Kill process 6206 (haddock) score 692 or sacrifice child
Killed process 6206 (haddock) total-vm:1672680kB, anon-rss:651508kB, file-rss:0kB

仮想マシンのメモリが足りないようなので1GB→2GBに増やす。
Dockerでメモリサイズを変更するには、裏で動いてるVirtualBoxの設定画面から変更すればよいっぽい。各自の環境で読み替えてください。


Docker話は別エントリにした方がよさそうなので以下に分けた↓
Dockerでメモリサイズの変更 - 城陽人の本棚


落ちたところからmakeし直し。makeするとき-jで並列度指定できるっぽいので、高速化のため2パラにしてみる。

# cd /usr/local/src/ghc-HEAD/ghc
# make -j 2
# make install

おっ、makeできたっぽい。

# /usr/local/haskell/ghc-HEAD/bin/ghc --version
The Glorious Glasgow Haskell Compilation System, version 7.9.20140318

GHCのHEADビルドできたー。

  • まとめ

CentOSだと依存関係つらい。。。HaskellerはDebian好きなのかな。