4.9. パッケージ

パッケージとは、Haskellモジュールから成るライブラリで、コンパイラが把握している。GHCにはいくつかのパッケージが付属している。同梱のライブラリ説明書(訳注: 未訳。web上の最新版)を見よ。また、HackageDBから別のライブラリを入手してインストールすることができる。

パッケージを使う手順はこの上なく単純である。--makeやGHCiを使っているなら、インストール済みパッケージの大部分を余分なオプションなしでプログラムから使うことができる。例外は下記4.9.1. パッケージを使う で説明されている。

自分のパッケージをビルドするのもとても簡単な作業である。我々が提供するCabalインフラストラクチャがパッケージの設定、ビルド、インストール及び配布を自動化する。必要なのは、単純な設定ファイルを書き、いくつかのファイルを正しい場所に置くことだけである。詳細はCabal説明書(訳注: 未訳。web上の最新版)およびCabalライブラリ(例えばDistribution.Simple)を見よ。

4.9.1. パッケージを使う

GHCは、インストール済みのパッケージしか関知しない。どんなパッケージがインストールされているか見るためには、ghc-pkg listコマンドを使えば良い。

$ ghc-pkg list
/usr/lib/ghc-6.12.1/package.conf.d:
    Cabal-1.7.4
    array-0.2.0.1
    base-3.0.3.0
    base-4.2.0.0
    bin-package-db-0.0.0.0
    binary-0.5.0.1
    bytestring-0.9.1.4
    containers-0.2.0.1
    directory-1.0.0.2
    (dph-base-0.4.0)
    (dph-par-0.4.0)
    (dph-prim-interface-0.4.0)
    (dph-prim-par-0.4.0)
    (dph-prim-seq-0.4.0)
    (dph-seq-0.4.0)
    extensible-exceptions-0.1.1.0
    ffi-1.0
    filepath-1.1.0.1
    (ghc-6.12.1)
    ghc-prim-0.1.0.0
    haskeline-0.6.2
    haskell98-1.0.1.0
    hpc-0.5.0.2
    integer-gmp-0.1.0.0
    mtl-1.1.0.2
    old-locale-1.0.0.1
    old-time-1.0.0.1
    pretty-1.0.1.0
    process-1.0.1.1
    random-1.0.0.1
    rts-1.0
    syb-0.1.0.0
    template-haskell-2.4.0.0
    terminfo-0.3.1
    time-1.1.4
    unix-2.3.1.0
    utf8-string-0.3.4

インストールされているパッケージは、デフォルトで露出されているか隠されているかのいずれかである。デフォルトで隠されているパッケージは、ghc-pkg listの出力の中に括弧付きで((lang-1.0)のように)現れるか、ターミナルが色付けに対応しているなら青で表示される。下記のコマンド行フラグを使えば、隠しパッケージを露出したり露出パッケージを隠したりできる。あなたのHaskellコードからインポートできるのは露出されているパッケージのモジュールだけである。隠しパッケージのモジュールをインポートしようとすると、GHCはエラーメッセージを出力する。

参考: Cabalを使っているなら、パッケージが露出されているか隠されているかという区別は関係しない。どのパッケージが利用可能かは.cabalの指定に列挙されている依存関係から決定される。露出されているか隠されているかの区別はghcghciを直接使うときのみ影響する。

パッケージが隠されているかの状態と似たものに、パッケージが信用されているかどうかの区別がある。この性質は、-fpackage-trustフラグを有効にし、GHCのSafe Haskell機能(7.27. Safe Haskellを見よ)を使ってコードをコンパイルする場合にのみ意味を持つ。

あるパッケージがどんなモジュールを公開しているかを見るには、ghc-pkgコマンドを使う。(4.9.6. パッケージ管理(ghc-pkgコマンド)を見よ)

$ ghc-pkg field network exposed-modules
exposed-modules: Network.BSD,
                 Network.CGI,
                 Network.Socket,
                 Network.URI,
                 Network

パッケージ制御のためのコマンド行引数は以下の通りである。

-package P

このオプションを与えると、インストール済みパッケージPが露出される。パッケージPはバージョン番号付きで完全な形で指定しても良いし(たとえば、network-1.0)、単一のバージョンしかインストールされていないならバージョン番号は省略しても良い。Pの複数のバージョンがインストールされているなら、指定されたもの以外の全てのバージョンは隠される。

さらに、-package PオプションはパッケージPが生成される実行ファイルや共有オブジェクトにリンクされるようにする。パッケージのライブラリが静的にリンクされるか動的にリンクされるかは-static/-dynamicの二つのフラグによって制御される。

--makeモードと--interactiveモード(4.5. 実行モードを見よ)では、通常、コンパイラはどのパッケージが現在のHaskellモジュール群から必要とされているかを判断し、それらだけをリンクする。一方、一括処理モードでは、依存性情報が利用できず、リンク時に-packageを明示的に与えなければならない。他に-packageを使ってパッケージのリンクを強制しなければならないのは、そのパッケージがHaskellモジュールを一つも含んでいない(たとえばCライブラリのみとか)場合である。その場合、GHCがそのパッケージへの依存を発見することはないので、明示的に言及する必要がある。

