パッケージとは、Haskellモジュールから成るライブラリで、コンパイラが把握している。GHCにはいくつかのパッケージが付属している。同梱のライブラリ説明書(訳注: 未訳。web上の最新版)を見よ。また、HackageDBから別のライブラリを入手してインストールすることができる。
パッケージを使う手順はこの上なく単純である。--make
やGHCiを使っているなら、インストール済みパッケージの大部分を余分なオプションなしでプログラムから使うことができる。例外は下記4.9.1. パッケージを使う で説明されている。
自分のパッケージをビルドするのもとても簡単な作業である。我々が提供するCabalインフラストラクチャがパッケージの設定、ビルド、インストール及び配布を自動化する。必要なのは、単純な設定ファイルを書き、いくつかのファイルを正しい場所に置くことだけである。詳細はCabal説明書(訳注: 未訳。web上の最新版)およびCabalライブラリ(例えばDistribution.Simple)を見よ。
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
の指定に列挙されている依存関係から決定される。露出されているか隠されているかの区別はghc
やghci
を直接使うときのみ影響する。
パッケージが隠されているかの状態と似たものに、パッケージが信用されているかどうかの区別がある。この性質は、-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.o
とMain.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を見よ)。
完全なHaskellプログラムは全て、main
パッケージのMain
モジュールのmain
を定義せねばならない。(-package-name
フラグを省略するとmain
パッケージ用のコードがコンパイルされる)。これを怠ると、やや不明瞭なリンク時エラーのメッセージが出る。
/usr/bin/ld: Undefined symbols: _ZCMain_main_closure
パッケージを使っていると、同じ名前の二つのモジュールができることがあり得る。例えば、あなたのプログラムがパッケージPを使っていて、Pには隠されたモジュールMがあり、さらにあなたのプログラムにもモジュールMがあるかもしれない。あるいは、利用している複数のパッケージの依存関係が重複したモジュールを含むかもしれない。パッケージの依存関係のせいで、あるプログラムが一つのパッケージの複数のバージョンを含むことさえあり得る。
これらの状況は、それだけではエラーではないが、[8]興味深い結果を招くことがある。例として、パッケージP
のバージョン1にM.T
という型があるとすると、これはパッケージP
のバージョン2由来のM.T
と同じ型ではない。一方が必要なときにもう一方を使おうとするとGHCはエラーを報告するだろう。
形式的にいうと、Haskell98では、プログラム中の実体(関数または型またはクラス)はそれが定義されているモジュール名と名前との対で一意に識別される。GHCでは、ある実体は、パッケージ、モジュール、名前の三つ組で一意に識別される。
パッケージデータベースとは、インストール済みのパッケージについての詳細が記録されている場所である。パッケージデータベースは一つのディレクトリであり、通常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/
であり、Windowsではarch
-os
-version
/package.conf.dC:\Documents And Settings\
のようなところである。user
\ghc\package.conf.dghc-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
の後に使うことで、スタック内でユーザのパッケージデータベースがロードされるべき位置を指定することができる。
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
とすれば良い。これは、利用中のパッケージデータベースを、探索されるのと逆の順序で全て表示する。
インストール済みのパッケージにはそれぞれ固有の識別子(「インストール済みパッケージ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を再インストールするしかないだろう。
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
パッケージP
のexposed
フラグ(訳注: 露出フラグ)をTrue
に設定する。
ghc-pkg hide P
パッケージP
のexposed
フラグ(訳注: 露出フラグ)をFalse
に設定する。
ghc-pkg trust P
パッケージP
のtrusted
フラグをTrue
に設定する。
ghc-pkg distrust P
パッケージP
のtrusted
フラグを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-module
のM
、list
とdescribe
のP
、そして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
をパッケージデータベースのスタックに加える。さらに、後続のオプションに上書きされない限り、register
、unregister
、expose
、hide
コマンドが変更するデータベースはfile
になる。これを上書きし得るのは、--package-db
、--user
、--global
である。
--force
パッケージを登録するとき、足りない依存関係、ディレクトリ、ファイルを無視して構わず追加する。これは、使っているパッケージシステムの要請で、ファイルをビルドしてインストールする前にGHCにパッケージを登録しないといけない場合に有用かもしれない。
--global
大域的パッケージデータベースを操作する。(これがデフォルトである)。このフラグはregister
、update
、unregister
、expose
、hide
の各コマンドに影響する。
--help
,
-?
コマンド行構文の要約を出力する。
--user
現在のユーザのパッケージデータベースを操作する。このフラグはregister
、update
、unregister
、expose
、hide
の各コマンドに影響する。
-v
[n
] ,
--verbose
[=n
]
多弁さを制御する。多弁さの水準は0から2までであり、デフォルトは1である。-v
のみなら2が選択される。
-V
,
--version
ghc-pkg
のバージョン番号を出力する。
苦労してパッケージをビルドすることは推奨されない。代わりに、可能なら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.o
、B.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
パッケージにも当てはまる。
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-libraries
とextra-libraries
の違いは、hs-libraries
には通常、プロファイルや並列処理などのビルドオプションの違う、複数の版があることである。複数の版は区別のために異なる接尾辞を持つ。例えば、標準プレリュードライブラリのプロファイル版はlibHSbase_p.a
という名前で、_p
がこれがプロファイル版であることを示している。接尾辞はhs-libraries
についてのみGHCによって自動で加えられ、extra-libraries
のライブラリには加えられない。
extra-libraries
に列挙されるライブラリはシステムのリンカがサポートするならどんなライブラリでも良く、動的ライブラリでも良い。(Unixでは.so
、Windowsでは.DLL
)
また、extra-libraries
はリンカのコマンド行においてhs-libraries
よりも後に置かれる。もしその逆の依存関係があり(つまり、extra-libraries
がhs-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文書のあるディレクトリ。
GHC 6.4まではエラーだったが、6.6以降はそうではない。