定食屋おろポン

おろしポン酢と青ネギはかけ放題です

cabal hellから抜け出したくてあがいた話

「cabalでパッケージをインストールする際、依存の解消がイマイチでハマりがち」という噂が流れているのは知っていた。

自分が遭遇するまでは「ふーん」と右から左であった。

仔細は省略するが、このたび見事にハマり、cabal hellを目の当たりにした。

熟練Haskellerであれば「こんなのは地獄のうちに入らぬわ!」などと高笑いするかもしれないが、初心者にとっては「面白そうなパッケージ試してみようと思ったらエラーが...解消しようと思ったらまたエラーが...エラー...エラー...」という終わりの見えない状況は十分に地獄と呼んでよいのではないか。

環境: Mac OSX 10.9.2

Haskell Platformのアンインストール

ここらへんを参考に、ghcもcabalもない、古き良き時代に戻る。

身も心もすっきりする。

GHCのインストール

参考: 2013年8月現在のHaskell開発環境 - maoeのブログ

Haskell Platformを使わない利点は、バージョンが固定されるパッケージが少ないので依存関係でこけることが減ること。

とのことなので、Haskell Platformを使わずインストールすることにする。

GHC: Download version 7.6.3 からGHC7.6.3のバイナリを落とし、インストール。

ちなみにニュービーな僕は「GHCのバージョンを一発で切り替えたい」などと欲をかかず、大人しく/usr/local/ghc/ghc-7.6.3/binにパスを通した。 それ以外は、概ね上記サイトの通りである。

Cabalのインストール

参考: An Introduction to Cabal sandboxes

「とりあえずcabal sandbox使っとけ」ということなので、githubのCabalをインストールする。

If you have used Haskell for some time, you’ve probably heard the expression “Cabal hell”. It refers to the fact that installing a new package with cabal install can break existing packages on your system.

すなわち。

もしもHaskellを何度か使ったことさえあれば、"Cabal hell"なる言葉を聞き及んだことがあろう。これは、新しいパッケージをインストールするために黒い画面に打ち込んだcabal installが既存パッケージをぶっ壊す恐ろしい現象を指す言葉である。

さて。

GHCしか入ってないならこうやれよ」と仰せなので以下のコードを逐一実行してみる。

$ git clone git://github.com/haskell/cabal.git /path/to/cabal
$ cd /path/to/cabal/Cabal
$ runhaskell Setup.hs configure
$ runhaskell Setup.hs build
$ runhaskell Setup.hs install
$ cd ../cabal-install
$ sh bootstrap.sh

と、sh bootstrap.shでこんなエラーが出て失敗する。

Data/Text.hs:1213:42:
     warning: missing terminating ' character [-Winvalid-pp-token]
-- In (unlikely) bad cases, this function's time complexity degrades

ここらへん を覗くと、gcc4.7を使うと解決するようだ。gcc48もgcc49もあるけど、gcc47なら出来るっていうんだからそうしてやろうじゃないか。 仕方ないので、4.7を入れてやる

時間がかかるので、しばらく正座して待つ。

gccコマンドがgcc47を参照するよう変更した後、再びsh bootstrap.shを行う。

The 'cabal' program has been installed in /Users/shogo/.cabal/bin/

めでたい。

使ってみる

「WAFが使えればもう大丈夫でしょう」という安易な発想から、 Making A Website With Haskell - adit.io を参考に Scottyを入れてみる。

さっそくcabal installで失敗する。世知辛い。

Resolving dependencies...
cabal: Could not resolve dependencies:
trying: todo-0.0.1 (user goal)
next goal: wai-extra (dependency of todo-0.0.1)
Dependency tree exhaustively searched.
Motoko% cabal update
Downloading the latest package list from hackage.haskell.org
Motoko% cabal install
Resolving dependencies...
cabal: Could not resolve dependencies:
trying: todo-0.0.1 (user goal)
trying: wai-extra-2.1.1.1 (dependency of todo-0.0.1)
trying: conduit-1.1.0 (dependency of wai-extra-2.1.1.1)
next goal: monad-logger (dependency of todo-0.0.1)
rejecting: monad-logger-0.3.4.1, 0.3.4.0, 0.3.3.2, 0.3.3.1, 0.3.3.0, 0.3.2.0,
0.3.1.1, 0.3.1, 0.3.0.1 (conflict: todo => monad-logger==0.3.0)
rejecting: monad-logger-0.3.0 (conflict: conduit==1.1.0, monad-logger =>
conduit>=1.0 && <1.1)
rejecting: monad-logger-0.2.4, 0.2.3.2, 0.2.3.1, 0.2.3, 0.2.2, 0.2.1, 0.2.0.1,
0.2.0 (conflict: todo => monad-logger==0.3.0)
Backjump limit reached (change with --max-backjumps).

Backjumpがlimitに達して失敗したようだ。依存関係の解消ができなくて失敗してたら心を折って、ついでにHHKBも2つにぶち折っているところだった。

--max-backjumpsだが、cabal install --helpによると、「とりあえず-1にしとけ」と読み取れる。

    --max-backjumps=NUM             Maximum number of backjumps allowed while
                                    solving (default: 200). Use a negative
                                    number to enable unlimited backtracking.
                                    Use 0 to disable backtracking completely.

cabal install --max-backjumps=-1でリトライする。。も失敗。

.
.
.
Installed persistent-sqlite-1.3.0.5
cabal: Error: some packages failed to install:
persistent-postgresql-1.3.0.5 depends on postgresql-libpq-0.9.0.0 which failed
to install.
postgresql-libpq-0.9.0.0 failed during the configure step. The exception was:
ExitFailure 1
postgresql-simple-0.4.2.1 depends on postgresql-libpq-0.9.0.0 which failed to
install.
todo-0.0.1 depends on postgresql-libpq-0.9.0.0 which failed to install.

めげずに個別にインストールをしてみる。 cabal install postgresql-libpq-0.9.0.0を行うと、setup: The program 'pg_config' is required but it could not be found.とのことなので、pg_configを入れる。

Homebrewからインストール。すぐ終わる。

% brew install postgresql
% which pg_config
/usr/local/bin/pg_config

これによって、cabal install postgresql-libpq-0.9.0.0が成功するため、もう一度cabal install --max-backjumps=-1を行ってみる。

...成功!

.
.
.
Configuring todo-0.0.1...
Building todo-0.0.1...
Installed todo-0.0.1

世界にこんにちはできたので、寝る。

f:id:oropon:20140408030602p:plain