例えば、Foo.oMain.oの二つのオブジェクトから成るプログラムをリンクするとき、networkパッケージを使っているなら、GHCに次のように-packageフラグを渡す必要がある。

$ ghc -o myprog Foo.o Main.o -package network

仮にソースからコンパイルしているとしても、同じフラグが必要である。これは、GHCが自分自身が一括処理モードで動いていると考えているからである。

$ ghc -o myprog Foo.hs Main.hs -package network
-package-id P

-packageのようにパッケージを露出するが、パッケージは名前ではなくIDで示される。これはパッケージを示す方法としてより頑健であり、通常なら(訳注: 同名パッケージに)覆い隠されてしまうパッケージを選択するのに用いることもできる。Cabalは-package-idフラグをGHCに渡す。

-hide-all-packages

インストール済みパッケージの露出フラグを無視し、それらをデフォルトで隠すようにする。このフラグを使うなら、必要なパッケージは(baseも含めて)全て-packageオプションで露出させる必要がある。

これは、どんなパッケージが大域的に露出されているかにプログラムが依存しないようにするのに有効である。また、パッケージへの依存を明示的に述べることは良いことである。このような理由で、Cabalは常に-hide-all-packagesフラグをGHCに渡す。

-hide-package P

このオプションは-packageの逆を行う。すなわち、指定されたパッケージを隠された状態にする。この状態では、そのパッケージのモジュールはHaskellのimport指令でインポートすることができない。

このオプションが指定されていても、このパッケージは最終的にプログラムにリンクされるかもしれない(別の露出パッケージが直接・間接にこのパッケージに依存しているかもしれないので)ことに注意せよ。

-ignore-package P

指定されると、コンパイラは、パッケージPおよびPに依存する全てのパッケージが全くインストールされていないかのように振る舞う。

-igonore-package Pと言うのは、P、及びPに依存する全てのパッケージについて-hide-packageフラグを与えるのと同じである。Pに依存するインストール済みパッケージがどれなのか前もって分からないことがあるが、そういうときに-ignore-packageフラグが便利である。

-no-auto-link-packages

デフォルトでは、GHCはbaseおよびrtsパッケージを自動的にリンクに組み入れる。このフラグはこの振る舞いを無効にする。

-package-name foo

コンパイルしようとしているモジュールが、パッケージfooの一員であることを、GHCに伝える。このフラグが省略される(とてもよくある場合である)と、デフォルトのパッケージであるmainと推定される。

注意: -package-nameの引数はそのパッケージの完全なパッケージ名-バージョン形式であるべきである。例えば、-package mypkg-1.2のように。

-trust P

このオプションは、インストール済みパッケージPを露出し、さらにGHCによって信用されるようにする。このコマンドは-packageと非常に似た形で機能するが、追加の作用として、パッケージデータベースの内容にかかわらず、GHCが選択されたパッケージを信用するようにする。(7.27. Safe Haskellを見よ)。

-distrust P

このオプションは、インストール済みパッケージPを露出し、さらにGHCによって信用されないようにする。このコマンドは-packageと非常に似た形で機能するが、追加の作用として、パッケージデータベースの内容にかかわらず、GHCが選択されたパッケージに信用を置かないようにする。(7.27. Safe Haskellを見よ)。

-distrust-all

インストール済みパッケージ群の信用フラグを無視し、デフォルトで信用しないようにする。このフラグをSafe Haskellと共に使うなら、信用される必要があるパッケージは(baseも含めて)-trustオプションを使って明示的に信用を与えられなければならない。このオプションはパッケージの隠し/露出状態を変えないので、システム中の全てのパッケージに-distrustを与えるのとは異なる。(7.27. Safe Haskellを見よ)。

4.9.2. mainパッケージ

完全なHaskellプログラムは全て、mainパッケージのMainモジュールのmainを定義せねばならない。(-package-nameフラグを省略するとmainパッケージ用のコードがコンパイルされる)。これを怠ると、やや不明瞭なリンク時エラーのメッセージが出る。

/usr/bin/ld: Undefined symbols:
_ZCMain_main_closure

4.9.3. パッケージを使うことのHaskell言語への影響

パッケージを使っていると、同じ名前の二つのモジュールができることがあり得る。例えば、あなたのプログラムがパッケージPを使っていて、Pには隠されたモジュールMがあり、さらにあなたのプログラムにもモジュールMがあるかもしれない。あるいは、利用している複数のパッケージの依存関係が重複したモジュールを含むかもしれない。パッケージの依存関係のせいで、あるプログラムが一つのパッケージの複数のバージョンを含むことさえあり得る。

これらの状況は、それだけではエラーではないが、[8]興味深い結果を招くことがある。例として、パッケージPのバージョン1にM.Tという型があるとすると、これはパッケージPのバージョン2由来のM.Tと同じ型ではない。一方が必要なときにもう一方を使おうとするとGHCはエラーを報告するだろう。

形式的にいうと、Haskell98では、プログラム中の実体(関数または型またはクラス)はそれが定義されているモジュール名と名前との対で一意に識別される。GHCでは、ある実体は、パッケージ、モジュール、名前の三つ組で一意に識別される。

4.9.4. パッケージデータベース

