(2017.1 新規作成.)
cabal-install コマンドではパッケージのバージョンの "組み合わせ" を固定することができない。バージョン地獄 (dependency hell) に陥ると大変になる。
cabal-install と併用し, プロジェクトごとのパッケージを固定する Stack の導入についてのメモ。
基本的なコンセプトは Ruby のための Bundler と同じ。プロジェクトが直接必要とするライブラリと, さらに依存するライブラリについて、システムグローバルにインストールされたパッケージで不足する場合, プロジェクト内にインストールしてしまう。
※実際には、ライブラリ本体は, ~/.stack/snapshots
以下にインストールされる。
Haskell は Ruby より状況が難しい。
1. パッケージの分け方が細かすぎる。2. 各パッケージのバージョン番号の振り方がよくなく、メジャーバージョンが上がってないのに非互換がしばしばある。単に依存するバージョンの最新版では、組み合わせとして壊れることがある。
Stack では, 依存関係として、テストされた組み合わせを維持する Stackage Server を利用する。GHC のバージョンごとに, Long Term Support (LTS) リリースを作っている。
システムにインストールされたGHCと基本ライブラリをできるだけ利用するようにする。
Fedora 24/25の場合:
# dnf copr enable petersen/stack # yum install stack
Fedora 30 以降では, petersen/stack リポジトリではなく, petersen/stack2 リポジトリを入れます。
# dnf copr enable petersen/stack2 # yum install stack
/usr/bin/stack コマンドが入る。(これは Fedora リポジトリのもの)
次のコマンドで stack を最新版に上げる。~/.local/bin
に最新版が入るので, あらかじめ ~/.bash_profile
で、/usr/bin
より先に参照されるようにすること。
$ stack upgrade
何もしないと, GHCすらプロジェクトごとにインストールしようとする。さすがにやりすぎ。
システムGHCを使う場合, ~/.stack/config.yaml
ファイルに次を追加する。
system-ghc: true
ドキュメントでは resolver
, compiler
も指定できるようだが, stack new で考慮されない。
stack new コマンドでプロジェクトを作る。
$ stack new hello-world new-template Downloading template "new-template
" to create project "hello-world
" inhello-world/
... The following parameters were needed by the template but not provided: author-email, author-name, category, copyright, github-username You can provide them in/home/horikawa/.stack/config.yaml
, like this: templates: params: author-email: value author-name: value category: value copyright: value github-username: value Or you can pass each one as parameters like this: stack new hello-world new-template -p "author-email:value" -p "author-name:value" -p "category:value" -p "copyright:value" -p "github-username:value" Looking for .cabal or package.yaml files to use to init the project. Using cabal packages: - hello-world/hello-world.cabal Selecting the best among 9 snapshots... * Matches lts-7.15 Selected resolver: lts-7.15 Initialising configuration using resolver: lts-7.15 Total number of user packages considered: 1 Writing configuration to file:hello-world/stack.yaml
All done.
(2020.5 更新) 自動的に生成されるファイルは次のとおり;
stack setup はやりすぎ。スキップする。
stack.yaml
を編集し、バージョン固定。手許では GHC 7.8.4 を使っている。対応する LTS を指定する。
(2020.5) Fedora 32 では GHC v8.6.5 が入る。対応するのは LTS 14.27.
resolver: lts-14.27
ビルド。
$ stack build
実行。実行ファイル名がダサい。
$ stack exec hello-world-exe someFunc
直接、依存するライブラリは hello-world.cabal
package.yaml
ファイルに追加する。hello-world.cabal
ファイルは, package.yaml
ファイルから自動的に生成される。
dependencies: - base >= 4.7 && < 5 library: source-dirs: src executables: hello-world-exe: main: Main.hs source-dirs: app ghc-options: - -threaded - -rtsopts - -with-rtsopts=-N dependencies: - hello-world
stack build でエラーになることがある。さらに依存しているライブラリで ltsにないもの (バージョン番号が違うものも) は, プロジェクトの stack.yaml
に追加。
extra-deps: - http-api-data-0.3.3