Cabal の使い方

Cabal とは

Cabal とは Haskell のパッケージマネージャーで、 Java の Gradle や、JavaScript の npm に相当するプログラムです。 パッケージマネージャーとは、ソフトウェアの依存関係を管理するためのツールで、 必要なライブラリーを簡単にインストールし、管理することができます。 また、パッケージのビルドや実行も行います。

インストール

Cabal は通常は haskell.org から GHCup 等を使って GHC と同時にインストールします。 また Stack も Cabal とは別の Haskell のパッケージマネージャーですが、一緒にインストールしておきましょう。

基本的な使い方

久しぶりに cabal をつかうときは cabal update しておきましょう。

以下のコマンドを実行することで、Cabal の my-project という名前のパッケージを作成できます。

mkdir my-project
cd my-project
cabal init

途中でいくつかの質問を聞かれますが、 Author name や Maintener email address は適切に入力してください。 他は、すべてデフォルト(Enter を押していくだけ)で問題ないでしょう。 とりあえず、テンプレートプログラムができているので、ビルドします。

cabal build

次のコマンドで実行します。

cabal run my-project

あるいは以下のコマンドでも実行できます。

cabal run exes

プログラム(デフォルトは app/Main.hs)の中身とともに my-project.cabal というファイルに必要な設定を書いていきます。 cabal init のときにデフォルトを選んだ場合は、 .cabal ファイルにコメントが入っているはずなので、 どこに何を書くか、大体わかります。 特に build-depends: のあとに、 依存するライブラリー名をコンマで区切って記述します。

プログラムに実行時引数を渡すときは、次のように -- の後に指定します。

cabal run my-project -- runtime arguments

あるいは以下のコマンドでも実行できます。

cabal run exes -- runtime arguments

実行例

既存の Git リポジトリーにあるパッケージの依存関係をインストールしてみます。

https://github.com/Kagawa-Laboratory/quasiquote-sample.git から、QuasiQuote を使用したサンプルパッケージをクローンして、依存関係をインストールしてください。 このサンプルは C 言語の“愚形”を発見しようとするプログラムです。

git clone https://github.com/Kagawa-Laboratory/quasiquote-sample.git
cd quasiquote-sample
cabal build

これで、サンプルパッケージのquasiquote-sample.cabal ファイルに記録されている依存関係がインストールされました。 実行するには、解析したい C のプログラムを dir/foo.c としておいて、次のコマンドを使用します。

cabal run quasiquote-sample -- dir\foo.c 

C のプログラムとしては以下のような例を試してみてください。

このサンプルプログラムでは“愚形”の存在するソースファイル中の位置の表示のみ行います。

基本的な使い方

Cabal の使用例として diagrams ライブラリーを使ってみましょう。 次のように Cabal パッケージを作成します。

mkdir diagrams-sample
cd diagrams-sample
cabal init

cabal init のときにいくつか質問されますが、デフォルトのままで問題ありません。

これで diagrams-sample.cabal という cabal の設定ファイルができているので、 VS Code などのエディターを使って diagrams-sample.cabal ファイルの build-depends: のところに、 次のように diagrams-libdiagrams-svg を追加してください。

    build-depends:    base ^>=4.21.0.0
                    , diagrams-lib
                    , diagrams-svg    

base のバージョン (^>=4.21.0.0)は GHC のバージョンに依存するので cabal init のときにできた通りにしておいてください。

さらに app/Main.hs というファイルもできているので、 これを次のような内容に書き換えてください。

あるいは Diagrams ギャラリー から好きなのを選んでも構いません。 そのソースファイルをダウンロードして、app/Main.hs と置き換えてください。(あるいは app/ ディレクトリーの下において、diagrams-sample.cabal の main-is: をダウンロードしたファイル名に変更してください。 例えば Kaleidoscope.lhs をダウンロードした場合は次のようにします。

    main-is:         Kaleidoscope.lhs      

準備ができたら、次のコマンドでビルドします。

cabal build

このとき、diagrams-libdiagrams-svg 以外にライブラリーが必要な場合は、エラーが表示されます。 (選んだソースファイルによっては、依存するライブラリー (build-depends) を追加する必要がある場合もあります。) エラーメッセージから必要なライブラリーを調べて diagrams-sample.cabalbuild-depends: に追加してください。

ビルドが成功したら実行します。上の Main.hs の場合は、実行時引数が必要なので次のように -- のあとに指定して実行します。

cabal run exes -- -w 256 -h 256 -o sample.svg 

これで、sample.svg というファイルができているはずです。 ブラウザなどで開いて確認してください。

他に実行結果の見栄えのよいライブラリーとしては、 gloss もあります。 こちらは、リアルタイムにアニメーションを表示できるライブラリーです。 このライブラリーを使用するときは build-depends:gloss を指定します。 ホームページにいくつかのサンプルがあるので、試してみてください。

cabal ファイルの構成

ここでは .cabal ファイルの主要なプロパティーについて説明します。 他のプロパティーについては、公式ドキュメントを参照してください。

.cabal ファイルの大まかな構成を以下に示します。 例のように共通部分と library セクション、executable セクションに分かれています。

cabal-version: 2.4
name:          my-project
version:       1.0.0
license:       BSD-3-Clause

library
    build-depends:    base ^>=4.21.0.0
                    , library-name
                      ⋮
    hs-source-dirs:   src
    other-modules:    Module.Name1
    exposed-modules:  Module.Name2

executable my-project
    main-is:         Main.hs
    hs-source-dirs:   app
    other-modules:    Module.Name3
    build-depends:    base ^>=4.21.0.0
                    , my-project
                    , library-name

name:

パッケージの名前を指定します。

version:

パッケージのバージョンを指定します。

data-files:

パッケージで使用するデータファイルがあれば、それらを指定します。

library

library セクションでは、このパッケージで実装するライブラリーの設定を記述します。 library name という形式で、ライブラリーの名前を指定することもできますが、 今回は説明を割愛します。

build-depends:

実行時に必要とするライブラリーを指定します。 ここでのバージョンの指定の仕方は、次のような形式で行います。

    build-depends:    base ^>=4.21.0.0
                    , diagrams-lib
                    , diagrams-svg

^>= は、指定したバージョン以上で、次のメジャーバージョン未満のバージョンを許容することを意味します。 Haskell のパッケージの場合、メジャーバージョンは A.B.C の形式の A.B の部分です。 C はマイナーバージョンで、バグ修正などのために更新されることが多いので、^>= を使うと便利です。 >= は、単にそのバージョン以上という指定になります。 ==< なども使用できますが、ここでは説明を割愛します。 バージョンを指定しなかった場合は、どのバージョンも許容されることになります。

hs-source-dirs:

ソースファイルのルートディレクトリを指定します。

other-modules:

外部に公開しないモジュールを指定します。

exposed-modules:

パッケージが外部に公開するモジュールを指定します。ここで指定したモジュールは、他のパッケージからインポート可能になります。

executable name

executable セクションでは、このパッケージで実装する実行可能ファイルの設定を記述します。 executable name という形式で、実行可能ファイルの名前を指定する必要があります。 (cabal init のときにデフォルトの答を選んだときはプロジェクトと同じ名前になっているはずです。) build-depends:, hs-source-dirs:, other-modules: などのプロパティーは、 library セクションと同様に使用できます。

main-is:

実行可能ファイルの main 関数を持つソースファイルを指定します。