パッケージデータベースとは、インストール済みのパッケージについての詳細が記録されている場所である。パッケージデータベースは一つのディレクトリであり、通常package.conf.dという名前である。これには各パッケージごとのファイルと、パッケージデータのバイナリキャッシュが入ったpackage.cacheが置かれている。通常、パッケージデータベースの中身を直接見たり変更したりする必要はないはずである。パッケージデータベースの管理はすべてghc-pkgツールを介して行える(4.9.6. パッケージ管理(ghc-pkgコマンド)を見よ)。

GHCは特定の二つのパッケージデータベースについて知っている。

  • 大域的パッケージデータベース。これはGHCのインストール内容に含まれる。例えば、/usr/lib/ghc-6.12.1/package.conf.d

  • 各ユーザ専用のパッケージデータベース。Unixシステムではこれは$HOME/.ghc/arch-os-version/package.conf.dであり、WindowsではC:\Documents And Settings\user\ghc\package.conf.dのようなところである。ghc-pkgツールはこのファイルがどこに置かれるべきか知っていて、存在しなければこれを作る。(4.9.6. パッケージ管理(ghc-pkgコマンド)を見よ)

GHCは、起動すると、これらの二つのパッケージデータベースの内容を読み、既知のパッケージの一覧を作り上げる。パッケージの一覧表を見るには、GHCを-vフラグ付きで走らせれば良い。

パッケージデータベースには重複があっても良く、スタック構造で配置される。スタックの一番上に近いパッケージは下のものより優先される(それを覆い隠す)。デフォルトでは、スタックには大域データベースとユーザのパッケージデータベースがこの順であるだけである。

GHCのパッケージデータベースのスタックを制御するには、以下のオプションを使えば良い。

-package-db file

パッケージデータベースfileを現在のスタックの一番上に置く。この方法で読まれるデータベースにあるパッケージは、スタックに最初からあったものや以前に指定されたパッケージよりも優先される。

-no-global-package-db

パッケージデータベースのスタックから大域パッケージデータベースを取り除く。

-no-user-package-db

ユーザ固有のパッケージデータベースを初期スタックにロードしない。

-clear-package-db

現在のパッケージデータベーススタックを空にする。このオプションは、以前に指定されたパッケージデータベースを(GHC_PACKAGE_PATH環境変数から読まれたものも含めて)全てパッケージデータベーススタックから取り除く。

-global-package-db

現在のスタックの一番上に大域パッケージデータベースを加える。このオプションは、-no-global-package-dbの後に使うことで、スタック内で大域パッケージデータベースがロードされるべき位置を指定することができる。

-user-package-db

現在のスタックの一番上にユーザのパッケージデータベースを加える。このオプションは、-no-user-package-dbの後に使うことで、スタック内でユーザのパッケージデータベースがロードされるべき位置を指定することができる。

4.9.4.1. GHC_PACKAGE_PATH環境変数

GHC_PACKAGE_PATH環境変数に:区切り(Windowsでは;区切り)でパッケージデータベースファイルを並べて指定することができる。この一覧はGHCとghc-pkgが使う。このとき、一覧に先に現れるデータベースが後のものより優先される。これはPATH環境変数の挙動に倣ったものである。この一覧が左から順に探索されると考えると良い。

GHC_PACKAGE_PATHが区切り子で終わるなら、デフォルトのパッケージデータベーススタック(つまり、ユーザのパッケージデータベースと大域パッケージデータベースがこの順で)付け加えられる。例えば、通常のパッケージにあなた自身のデータベースを付け加えるには、次のようにすると良い。(Unixの例)

$ export GHC_PACKAGE_PATH=$HOME/.my-ghc-packages.conf:

(Windowsでは:の代わりに;を使うこと)

GHC_PACKAGE_PATHが正しく設定されているかどうかを確かめるには、ghc-pkg listとすれば良い。これは、利用中のパッケージデータベースを、探索されるのと逆の順序で全て表示する。

4.9.5. パッケージID、依存関係、壊れたパッケージ

インストール済みのパッケージにはそれぞれ固有の識別子(「インストール済みパッケージID」または単に短く「パッケージID」)があり、そのシステムにインストールされている他のパッケージと区別される。インストール済みパッケージそれぞれに決められたパッケージIDを見るには、ghc-pkg list -vを使えばよい。

$ ghc-pkg list -v
using cache: /usr/lib/ghc-6.12.1/package.conf.d/package.cache
/usr/lib/ghc-6.12.1/package.conf.d
   Cabal-1.7.4 (Cabal-1.7.4-48f5247e06853af93593883240e11238)
   array-0.2.0.1 (array-0.2.0.1-9cbf76a576b6ee9c1f880cf171a0928d)
   base-3.0.3.0 (base-3.0.3.0-6cbb157b9ae852096266e113b8fac4a2)
   base-4.2.0.0 (base-4.2.0.0-247bb20cde37c3ef4093ee124e04bc1c)
   ...

パッケージ名の後の括弧内にある文字列がパッケージIDである。これは通常パッケージ名とバージョンで始まり、コンパイルされたパッケージから導出されたハッシュ文字列で終わる。パッケージ間の依存関係は、単にパッケージとバージョンについてではなく、パッケージIDについて表現される。例えば、このhaskell98パッケージの依存関係を見て欲しい。

