トップ «前の日記(2013-05-03 [Friday]) 最新 編集

Catra's Diary

2005|01|02|03|05|06|07|10|
2006|05|07|09|10|11|
2007|06|07|08|
2008|01|02|07|09|11|12|
2009|06|
2010|03|07|
2011|01|
2013|05|

2013-05-05 [Sunday]

_ hsenv について

Haskell 環境をローカル(プロジェクト毎)に生成するコマンド hsenv <URL:http://hackage.haskell.org/package/hsenv>

rbenv & ruby-build を調べたのはついでで、実際はこちらが先。 hsenv は python の virtualenv を参考に作ったとあり、似たようなものに rvm があるなあ、 と見てみると最近は rbenv の方が好まれているらしい。 ということで調べてみたら、結構おもしろかったのでまとめてみた。

hsenv は、最初は rbenv のように ghc の各バージョンや、ghc 以外の Haskell を切り替えて使えるようなツールかと思っていたが、 どちらかというと cabal-dev に近く、 hsenv コマンドを実行したカレントディレクトリに .hsenv/ を生成しその下に必要なパッケージをインストールしていく形。 cabal-dev install ではなく cabal install を使えるように .hsenv/bin/ 以下に ghc, ghci, ghc-mod, runghc, cabal、そしてそれらを有効にする activate を置く。 source activate をしたシェルを使っている間(exit するまで)、 または deactivate_hsenv を実行するまでは、cabal install したパッケージは ~/.cabal/ 以下ではなく .hsenv/cabal/ 以下にインストールされ、system(global) や user へ影響しないようにする。 (※Haskell は The Haskell 2010 report をサポートする実装が ghc しかなく、ビルドも面倒なため、 Python や Ruby と比べ他の実装と切り替えて使用するということが少ないんだろうと思う。)

以下は hsenv の説明から。

Basic usage.

まず、Haskell 環境をサンドボックス化したいディレクトリを選ぶ(例えば cabal 化したプロジェクトなど)。 ディレクトリに移動する。

$ cd ~/projects/foo

次に、隔離した Haskell 環境を生成する(環境ごとに1回だけ実行する)。

$ hsenv

あとは、このHaskell 環境を使いたいときに毎回、以下を実行して環境を有効化する。

$ cd ~/projects/foo
$ source .hsenv/bin/activate

これで、生成した Haskell 環境に PATH が通り、cabal のインストール先も切り替えるなどする。 cabal でインストールしたパッケージは system(global) や user へ影響しないよう、 ~/projects/foo/.hsenv/cabal 以下にインストールされる。 また、基本的なパッケージのみ(ghc と Cabal、それらが依存するパッケージ)を Haskell 環境にコピーするため、 これらのパッケージ以外の影響も受けない。

Haskell 環境を使い終わったら、以下のコマンドを実行するか、現在のシェルを終了する。

$ deactivate_hsenv

Advanced usage.

異なる GHC のバージョンを使用することができる。 開発中のコードが違うバージョン(nightly buildも含め)でのテストに使える。

まず、バイナリ配布の GHC を取得して、 以下を実行して新しい Haskell 環境を生成する。

$ hsenv --ghc=/path/to/ghc_something.tar.gz2

あとは、Basic usage 同様にして [de]activation する。

雑記

hsenv を調べたのは、penny をインストールしようとしたら、penny-lib が依存している bytestring (0.10.*) と、 既にインストールしている bytestring 0.9.2.1 がコンフリクトしており、--reinstall --force-reinstalls を指定して cabal install を実行する必要があったため。 少しスマートな方法は無いか調べてみた。

調べてみると cabal-dev と同様な仕組みであることが分かった。 実運用上は cabal-dev を使っていればよく、cabal-dev shell のようにして ./cabal-dev/ 以下にインストールしたパッケージやコマンドを実行できればより便利と思われる。 (cabalize する予定のパッケージでも、いろいろ依存関係がある大規模S/Wなら開発(設計)中は hsenv で作って、 必要なパッケージが固まってきたら *.cabal を書いて cabal-dev に移行するのがスマートかもしれない。)

結局 penny-bin パッケージをインストールする場合は、hsenv で作成した Haskell 環境に bytestring が含まれており、 それらに依存している regex-compat, regex-posix, regex-base パッケージをインストールしなおす必要があると cabal に怒られる。そのため、

$ cabal-dev install --force-reinstalls penny-bin

で、必要な cabal パッケージを含めて cabal-dev 以下に配置するしかない。

(隔離環境で hsenv や cabal-dev で新しくパッケージをインストールするのに、 既に system(global) や user にインストールしている(ビルド済みの)パッケージを元に依存関係を生成してエラーを出すのは、 cabal のバグの気がする。)


トップ «前の日記(2013-05-03 [Friday]) 最新 編集