コンパイルシステムの段階のうち一つ一つについて、ghcに備え付けられたプログラムの代わりに別のものを使うように指定することができる。例えば、別のアセンブラを使ってみたいかもしれない。以下のオプションで、指定されたコンパイル段階で使われる外部プログラムを変更することができる。
-pgmL
cmd
文芸形式の前処理器としてcmd
を使う。
-pgmP
cmd
Cプリプロセッサとしてcmd
を使う(-cpp
が指定されているときのみ)
-pgmc
cmd
Cコンパイラとしてcmd
を使う。
-pgmlo
cmd
LLVM最適化器としてcmd
を使う。
-pgmlc
cmd
LLVMコンパイラとしてcmd
を使う。
-pgmm
cmd
manglerとしてcmd
を使う。
-pgms
cmd
splitterとしてcmd
を使う。
-pgma
cmd
アセンブラとしてcmd
を使う。
-pgml
cmd
リンカとしてcmd
を使う。
-pgmdll
cmd
DLL生成器としてcmd
を使う。
-pgmF
cmd
前処理器としてcmd
を使う。(-F
が指定されているときのみ)
-pgmwindres
cmd
Windowsにおいて、マニフェストを埋め込むためのプログラムとしてcmd
を使う。通常、これは、GHCのインストールで供給されるwindres
プログラムである。4.11.6. リンクに影響するオプションの-fno-embed-manifest
参照。
以下のフラグを使って、特定のコンパイル段階に指定されたオプションを強制的に使わせることができる。
-optL
option
option
を文芸形式の前処理器に渡す。
-optP
option
option
をCPPに渡す。(-cpp
が有効なときのみ効果がある)
-optF
option
option
を用意した前処理器に渡す。(4.11.4. Haskell前処理器に影響するオプションを見よ)
-optc
option
option
をCコンパイラに渡す。
-optlo
option
option
をLLVM最適化器に渡す。
-optlc
option
option
をLLVMコンパイラに渡す。
-optm
option
option
をmanglerに渡す。
-opta
option
option
をアセンブラに渡す。
-optl
option
option
をリンカに渡す。
-optdll
option
option
をDLL生成器に渡す。
-optwindres
option
Windowsにおいて、マニフェストを埋め込む際、option
をwindres
に渡す。4.11.6. リンクに影響するオプションの-fno-embed-manifest
を見よ。
つまり、例えば、-Ewurble
オプションをアセンブラに渡すには、-opta-Ewurble
とすれば良い。(Eの前のハイフンは必須である)
GHCはそれ自身Haskellプログラムなので、GHCのランタイムシステムに直接オプションを渡す必要があるなら、それらを+RTS ... -RTS
で囲むことができる。(4.16. コンパイル済みプログラムを実行するを見よ)
-cpp
HaskellコードがCプリプロセッサcppに通されるのは、-cpp
オプションが与えられたときのみである。大量の条件コンパイルのある大きなシステムを構築しているのでない限り、これが必要になることはないはずである。
-D
symbol
[=value
]
通常の方法でマクロsymbol
を定義する。注意: これはCを介してコンパイルするときにCコンパイラに渡される-D
マクロには影響しない。それには、-optc-Dfoo
というハックを使うこと。(4.11.2. 特定の段階にオプションを強制するを見よ)
-U
symbol
通常の方法でマクロsymbol
を未定義にする。
-I
dir
#include
ファイルを探すディレクトリを、通常のCでの方法で指定する。
Haskellソースコード(.hs
または.lhs
ファイル)をプリプロセスするとき、GHCドライバはいくつかのマクロを事前定義する。
定義されるシンボルは以下に示されている。あなたのシステムにインストールされたGHCでどのシンボルが定義されているかを確かめるには、以下の小技が有用である。
$ ghc -E -optP-dM -cpp foo.hs $ cat foo.hspp
(foo.hs
というファイルが必要だが、実際に使われることはない)
__GLASGOW_HASKELL__
GHCのバージョン
では、x
.y
.z
__GLASGOW_HASKELL__
の値は定数xyy
である。(y
が一桁なら、前に0が追加される。例えばGHCのバージョン6.2では__GLASGOW_HASKELL__==602
である)。詳しくは1.4. GHCのバージョン番号付け規則を参照。
運が良ければ、__GLASGOW_HASKELL__
は、C風プリプロセスをサポートする他の処理系では定義されていないだろう。
(参考までに、他のシステムで比較に使える名前は、Hugsは__HUGS__
、nhc98は__NHC__
、hbcは__HBC__
である。)
注意。このマクロはHaskellソースとCソースの両方のプリプロセス時に有効である。これには、Haskellモジュールから生成されたCソースも含む。(つまり、.hs
、.lhs
、.c
、.hc
の各ファイルである)
__PARALLEL_HASKELL__
-parallel
が使われているときのみ定義される。このシンボルはHaskell(入力)とC(GHCの出力)をプリプロセスするときに定義される。
os
_HOST_OS=1
この定義を使ってOSに基づく条件コンパイルをすることができる。ただし、os
は使われているOSの名前である。(例えばlinux
、Windowsではmingw32
、solaris
など)
arch
_HOST_ARCH=1
この定義を使ってホストのアーキテクチャに基づく条件コンパイルをすることができる。ただし、arch
は使われているアーキテクチャの名前である。(例えばi386
、x86_64
、powerpc
、sparc
など)
警告を少々。-cpp
は「文字列間隙」との相性があまりよくない。言い替えると、次のような文字列間隙は-cpp
の使用下ではうまく動かない。
strmod = "\ \ p \ \ "
/usr/bin/cpp
がバックスラッシュと改行を消し去るからである。
一方、行末にスペースを加えれば、cpp(少なくともGNU cpp、他のcppもそうかもしれない)はバックスラッシュと空白の対をそのまま残し、文字列間隙は期待どおりに働く。
-F
Haskellソースファイルは、-F
オプションが与えられたときのみ選んだ前処理器に通される。
選んだ前処理器をコンパイル時に走らせるのは、場合によっては適切で、便利である。-F
オプションを使うと、前処理器はGHCの総合的なコンパイルパイプラインの一部として走る。このため、Haskell前処理器を別に走らせるのと比べると、解釈実行モードでもうまく動いたり、GHCの再コンパイル検査器の恩恵に浴することができるという点で有利である。
前処理器が走るのはHaskellコンパイラがHaskell入力を処理する直前、ただし文芸的マーク付けが落とされ、(場合によっては)Cプリプロセッサが入力を洗浄した後である。
-pgmF
を使って、前処理器として使うプログラムを選ぶことができる。起動されるとき、cmd
cmd
前処理器はコマンド行から最低三つの引数を渡される。最初の引数は元のソースファイルの名前であり、二番目は入力の置かれているファイルの名前であり、三番目はcmd
が出力を書き込むべきファイルの名前である。
前処理器への追加の引数は-optF
オプションで渡すことができる。これらは、コマンド行において、三つの標準的な入出力引数の後に置かれる。
前処理器の例として、ソースファイルを、GHCが期待するエンコーディングに変換するというのがあげられる。つまり、以下のようなスクリプトconvert.sh
を作るのだ。
#!/bin/sh ( echo "{-# LINE 1 \"$2\" #-}" ; iconv -f l1 -t utf-8 $2 ) > $3
そして、GHCに-F -pgmF convert.sh
を渡す。-f l1
オプションはあなたのLatin-1ファイル(引数$2
に与えられる)を変換するように指示し、「-t uft-8」オプションはUTF-8でエンコードされたファイルを返すように指示している。結果は引数$3
にリダイレクトされる。echo "{-# LINE 1 \"$2\" #-}"
は、エラーがあったとき、その位置を元のソースファイルの物として報告させるようにするためのものである。
-fasm
Cを介するのではなく、GHCのネイティブコード生成器を使ってコンパイルする。こうするとコンパイルは速くなるが(最大で二倍ほど)、生成されたコードはCを介したものよりも多少遅くなるかもしれない。-fasm
はデフォルトである。
-fvia-C
ネイティブコード生成器を使わず、Cを介してコンパイルする。GHCにネイティブコード生成器のないアーキテクチャでは、これがデフォルトである。
-fllvm
ネイティブコード生成器を使わず、LLVMを介してコンパイルする。これは一般的に、ネイティブコード生成器に比べてやや長いコンパイル時間が掛かるが、Cを介してコンパイルするよりは高速である。生成されたコードは一般的に、他の二つのコード生成器と同等か、それより速い。LLVMを介したコンパイルには、LLVMのバージョン2.7以降がパスにあることが必要である。
-fno-code
コード生成(と、それ以降の段階全て)を完全に省略する。コンパイルの中間段階の出力を見たいだけのときには使い道があるかもしれない。
-fobject-code
オブジェクトコードを生成する。GHCi以外ではこれがデフォルトであり、GHCiでは、バイトコードよりもオブジェクトコードを優先して生成するようにすることができる。
-fbyte-code
オブジェクトコードの代わりにバイトコードを生成する。GHCiではこれがデフォルトである。現在、バイトコードは対話的インタプリタでのみ使え、ディスクに保存することができない。このオブションが役に立つのは、-fobject-code
の効果を反転させるときだけである。
-fPIC
位置独立なコード(共有ライブラリや共有バイナリに置けるコード)を生成する。これは現在、Linux x86とx86-64において、ネイティブコード生成器(-fasm)を使っているときに動作する。Windowsでは位置独立コードは決して使われないので、このプラットフォームではこのフラグは何もしない。
-dynamic
コード生成に際して、別パッケージからインポートされた実体は別の共有ライブラリやバイナリにあると仮定する。
このオプションをリンク時に使うと、GHCは共有ライブラリをリンクするのに注意。
GHCはあなたのコードをいろいろなライブラリとリンクしなければならない。これには、ユーザ供給のもの、GHC供給のもの、システム供給のもの(例えば-lm
数学ライブラリ)が含まれ得る。
-l
lib
lib
ライブラリをリンクする。Unixシステムでは、これはライブラリディレクトリパスのどこかにあるlib
またはlib
.alib
というファイルに置かれる。lib
.so
大部分のUNIXリンカは悲しい状態にあって、こういうオプションの順序に意味がある。ライブラリfoo
がライブラリbar
を必要とするなら、一般に、コマンド行中で、-l
foo
は-l
bar
よりも前に来なければならない。
外部ライブラリを使うときに心に留めた方がいい罠がもう一つある。もしライブラリにmain()
関数があるなら、これはGHCのmain()
関数よりも優先して使われるということである。(例えば、libf2c
やlibl
には独自のmain()
がある)。これは、GHCのmain()
がHSrts
ライブラリ由来であり、通常コマンド行中で他の全てのライブラリよりも後に置かれるからである。GHCのmain
が他の外部ライブラリ由来のmain()
よりも優先して使われるようにするには、単に-lHSrts
オプションをコマンド行で他のライブラリよりも前に置けば良い。
-c
リンクを省略する。––make
と併用して、プログラムにMain
モジュールがあったときに行われる自動リンクを避けることができる。
-package
name
Haskell「パッケージ」(4.9.
パッケージ
を見よ)を使っているなら、関係する-package
をリンク時にも忘れずに指定する必要がある。こうすることで、必要なライブラリがプログラムにリンクされる。-package
を忘れると何ページにもわたるリンクエラーが起こるだろう。
-framework
name
Darwin/MacOS Xのみ。フレームワークname
をリンクする。このオプションはAppleのリンカの-framework
オプションに相当する。フレームワークとパッケージは別々のものだということに注意してほしい。フレームワークはHaskellのコードを含まない。むしろ、これは共有ライブラリをパッケージ化するApple流のやりかたである。例えば、Appleの「Carbon」APIにリンクするには、-framework Carbon
を使うことができる。
-L
dir
ユーザ供給のライブラリを探す場所。ディレクトリdir
をライブラリディレクトリパスの先頭に加える。
-framework-path
dir
Darwin/MacOS Xのみ。ディレクトリdir
をフレームワークディレクトリパスの先頭に加える。これはAppleのリンカの-F
オプションに相当する。(GHCでは-F
は別の要素に使用済みである)
-split-objs
通常生成されるような単一のオブジェクトファイルを分割して、モジュール中のHaskell関数や型一つずつにオブジェクトファイルを生成するようにリンカに指示する。これはライブラリに対してのみ意味を持つ。この場合、そのライブラリにリンクされる実行ファイルは、必要なオブジェクトファイルとのみリンクされるので、よりファイルサイズが小さくなる。しかし、全てのセクションを別々に組み立てるのは高価なので、これはふつうにコンパイルするよりも遅い。我々はこの機能をGHCのライブラリをビルドするのに使っている。(警告: 自分が何をしているか分かっているのでない限り、このオプションを使わないように!)
-static
可能なら共有Haskellライブラリを避けるようにリンカに指示する。これはデフォルトである。
-dynamic
このオプションは、Haskellの共有ライブラリをリンクするようにGHCに指示する。このフラグは依存するライブラリの選択に影響するだけであり、現在作っているものの形式には影響しない(-sharedを見よ)。作り方に関しては4.12. 共有ライブラリを使うを見よ。
このオプションはコード生成にも影響を与えることに注意。(上記参照)
-shared
このフラグが与えられると、実行可能形式を作る代わりにGHCは共有オブジェクトを生み出す。対象のOSによって、これはELF DSOだったり、Windows DLLだったり、Mac OSのdylibだったりする。GHCはこの統一フラグのもとにOSの詳細を隠す。
生成される共有オブジェクトが-package
オプションで与えられたHaskellのパッケージライブラリに静的にリンクされるか動的にリンクされるかは、-dynamic
/-static
フラグによって制御される。Haskell以外のライブラリはそのシステムでgccが通常にリンクするのと同じようにリンクされる。例えば、大部分のELFシステムでは、動的ライブラリが見つかった場合はそれが使われる。
共有オブジェクトへとリンクされるオブジェクトファイルは-fPIC
でコンパイルされなければならない。4.11.5. コード生成に影響するオプションを見よ。
Haskellパッケージのために共有オブジェクトを作る場合、そのパッケージにリンクされるときにGHCがその共有オブジェクトを認識できるように、その共有オブジェクトには正しい名前が付けられねばならない。共有オブジェクトの名前manglingを見よ。
-dynload
このフラグは、実行時に共有ライブラリを探すときのいくつかの方式から一つを選ぶものである。それぞれの方式については4.12.4. 実行時における共有ライブラリの発見を見よ。
-main-is thing
Haskellの通常の規則では、プログラムはMain
のmain
関数を供給する必要がある。テスト時には、どの関数が「主要な(main)」ものであるかを変えられると便利であり、これを可能にするのが-main-is
フラグである。thing
は次のうちいずれかである。
小文字で始まる識別子foo
。GHCはMain.foo
がmain関数だとみなす。
モジュール名A
。GHCはA.main
がmain関数だとみなす。
修飾名A.foo
。GHCはA.foo
がmain関数だとみなす。
厳密に言うと、-main-is
はそもそもリンク時フラグではない。リンク段階ではなんの効果も及ぼさない。このフラグは、指定されたmain関数のあるモジュール(例えば上記のうち後ろ二つではA
である)をコンパイルするときに指定する必要がある。他のモジュールには影響がないので、ghc --make
に与えても安全である。ただし、main関数の指定を変更したとき、どのモジュールにもそれ以外に変更がないなら、新旧両方の「main」のモジュールを強制的に再コンパイルさせないといけない。ghc
はこれらが両方とも再コンパイルを要していると判断できるほど賢くないのである。再コンパイルを強制するには、オブジェクトファイルを削除しても良いし、-fforce-recomp
フラグを使っても良い。
-no-hs-main
ghcでコンパイルされたコードを別の(非Haskellの)プログラムの一部として使いたいときは、RTSはmain()
の定義をリンク時に供給せず、あなたが供給せねばならない。このことをリンク時にコンパイラに伝えるのが-no-hs-main
である。8.2.1.1. 自分で用意したmain()
を使うも見よ。
リンカにわたされるコマンド行はかなり複雑なので、複数言語のアプリケーションの最終リンクにはghcを使うのが良いだろう。ただしこれは必須ではない。ドライバがどんなオプションをリンカに渡しているかを見るには一度-v
付きでリンクしてみるだけで良い。
-no-hs-main
フラグは、--make
モードにおいて、HaskellのMain
モジュールがないときでもコンパイラにリンクを行わせるために使うこともできる。(通常、Main
がないときはコンパイラはリンクを試みない)
-debug
プログラムをデバッグ版のランタイムシステムにリンクする。デバッグランタイムは大量のアサーションと正気度チェックを有効にし、実行時にデバッグ出力を生成するためのオプションを提供する。(一覧を見るにはプログラムを+RTS -?
付きで実行せよ)
-threaded
プログラムを「スレッド化された」版のランタイムシステムにリンクする。スレッド化ランタイムシステムは複数のOSスレッドを管理するのでこう呼ばれる。これに対して、デフォルトのランタイムシステムは純粋に単一スレッドである。
並行性を使うのに-threaded
は必要ない。単一スレッドのランタイムはHaskellスレッド間の並行性をちゃんと扱う。
スレッド化ランタイムシステムには次のような利点がある。
マルチプロセッサまたはマルチコアの機械における並列性。4.14. SMP並列計算を使うを見よ。
他のHaskellスレッドをブロックせずに他言語関数を呼び出したり、foreign exportされたHaskellの関数を複数のOSスレッドから呼び出す能力。8.2.4. マルチスレッドとFFIを見よ。
-eventlog
プログラムを"eventlog"版のランタイムシステムにリンクする。この方法でリンクされたプログラムは、実行時にイベント(スレッドの開始/停止など)の追跡情報を
というバイナリファイルに生成することができる。このファイルは後でいろいろなツールによって解釈できる。さらなる情報は4.16.6. 追跡情報を得るを見よ。
program
.eventlog
-eventlog
は-threaded
と併用することができる。また-debug
によって自動的に有効になる。
-rtsopts
このオプションは、コマンド行やGHCRTS
で与えられるRTS制御オプションの処理に影響する。可能なのは以下の三つ。
-rtsopts=none
すべてのRTSオプションの処理を無効にする。+RTS
がコマンド行内のいずれかの位置に現れた場合、プログラムはエラーメッセージを出力して異常終了する。GHCRTS
環境変数が設定されている場合、プログラムは警告メッセージを出力し、GHCRTS
を無視し、通常通りに実行される。
-rtsopts=some
[これがデフォルトの設定である]「安全」なRTSオプション(現在-?
と--info
のみ)だけを有効にする。これら以外のRTSオプションがコマンド行やGHCRTS
で使われていた場合、プログラムはエラーメッセージを出力して異常終了する。
-rtsopts=all
, or
just -rtsopts
コマンド行とGHCRTS
の両方で、全てのRTSオプションの処理を有効にする。
GHC 6.12.3以前では、全てのRTSオプションを処理するのがデフォルトだった。しかし、RTSオプションは任意のファイルに対するログデータの書き込みを、実行プログラムのコンテキストで許すので、セキュリティ上の問題が発生する余地がある。このため、GHC 7.0.1以降のデフォルトは-rtsopts=some
である。
-with-rtsopts
このオプションは、RTSオプションのデフォルトをリンク時に設定できるようにする。例えば、-with-rtsopts="-H128m"
はヒープのデフォルトの大きさを128MBにする。このプログラムのデフォルトのヒープサイズは、ユーザによって上書きされない限り、常にこれになる。(-rtsopts
オプションの設定によっては、ユーザが実行時にRTSオプションを設定することができないかもしれない。その場合には-with-rtsopts
がそれを設定する唯一の方法である。)
-fno-gen-manifest
Windowsでは、バイナリをリンクする際、GHCは通常マニフェストファイルを生成する。マニフェストは
というファイルに置かれる。ここで、prog
.exe.manifestprog.exe
が実行ファイルの名前である。現在、このマニフェストファイルの役割は唯一つである。Windows Vistaにおける「インストーラの検知」を無効にするのだ。(これは、ある種の名前(例えば、「install」「setup」「patch」を含む名前)の実行ファイルの権限を昇格させようとするものだ)。マニフェストファイルを使ってインストーラ検知を無効にしないと、Windowsがインストーラだと見なした実行ファイルを実行しようと試みた場合、起動者にパーミッションエラーのコードが返されることになる。この結果、起動者によって、ユーザに昇格の許可を求めるダイアログボックスを表示したり、単に権限不足のエラーになるかもしれない。
インストーラ検知は、セキュリティコントロールパネルを使って大域的に無効にすることもできるが、GHCはデフォルトで、ユーザがインストーラ検知を無効にしてあることに依存しないバイナリを生成する。
-fno-gen-manifest
はこのマニフェストファイルの生成を無効にする。こうすることの一つの理由としては、例えば自分でマニフェストファイルを用意した場合というのがあるだろう。
将来的には、GHCはマニフェストファイルをもっと多くのことに使うようになるかもしれない。依存しているDLLの位置を指定するなど。
-fno-gen-manifest
は-fno-embed-manifest
も有効にする。下記参照。
-fno-embed-manifest
WindowsにおいてGHCがバイナリのリンク時に生成するマニフェストファイルは、デフォルトで、実行ファイル自体に埋め込まれる。これによって、バイナリを、マニフェストファイルを同時に供給する必要なしで配布することができる。この埋め込みは、windres
を走らせることによって為される。マニフェストを埋め込むためにGHCが何をしているが正確に知るには、-v
フラグを使うとよい。このために、GHCのインストールにはwindres
のコピーが付属している。
-pgmwindres
(4.11.1. それぞれの段階で使われるプログラムを変更する)と-optwindres
(4.11.2. 特定の段階にオプションを強制する)も参照。
-dylib-install-name path
Darwin/MacOS Xでは、動的ライブラリにはビルド時に「install name」が付加される。これは、そのライブラリの最終的なインストールパスである。後にこのライブラリをリンクするライブラリや実行ファイルは、このライブラリを実行時に探索する場所としてこのパスを選ぶ。デフォルトでは、ghcはライブラリがビルドされた場所をinstall nameとして設定する。このオプションは、指定したパスでそれを上書きすることを可能にする。(Appleのリンカに-install_name
を渡すものである)。他のプラットフォームでは無視される。