$ ghc-pkg field haskell98 depends
depends: array-0.2.0.1-9cbf76a576b6ee9c1f880cf171a0928d
         base-4.2.0.0-247bb20cde37c3ef4093ee124e04bc1c
         directory-1.0.0.2-f51711bc872c35ce4a453aa19c799008
         old-locale-1.0.0.1-d17c9777c8ee53a0d459734e27f2b8e9
         old-time-1.0.0.1-1c0d8ea38056e5087ef1e75cb0d139d1
         process-1.0.1.1-d8fc6d3baf44678a29b9d59ca0ad5780
         random-1.0.0.1-423d08c90f004795fd10e60384ce6561

パッケージを再インストールしたときに、それに依存するパッケージを再コンパイルし忘れると問題が起こるが、パッケージIDはこの問題を検出するために存在する。再コンパイルの依存関係が必要なのは、例え同じソースコードから同じコンパイラでビルドされたとしても、新しくコンパイルされたパッケージのABI(Application Binary Interface)が異なるかもしれないからである。パッケージIDがあると、再コンパイルしたパッケージは前の版とは異なるパッケージIDを持つことになるので、前の版に依存していたパッケージは宙に浮いた状態、つまり依存関係のうちどれかが満たされていない状態になる。この意味で壊れているパッケージは、ghc-pkg listの出力において、赤色(可能なら)か、さもなくば中括弧で囲まれて示される。次の例において、filepathパッケージを再コンパイル、再インストールしたので、これによってCabalを含むいくつかの依存物が壊れている。

$ ghc-pkg list
WARNING: there are broken packages.  Run 'ghc-pkg check' for more details.
/usr/lib/ghc-6.12.1/package.conf.d:
    {Cabal-1.7.4}
    array-0.2.0.1
    base-3.0.3.0
    ... etc ...

加えて、ghc-pkg listは壊れたパッケージがあることについて注意を促し、ghc-pkg checkを勧める。これは、この失敗の性質についてさらなる情報を表示するものである。

$ ghc-pkg check
There are problems in package ghc-6.12.1:
  dependency "filepath-1.1.0.1-87511764eb0af2bce4db05e702750e63" doesn't exist
There are problems in package haskeline-0.6.2:
  dependency "filepath-1.1.0.1-87511764eb0af2bce4db05e702750e63" doesn't exist
There are problems in package Cabal-1.7.4:
  dependency "filepath-1.1.0.1-87511764eb0af2bce4db05e702750e63" doesn't exist
There are problems in package process-1.0.1.1:
  dependency "filepath-1.1.0.1-87511764eb0af2bce4db05e702750e63" doesn't exist
There are problems in package directory-1.0.0.2:
  dependency "filepath-1.1.0.1-87511764eb0af2bce4db05e702750e63" doesn't exist

The following packages are broken, either because they have a problem
listed above, or because they depend on a broken package.
ghc-6.12.1
haskeline-0.6.2
Cabal-1.7.4
process-1.0.1.1
directory-1.0.0.2
bin-package-db-0.0.0.0
hpc-0.5.0.2
haskell98-1.0.1.0

この問題を解決するには、壊れたパッケージ群を、新しい依存関係に対して再コンパイルしなければならない。これをするのに最も簡単な方法は、cabal-installを使うか、あるいはHackageDBからそのパッケージをダウンロードして通常と同じようにビルド、インストールすることである。

GHC自身が依存しているパッケージを再コンパイルすることがないように注意。これをするとghcパッケージ自体が壊れる可能性があり、ghcは単純にコンパイルしなおすことができない。この状態から回復するにはGHCを再インストールするしかないだろう。

4.9.6. パッケージ管理(ghc-pkgコマンド)

ghc-pkgツールは、パッケージデータベースの情報を取得したり、これに変更を加えたりするためのものである。どんなパッケージデータベースが使われているか見るには、ghc-pkg listとすれば良い。ghc-pkgが知っているパッケージデータベースのスタックは、GHC_PACKAGE_PATH環境変数(4.9.4.1. GHC_PACKAGE_PATH環境変数を見よ)を使うか、ghc-pkgのコマンド行から--package-dbを使うことで変更できる。

データベースを変更するとき、ghc-pkgはデフォルトで大域的データベースを変更する。--userを指定すればユーザデータベースが操作される。また、--package-dbを使ってまったく別のデータベースを操作させることもできる。これらのオプションが複数与えられたときは、もっとも右にあるものが対象のデータベースとして使われる。

パッケージデータベースに問い合わせを行うコマンド(list、latest、describe、find、dot)は、フラグ--user--global--package-dbによって指定されるデータベースの列に対して動作する。これらのフラグが一つも与えられなかった場合、デフォルトは--global --userである。

GHC_PACKAGE_PATH環境変数が設定されていて、その値の最後が区切り子(Unixでは:、Windowsでは;)でないとき、最後のデータベースが大域データベースとみなされ、ghc-pkgはデフォルトでこれを変更する。このようになっているのは、GHC_PACKAGE_PATHを使って仮想的なパッケージ環境を構築し、そこでは他に何も指定することなくCabalパッケージをインストールできるようにすることが可能であるように、である。

