• stack install と全く同じ動作をする cabal コマンドは cabal install all:exes です。

今回利用した cabalstack のバージョンは以下の通りです。

$ cabal -V
cabal-install version 3.0.0.0
compiled using version 3.0.0.0 of the Cabal library 

$ stack --version
Version 2.1.3, Git revision 636e3a759d51127df2b62f90772def126cdf6d1f (7735 commits) x86_64 hpack-0.31.2

この記事では stack install コマンドと cabal install コマンドの挙動の違いなどについて調査した結果等をまとめています。

プロジェクトの構成

例えば、プロジェクトが以下のような構成になっていて、executable (mainExe1, mainExe2, subExe1, subExe2) が定義されているとしましょう。

$ tree .
.
├── app
│   ├── Main1.hs
│   └── Main2.hs
├── cabal.project
├── stack.yaml
├── subs
│   ├── pkg1
│   │   ├── app
│   │   │   └── Main.hs
│   │   └── pkg1.cabal
│   └── pkg2
│       ├── app
│       │   └── Main.hs
│       └── pkg2.cabal
└── app.cabal

プロジェクトのコード

stack install と cabal install の違い

  stack install cabal install
インストール方法 コピー シンボリックリンク
インストール先ディレクトリの指定オプション local-bin-path --installdir

cabal install

cabal install に指定可能なコマンドをいくつか試してみて、実際に何がインストールされるか一覧にしました。

コマンド mainExe1 mainExe2 subExe1 subExe2 備考
cabal install O O
cabal install . O O
cabal install app O O
cabal install pkg1 O
cabal install pkg2 O
cabal install . pkg1 pkg2 O O O O
cabal install app pkg1 pkg2 O O O O
cabal install all O O O O *注意点
cabal install all:exes O O O O

  • cabal installstack install . の挙動など、いくつか stack と異なる場合があるので注意が必要です。
  • 注意点: 全てのパッケージに executable が含まれている場合に限り実行可能です。
    • cabal install allexecutable が含まれていないパッケージがある場合は以下のようなエラーになります。
cabal: Cannot build the executables in the package pkg2 because it does not
contain any executables. Check the .cabal file for the package and make sure
that it properly declares the components that you expect.
  • stack install に相当するコマンドは cabal install all:exes です。

stack install

同様に stack install も確認しました。

コマンド mainExe1 mainExe2 subExe1 subExe2 備考
stack install O O O O
stack install . O O O O
stack install app O O
stack install pkg1 O
stack install pkg2 O
stack install . pkg1 pkg2 *エラー1
stack install app pkg1 pkg2 O O O O
stack install all *エラー2
stack install all:exes *エラー2

エラー 1

$ stack install . pkg1 pkg2
The following errors occurred while parsing the build targets:
- The package pkg1 was specified in multiple, incompatible ways: . pkg1
- The package pkg2 was specified in multiple, incompatible ways: . pkg2

エラー 2

$ stack install all
Error: While constructing the build plan, the following exceptions were encountered:
Unknown package: all
Some different approaches to resolving this:
Plan construction failed.

その他の指定方法

cabal

コマンド mainExe1 mainExe2 備考
cabal install app:exe *エラー1
cabal install app:exes O O
cabal install app:exe:mainExe1 O O
cabal install app:exe:mainExe2 O O
cabal install app:mainExe1 O O
cabal install app:mainExe2 O O
cabal install exes O O
cabal install exe:mainExe1 O O
cabal install exe:mainExe2 O O
cabal install mainExe1 O O
cabal install mainExe2 O O

エラー1

$ cabal install app:exe
cabal: Unknown target 'app:exe'.
The package app has no component 'exe'.

stack

コマンド mainExe1 mainExe2 備考
stack install app:exe *エラー1
stack install app:exes *エラー1
stack install app:exe:mainExe1 O
stack install app:exe:mainExe2 O
stack install app:mainExe1 O
stack install app:mainExe2 O
stack install exes *エラー2
stack install exe:mainExe1 *エラー2
stack install exe:mainExe2 *エラー2
stack install mainExe1 *エラー3
stack install mainExe2 *エラー3

エラー1

$ stack install app:exe
Error parsing targets: Component exe does not exist in package app

エラー2

$ stack install exe:mainExe1
Error parsing targets: Unknown local package: exe

エラー3

$ stack install mainExe1
Error: While constructing the build plan, the following exceptions were encountered:
Unknown package: mainExe1
Some different approaches to resolving this:
Plan construction failed.

cabal install で良く使うオプション

オプション 内容
--installdir=<path> インストール先のパスを指定
--install-method=copy シンボリックリンクではなく、実体がコピーされる。
Docker にバイナリをコピーする際や Windows 環境などで利用することがあります。
--overwrite-policy=always すでに実行ファイルが存在する場合でも、常に上書きします。

--overwrite-policy=always を毎回指定するのが面倒な場合は

$ cabal user-config update -a overwrite-policy:always

というコマンドで ~/.cabal/config に設定できます。

3.2.0.0 で変更になる点など

Windows 環境において cabal install の際のデフォルトの挙動が変更されます。シンボリックリンクが作成できない場合は自動的にコピーになります。


ローカルのプロジェクト設定を無視するオプション -z, --ignore-project が追加されます。


$ cabal install 'https://hackage.haskell.org/package/cabal-fmt-0.1.2/cabal-fmt-0.1.2.tar.gz#sha256=aae556efbcaddfd65c6a1c1811b122b0d8c8d00624c8c2e36aabb5e9f9ea9840'