環境
- さくらのレンタルサーバー スタンダード
- FreeBSD 9.1-RELEASE-p15 (x86_64)
- もちろんroot権限なし
- ここでは、シェルはbashを使う(デフォルトはcshだった気がする)
- ここでは、プレフィックスは
$HOME/usr
にする($HOME/usr/bin
とか $HOME/usr/lib
にファイルが入るということ)
1. GHCをインストールする
FreeBSD向けにはHaskell Platformは出ていない。しかしGHCのバイナリは配布されているので、ここからとってくる。この記事を書いている2014年7月6日の時点では、最新バージョンは7.8.2である。
$ curl -O http://www.haskell.org/ghc/dist/7.8.2/ghc-7.8.2-x86_64-portbld-freebsd.tar.xz
$ tar xf ghc-7.8.2-x86_64-portbld-freebsd.tar.xz
$ cd ghc-7.8.2
$ ./configure --prefix=$HOME/usr
この後に gmake install
をするのだが、ghc-pkgやghcが使っている共有ライブラリにパスが通っていないので、 LD_LIBRARY_PATH を設定してやる。…なんかもっといい方法があると思う。
$ echo "export LD_LIBRARY_PATH=$HOME/usr/lib/ghc-7.8.2/terminfo-0.4.0.0:$HOME/usr/lib/ghc-7.8.2/bin-package-db-0.0.0.0:$HOME/usr/lib/ghc-7.8.2/binary-0.7.1.0:$HOME/usr/lib/ghc-7.8.2/Cabal-1.18.1.3:$HOME/usr/lib/ghc-7.8.2/process-1.2.0.0:$HOME/usr/lib/ghc-7.8.2/pretty-1.1.1.1:$HOME/usr/lib/ghc-7.8.2/directory-1.2.1.0:$HOME/usr/lib/ghc-7.8.2/unix-2.7.0.1:$HOME/usr/lib/ghc-7.8.2/time-1.4.2:$HOME/usr/lib/ghc-7.8.2/old-locale-1.0.0.6:$HOME/usr/lib/ghc-7.8.2/filepath-1.3.0.2:$HOME/usr/lib/ghc-7.8.2/containers-0.5.5.1:$HOME/usr/lib/ghc-7.8.2/bytestring-0.10.4.0:$HOME/usr/lib/ghc-7.8.2/deepseq-1.3.0.2:$HOME/usr/lib/ghc-7.8.2/deepseq-1.3.0.2:$HOME/usr/lib/ghc-7.8.2/array-0.5.0.0:$HOME/usr/lib/ghc-7.8.2/base-4.7.0.0:$HOME/usr/lib/ghc-7.8.2/integer-gmp-0.5.1.0:$HOME/usr/lib/ghc-7.8.2/ghc-prim-0.3.1.0:$HOME/usr/lib/ghc-7.8.2/rts-1.0:$HOME/usr/lib/ghc-7.8.2/haskeline-0.7.1.2:$HOME/usr/lib/ghc-7.8.2/ghc-7.8.2:$HOME/usr/lib/ghc-7.8.2/transformers-0.3.0.0:$HOME/usr/lib/ghc-7.8.2/template-haskell-2.9.0.0:$HOME/usr/lib/ghc-7.8.2/hpc-0.6.0.1:$HOME/usr/lib/ghc-7.8.2/hoopl-3.10.0.1" > ~/ghc-ld-path.sh
$ source ~/ghc-ld-path.sh
$ gmake install
2. Cabalをインストールする
このへんからCabalのソースコードを落としてくる。
$ curl -O http://www.haskell.org/cabal/release/cabal-install-1.20.0.2/cabal-install-1.20.0.2.tar.gz
$ tar xf cabal-install-1.20.0.2.tar.gz
$ cd cabal-install-1.20.0.2
$ emacs bootstrap.sh
本来なら cabal-install-*
の中にある bootstrap.sh
を実行すればいいのだが、sedの仕様の違いかなんだか知らないがリンカのコマンドがおかしなことになるので、テキストエディタで bootstrap.sh
を編集してリンカを ld
に決め打ちしてやる。
LINK=/usr/bin/ld
また、そのままだと tar が /dev/sr0
だかなんだかにアクセスして死ぬので、ググって出てきた情報を元に tar
の代わりに tar -f -
を使うようにする。これは bootstrap.sh
を書き換えなくても環境変数で上書きできる。
あと、Haddockでドキュメントを生成するのがうまくいかなさそうな気配を感じたので、 --no-doc
をつけてドキュメントを生成しないようにする。
$ TAR="tar -f -" ./bootstrap.sh --no-doc
これでインストールされるはず。
環境変数 PATH
がcabalとかを見に行くように、.bash_profile
をいじってやる。
$ emacs ~/.bash_profile
export PATH=$HOME/.cabal/bin:$HOME/usr/bin:$PATH
あとは普通にcabalが使える。
$ cabal update
$ cabal install cabal-install
3. せっかくなのでCabalでいろいろインストールしてみる
なんとなくIdrisを入れてみよう!と思った。依存関係がよくわからないが、コマンドとしては
$ cabal install --upgrade-dependencies --force-reinstalls idris
ぐらいでいけるはず。…だが現実はそううまくはいかない。
遭遇した問題としては大きく分けて二つあって、テンポラリディレクトリ /var/tmp
以下で作業してるのがなぜか実行権限が与えられなくてconfigureとかでこけるのと、ソースコード中に非US-ASCII文字が入っていてこけるの。
前者は、テンポラリディレクトリを自前で用意したディレクトリに変えれば良い。つまり ~/tmp
的なディレクトリを作ってやって、環境変数 TMPDIR=~/tmp
とすればよい。
後者は、 hGetContents
が失敗する的なエラーが出る。
hGetContents: invalid argument (invalid byte sequence)
file
コマンドで問題のファイルを見るとUS-ASCIIではなくUTF-8になっているのが分かる。そこで、問題のファイルから非US-ASCII文字を探し出してやって、それをUS-ASCII文字で置き換えてやればファイルがUS-ASCIIになって hGetContents
で問題なく読み込める…という方法でビルドしたが、冷静に考えてHaskellはUnicode対応してるはずだし hGetContents
でUTF-8を読み込めないのがおかしい。終わった後に気づいたが、おそらく文字エンコーディングが設定されていない的な問題な気がするので、 LANG=en_US.UTF-8
あたりを指定すれば良かった。
結局、
$ mkdir ~/tmp
$ TMPDIR=~/tmp LANG=en_US.UTF-8 cabal install --upgrade-dependencies --force-reinstalls idris
とすれば深いこと考えずにビルドできるはず。
以前やった時はどこかで挫折してしまっていたが、今回は気合いでなんとか頑張った。普段OS X と (Arch) Linux ばかり触っていて、 FreeBSD はよくわからないのだが、まあなんとかなった。
あとはレンタルサーバーの環境にnode.jsが入れば楽しそうなのだが…。
共用サーバーに処理系をいろいろ入れていろいろやりたいというのが間違いで、そういうのがしたいならVPSでも契約しろというのは正論だろう。