ghc-pkgプログラムは下の一覧にあるような方法で実行できる。パッケージ名が必要なところでは、バージョン番号を含めて完全な形で指定しても良いし(network-1.0のように)、バージョン番号なしで指定しても良い。パッケージをバージョン番号なしで指定すると、そのパッケージの全てのバージョンが該当する。指定された操作は該当する全てのパッケージに対して行われる。パッケージの全てのバージョンが該当するという指定子はpkg-*のように書くこともでき、こうすれば複数のパッケージが該当するだろうことがより明確になる。

ghc-pkg init path

pathに、新しい空のパッケージデータベースを作る。pathが既に存在していてはならない。

ghc-pkg register file

file(これは「-」であっても良い。その場合標準入力)からパッケージの仕様を読み、インストール済みパッケージのデータベースに加える。fileの構文は4.9.8. InstalledPackageInfo: パッケージの仕様 で与えられる。

パッケージの仕様はインストール済みパッケージのものであってはならない。

ghc-pkg update file

registerと同様だが、同名のパッケージがインストール済みなら、新しいもので置き換える。

ghc-pkg unregister P

指定されたパッケージをデータベースから削除する。

ghc-pkg check

パッケージデータベース内の依存関係の整合性を検査し、依存関係が満たされていないパッケージがあれば報告する。

ghc-pkg expose P

パッケージPexposedフラグ(訳注: 露出フラグ)をTrueに設定する。

ghc-pkg hide P

パッケージPexposedフラグ(訳注: 露出フラグ)をFalseに設定する。

ghc-pkg trust P

パッケージPtrustedフラグをTrueに設定する。

ghc-pkg distrust P

パッケージPtrustedフラグをFalseに設定する。

ghc-pkg list [P] [--simple-output]

このオプションは、ghc-pkgの知っているデータベースそれぞれについて、現在インストールされているパッケージを表示する。これには大域データベース、ユーザ固有のデータベース、及びコマンド行から-fオプションで指定されたファイルが含まれる。

隠されたパッケージ(exposedフラグ(訳注: 露出フラグ)がFalseであるもの)は括弧付きで表示される。

パッケージ識別子Pは省略可能だが、これが与えられると、この識別子に該当するパッケージのみが出力される。

--simple-outputオプションが与えられると、パッケージはスペースで区切られて一行で出力され、データベース名は含まれない。これはghc-pkg listの出力をスクリプトでパースするのが楽なようにである。

ghc-pkg find-module M [--simple-output]

このオプションは、Mというモジュールをエクスポートしている登録済みパッケージを列挙する。例を挙げる。

$ ghc-pkg find-module Var
c:/fptools/validate/ghc/driver/package.conf.inplace:
    (ghc-6.9.20080428)

$ ghc-pkg find-module Data.Sequence
c:/fptools/validate/ghc/driver/package.conf.inplace:
    containers-0.1

それ以外の点については、オプションを含め、ghc-pkg listと同じように振る舞う。

ghc-pkg latest P

パッケージPの最新の利用可能な版を表示する。

ghc-pkg describe P

指定されたパッケージの完全な説明を出力する。説明はInstalledPackageInfoの形で、これはghc-pkg registerへの入力ファイルの書式と同じである。詳細は4.9.8. InstalledPackageInfo: パッケージの仕様 を見よ。

パターンが複数のパッケージと照合する場合、個々のパッケージの説明が---という文字列だけからなる行で区切られて出力される。

ghc-pkg field P field[,field]*

インストール済みパッケージPの説明のうち、一つのフィールドを表示する。コンマで区切ることで複数のフィールドを選択できる。

ghc-pkg dot

パッケージの依存関係のグラフを、graphvizへの入力に適した形式で生成する。例えば、依存グラフのPDFを生成するには次のようにする。

ghc-pkg dot | tred | dot -Tpdf >pkgs.pdf
ghc-pkg dump

全てのパッケージについて、InstalledPackageInfoの形式で完全な説明を出力する。複数のパッケージは---という文字列だけからなる行で区切られる。

これはghc-pkg describe '*'とほとんど同じである。ただし、ghc-pkg dumpは結果をパースするツールによって使われることを意図しているので、例えばghc-pkg describe '*'はパターンに照合するパッケージを見つけられなかった場合にエラーを出力するのに対し、ghc-pkg dumpは何も出力しないだけである。

ghc-pkg recache

選択したデータベースについて、バイナリキャッシュファイルpackage.cacheを再作成する。これは、キャッシュが何らかの理由でデータベースの内容との同期が取れなくなった場合に必要かもしれない(この疑いがある場合、ghc-pkgが警告を発するだろう)。

これ以外でghc-pkg recacheが便利なのは、パッケージを手動で登録する場合である。パッケージの登録は、適切なファイルをデータベースディレクトリに置き、ghc-pkg recacheでキャッシュを更新するだけで可能である。自動化されたパッケージシステムにとっては、こちらの方法でパッケージを登録する方が便利かもしれない。

find-moduleMlistdescribeP、そしてfieldについては、部分文字列照合ができる。その場合、部分文字列の開放端を'*'で示す。(prefix**suffix*infix*のように)。例を示す(出力は省略)。

-- regex関係のパッケージを全て表示する
ghc-pkg list '*regex*' --ignore-case
-- 文字列関係のパッケージを全て表示する
ghc-pkg list '*string*' --ignore-case
-- OpenGL関係のパッケージ
ghc-pkg list '*gl*' --ignore-case
-- Data階層のモジュールをエクスポートしているパッケージを一覧
ghc-pkg find-module 'Data.*'
-- Monadモジュールをエクスポートしているパッケージを一覧
ghc-pkg find-module '*Monad*'
-- 全てのパッケージの名前とメンテナを表示
ghc-pkg field '*' name,maintainer
-- 全てのパッケージのhaddockのhtmlの場所を表示
ghc-pkg field '*' haddock-html
-- データベース全体をダンプ
ghc-pkg describe '*'

さらに、ghc-pkgは以下のフラグを受け付ける。

-f file , -package-db file

fileをパッケージデータベースのスタックに加える。さらに、後続のオプションに上書きされない限り、registerunregisterexposehideコマンドが変更するデータベースはfileになる。これを上書きし得るのは、--package-db--user--globalである。

--force

パッケージを登録するとき、足りない依存関係、ディレクトリ、ファイルを無視して構わず追加する。これは、使っているパッケージシステムの要請で、ファイルをビルドしてインストールする前にGHCにパッケージを登録しないといけない場合に有用かもしれない。

--global

大域的パッケージデータベースを操作する。(これがデフォルトである)。このフラグはregisterupdateunregisterexposehideの各コマンドに影響する。

--help , -?

コマンド行構文の要約を出力する。

--user

現在のユーザのパッケージデータベースを操作する。このフラグはregisterupdateunregisterexposehideの各コマンドに影響する。

-v[n] , --verbose[=n]

多弁さを制御する。多弁さの水準は0から2までであり、デフォルトは1である。-vのみなら2が選択される。

-V , --version

ghc-pkgのバージョン番号を出力する。

4.9.7. Haskellソースからパッケージをビルドする

苦労してパッケージをビルドすることは推奨されない。代わりに、可能ならCabal(訳注: 未訳。web上の最新版)を使ってほしい。しかし、あなたのパッケージが特に複雑だったリ、大量の設定を要したりするなら、低レベルな機構にフォールバックしなければならないかもしれないので、そういう強者のためにいくつか手がかりを示しておく。

パッケージをインストールする際、ghc-pkgに渡すための「インストール済みパッケージ情報」ファイルを構築する必要がある。このファイルの内容は4.9.8. InstalledPackageInfo: パッケージの仕様 に説明されている。

パッケージ中のHaskellコードは、ビルドされて一つ以上のライブラリアーカイブ(例えばlibHSfoo.a)になるか、あるいは単一の共有オブジェクト(例えばHSfoo.dll/.so/.dylib)になることもできる。共有オブジェクトが単一でなければいけないのは、コンパイラが共有オブジェクト間呼び出しを作るか共有オブジェクト内呼び出しを作るかの判断にパッケージシステムが用いられるからである。(共有オブジェクト間呼び出しには余分な間接参照が必要になる)。

  • 静的ライブラリをビルドするのはarを用いて為される。次のように。

    ar cqs libHSfoo-1.0.a A.o B.o C.o ...

    ここで、A.oB.oなどはコンパイル済みHaskellモジュールであり、libHSfoo.aは作りたいライブラリである。システムによって構文が微妙に違うかもしれないので、問題があれば説明書を確かめること。

  • パッケージfooをロードするに当たって、GHCはそれのlibHSfoo.aライブラリを直接ロードすることもできるが、リンク済みの単一のHSfoo.oの形のパッケージをロードすることもできる。.oファイルをロードするのはやや速いが、代わりにコンパイル済みパッケージのコピーを一つ余分に持つ必要がある。経験的には、パッケージのモジュールが-split-objs付きでコンパイルされたのなら、パッケージをGHCiにロードする時間を減らせるのでHSfoo.oを使う価値がある。-split-objsなしでは、.o.aのライブラリの間にあまり大きなロード時間の違いがないので、.aだけを置いておくことでディスク領域を節約した方が良い。GHC配布物中では、GHCパッケージ自体を除く大部分のパッケージに.oを用意している。

    HSfoo.oファイルはCabalによって自動的にビルドされる。これを無効にするには--disable-library-for-ghciを使う。手動でビルドするには、以下のGNU ldコマンドを使うことができる。

    ld -r --whole-archive -o HSfoo.o libHSfoo.a

    (MacOS Xなら--whole-archiveの代わりに-all_loadを使うこと。)

  • パッケージを共有ライブラリとしてビルドする場合、リンクの段階を行うためにGHCを使うことができる。これによって、内部的に使うリンカの詳細が一部隠され、GHCが対応している全ての共有オブジェクト形式(DLL、ELF DSO、Mac OSのdylib)に対して共通のインタフェースが得られる。共有オブジェクトは特定の方法で命名されねばならないが、これは次の二つの理由による。(1)GHCのコンパイラバージョンが名前に含まれていなければならない。これは、ライブラリを二つの異なるバージョンのGHCでコンパイルすると、呼び出し規約の点でまず間違いなく非互換になるので、これらが衝突しないようにするためである。(2)この名前は、静的ライブラリの名前とは異なっていなければならない。さもなくば、精密にリンカを制御することができず、-static/-dynamicフラグが動作するようにできなくなるだろう。4.12.6. リンクに影響するオプションを見よ。

    ghc -shared libHSfoo-1.0-ghcGHCVersion.so A.o B.o C.o

    共有オブジェクトの名前の中にGHCのバージョン番号を使うことで、異なるバージョンのGHCでコンパイルした異なるバージョンのライブラリをシステムの標準の場所(たとえば*nixの/usr/lib以下)にインストールすることが可能になる。GHCのバージョン番号を得るには、ghc --numeric-versionを起動して、その出力をGHCVersionとして使えばよい。共有オブジェクトをリンクするためにオブジェクトファイルを準備する方法について、4.12.5. コード生成に影響するオプションも参照せよ。

新しいパッケージの一部となるべきモジュールをコンパイルするときは、-package-nameオプション(4.9.1. パッケージを使う )を使うこと。パッケージのコンパイル時に-package-nameオプションを付け忘れるとおそらく惨事になるが、それが分かるのは後でそのパッケージからモジュールをインポートしようとしたときだろう。この時点でGHCは、そのモジュールがあると期待されるパッケージと、.hiファイルに記録されたパッケージ名が異なることに文句をいう。

共有オブジェクトについて注意に値することがある。それぞれのパッケージが単一の共有オブジェクトファイルとしてビルドされているとき、共有オブジェクトへの参照は余分な間接参照を必要とするので、パッケージ内での参照の方がパッケージ間参照よりもコストがかからない。もちろん、このことはmainパッケージにも当てはまる。

4.9.8. InstalledPackageInfo: パッケージの仕様

パッケージの仕様は一つのHaskellレコードである。具体的には、Distribution.InstalledPackageInfoモジュールにあるレコードInstalledPackageInfoである。これはCabalパッケージの一部であり、GHCに付属している。

InstalledPackageInfoには人間可読の構文がある。parseInstalledPackageInfoおよびshowInstalledPackageInfoという二つの関数でこの構文をそれぞれ読んだり書いたりできる。次に示すのはunixパッケージのInstalledPackageInfoの例である。

$ ghc-pkg describe unix
name: unix
version: 2.3.1.0
id: unix-2.3.1.0-de7803f1a8cd88d2161b29b083c94240
license: BSD3
copyright:
maintainer: libraries@haskell.org
stability:
homepage:
package-url:
description: This package gives you access to the set of operating system
             services standardised by POSIX 1003.1b (or the IEEE Portable
             Operating System Interface for Computing Environments -
             IEEE Std. 1003.1).
             .
             The package is not supported under Windows (except under Cygwin).
category: System
author:
exposed: True
exposed-modules: System.Posix System.Posix.DynamicLinker.Module
                 System.Posix.DynamicLinker.Prim System.Posix.Directory
                 System.Posix.DynamicLinker System.Posix.Env System.Posix.Error
                 System.Posix.Files System.Posix.IO System.Posix.Process
                 System.Posix.Process.Internals System.Posix.Resource
                 System.Posix.Temp System.Posix.Terminal System.Posix.Time
                 System.Posix.Unistd System.Posix.User System.Posix.Signals
                 System.Posix.Signals.Exts System.Posix.Semaphore
                 System.Posix.SharedMem
hidden-modules:
trusted: False
import-dirs: /usr/lib/ghc-6.12.1/unix-2.3.1.0
library-dirs: /usr/lib/ghc-6.12.1/unix-2.3.1.0
hs-libraries: HSunix-2.3.1.0
extra-libraries: rt util dl
extra-ghci-libraries:
include-dirs: /usr/lib/ghc-6.12.1/unix-2.3.1.0/include
includes: HsUnix.h execvpe.h
depends: base-4.2.0.0-247bb20cde37c3ef4093ee124e04bc1c
hugs-options:
cc-options:
ld-options:
framework-dirs:
frameworks:
haddock-interfaces: /usr/share/doc/ghc/html/libraries/unix/unix.haddock
haddock-html: /usr/share/doc/ghc/html/libraries/unix

以下はこのファイルの構文の簡単な解説である。

パッケージの仕様はいくつかのフィールド・値の対からなっている。フィールドにはまず行の左端から始まるフィールド名があり、「:」がそれに続き、さらに値が次の「左端から始まる行」またはファイル終端まで続く。

値の記法はフィールドによって異なる。次のようにいくつかのフィールド型がある。

自由形式

任意の文字列。解釈されたりパースされたりすることはない。

文字列

非空白文字の列、または引用符で囲まれた任意の文字の列"..."

文字列の並び

コンマで区切られた文字列の列。空の列であっても良い。

加えて、特別な構文を持つフィールドもいくつかある。(例えば、パッケージ名、バージョン、依存関係)

許されるフィールドと、その型は、以下の通りである。

name

パッケージ名。(バージョンを含まない)

id

パッケージID。適切なものを選ぶのはあなたの責任である。

version

パッケージのバージョン。通常はA.Bの形である。(任意の数値要素が許される)

license

(文字列)パッケージが配布されるにあたってのライセンス。このフィールドは型Licenseの値である。

license-file

(省略可能な文字列)このパッケージについての詳細なライセンス情報の置かれたファイルの名前。

copyright

(省略可能な自由形式)著作権表示の文字列。

maintainer

(省略可能な自由形式)パッケージのメンテナのメールアドレス。

stability

(省略可能な自由形式)パッケージの安定性を示す文字列。(例: stable、provisional、experimental)

homepage

(省略可能な自由形式)パッケージのホームページのURL。

package-url

(省略可能な自由形式)ダウンロード可能な、このパッケージの配布物のURL。この配布物はCabalパッケージであるべきである。

description

(省略可能な自由形式)パッケージの説明。

category

(省略可能な自由形式)パッケージが所属する分類。このフィールドは将来の中央集権化されたパッケージ配布フレームワーク(仮称Hackage)との連携のためのものである。

author

(省略可能な自由形式)パッケージの作者。

exposed

(真偽値)パッケージが露出されるか否か。

exposed-modules

(文字列の並び)このパッケージがエクスポートするモジュール。

hidden-modules

(文字列の並び)このパッケージが提供するが、プログラマには露出されないモジュール。こういうモジュールをインポートすることはできないが、重複モジュール制限の対象にはなる。(訳注: この制限はもはや存在しない)つまり、同じプログラムの別のパッケージが同じ名前のモジュールを提供していてはいけない。

trusted

(真偽値)このパッケージが信用されているか否か。

import-dirs

(文字列の並び)パッケージのインタフェースファイル(.hiファイル)のあるディレクトリの一覧。

パッケージがプロファイル版のライブラリを含むなら、そのインタフェースファイルの接尾辞は.p_hiであるべきである。したがって、パッケージは同じライブラリの通常版とプロファイル版を衝突なしに両方含むことができる。(下記のlibrary_dirsも見よ)

library-dirs

(文字列の並び)このパッケージのライブラリがあるディレクトリの一覧。

hs-libraries

(文字列の並び)このパッケージ内の、Haskellコードのライブラリの一覧。.aまたは.dllという接尾辞は省略する。パッケージがライブラリとしてビルドされるときは、libという接頭辞も省く。

GHCiで使うためには、各ライブラリにはオブジェクトファイルもあるべきである。オブジェクトファイルの名前にはlib接頭辞がなく、プラットフォームに置ける通常の接尾辞が付く。

例えば、パッケージ仕様でHaskellライブラリをHSfooと指定したとすると、GHCが実際に使うライブラリファイルは以下のものである。

libHSfoo.a

UnixおよびWindows(mingw)システムにおけるライブラリの名前。Unixシステムでは動的ライブラリをビルドするのがサポートされていないことに注意。

HSfoo.dll

Windowsシステムにおける動的ライブラリの名前。(なくても良い)

HSfoo.o, HSfoo.obj

GHCiが使う、ライブラリのオブジェクト版。

extra-libraries

(文字列の並び)このパッケージの外部ライブラリの一覧。hs-librariesextra-librariesの違いは、hs-librariesには通常、プロファイルや並列処理などのビルドオプションの違う、複数の版があることである。複数の版は区別のために異なる接尾辞を持つ。例えば、標準プレリュードライブラリのプロファイル版はlibHSbase_p.aという名前で、_pがこれがプロファイル版であることを示している。接尾辞はhs-librariesについてのみGHCによって自動で加えられ、extra-librariesのライブラリには加えられない。

extra-librariesに列挙されるライブラリはシステムのリンカがサポートするならどんなライブラリでも良く、動的ライブラリでも良い。(Unixでは.so、Windowsでは.DLL)

また、extra-librariesはリンカのコマンド行においてhs-librariesよりも後に置かれる。もしその逆の依存関係があり(つまり、extra-librarieshs-librariesに依存する)、しかもそれらが静的ライブラリなら、パッケージを二つに分割する必要があるかもしれない。

include-dirs

(文字列の並び)このパッケージのCインクルードファイルが置かれるディレクトリの一覧。

includes

(文字列の並び)このパッケージを使ってCを介したコンパイルをするときにインクルードするべきファイルの一覧。典型的には、これはこのパッケージで使われる全てのC関数のプロトタイプを含んでいて、パッケージ中のHaskell関数がインライン化された結果これらの関数が呼ばれることになったときに使われる。

depends

(パッケージIDの並び)このパッケージが依存するパッケージの一覧。

hugs-options

(文字列の並び)このパッケージのためにHugsに渡すオプション。

cc-options

(文字列の並び)このパッケージが使われるときにgccのコマンド行に渡される追加の引数。(Cを介したコンパイルでのみ使われる)

ld-options

(文字列の並び)このパッケージが使われるとき、リンク時にgccのコマンド行に渡される追加の引数。

framework-dirs

(文字列の並び)Darwin/MacOS Xにおいて、このパッケージが使うフレームワークをのあるディレクトリの一覧。これは-framework-pathオプションに対応する。その他全てのプラットフォームでは無視される。

frameworks

(文字列の並び)Darwin/MacOS Xにおいて、リンクするフレームワークの一覧。これは-frameworkオプションに対応する。どのフレームワークを実際に使うかについてはAppleのdeveloper documentationを見てほしい。この項目はその他のプラットフォームでは無視される。

haddock-interfaces

(文字列の並び)このパッケージのHaddockインタフェースファイル(.haddockファイル)の一覧。

haddock-html

(省略可能な文字列)Haddockで生成されたこのパッケージのHTML文書のあるディレクトリ。

[8]

GHC 6.4まではエラーだったが、6.6以降はそうではない。