GCCのspecsとは
GCCには、GCC-3系まで、specsというファイルがあった。これは、GCCのデフォルトの動作を決定するファイルで、かなり重要なものだ。例えば標準のシステムインクルードパス、例えばデフォルトでリンクされるライブラリ(glibcやMinGWで言えばlibmsvcrt)等が記述されており、hello-worldを書く時にさえ必要ということになる。
このファイルはMinGWならば<mingw>/lib/gcc/mingw32/<gcc-ver>/にあり、編集することでGCCのデフォルトの挙動を変更することが可能だ。MinGWはMSYS上から使用する限りは特に問題なくとも、コマンドプロンプトなどから直接MinGWを使用する場合にはこのファイルを修正し、標準のシステムインクルードパスを記述しなければ、まともに使用できないこともある。
そもそものgccの仕組み
GCCを利用するため、普段何気なくgccと打ち込んではいるが、例えばMinGWのgcc-3.4.5ではgcc.exeが88KBしかない。誰がどう考えても、gcc.exeが全て処理しているとは思えない。
正解は、<mingw>/libexec/gcc/mingw32/<gcc-ver>/以下にcc1.exeという3MBを超える実行ファイルが存在し、こちらがgccコンパイラ本体となっている。ではなぜそんなややこしいことをするのか。それは、gccが多機能すぎることから、処理を分散させるためである。
gccは、そのコマンドだけで、プリプロセッサからアセンブラ、コンパイラ、リンカの役目まで果たしている。これを全て1つの.exeが賄うのは、不可能では無いにしても、管理上好ましくない。実際にはgccはリンカにld.exeを使用するし、コンパイラにはcc1.exeを使用する。
gcc.exeはフロントエンドでしかなく、実際に動作すべきプログラムはgcc.exeが判断して振り分けている。
specs
その際の振り分け規則や、内部的にデフォルトで使用するオプションなどを記述するのがspecsファイル、というわけだ。specsファイル相当のものは実はGCCをビルドする際にGCCのバイナリにも埋め込まれているが、この設定をオーバーライドするのがspecsファイルになる。ビルド環境と実行環境が異なっても、これにより差異を吸収することができる。
gcc.exeによって使用されているspecsの内容は、
gcc -dumpspecs
で表示される。実際にspecsを編集する場合には、この内容をリダイレクトし、上記ディレクトリに置いて編集するのがよい。
specsファイルの記述方法
specsの中身は、かなりごちゃごちゃとした表記になっていると思う。基本的なルールとしてはMakefileの書式に近く、
<対象>: <実行するコマンド>
の形式になっている。が、その内容は殆どが%{}, %()等のマクロや変数展開であり、初めて見た人間にはBrainfuckやWhitespaceのような変態言語の一種のようにも見える。例えば以下のTDM版gcc-4.4.0のdumpspecsを見てみて欲しい。
*cpp_unique_options: %{C|CC:%{!E:%eGCC does not support -C or -CC without -E}} %{!Q:-quiet} %{nostdin c*} %{C} %{CC} %{v} %{I*&F*} %{P} %I %{MD:-MD %{!o:%b.d}%{o*:%.d%*}} %{MMD:-MMD %{!o:%b.d}%{o*:%.d%*}} %{M} %{MM} %{MF*} %{MG} %{MP} %{MQ*} %{MT*} %{!E:%{!M:%{! MM:%{!MT:%{!MQ:%{MD|MMD:%{o*:-MQ %*}}}}}}} %{remap} %{g3|ggdb3|gstabs3|gcoff3|gx coff3|gvms3:-dD} %{H} %C %{D*&U*&A*} %{i*} %Z %i %{fmudflap:-D_MUDFLAP -include mf-runtime.h} %{fmudflapth:-D_MUDFLAP -D_MUDFLAPTH -include mf-runtime.h} %{E|M| MM:%W{o*}}
最初のエラー的メッセージと最後のマクロ定義等のあたりは分からないでもないが、なんとなーく、気分的には、変態言語のFalseに近いようにも感じる。
実用・specsファイル
正直上記の内容を解説する気にはなれないので、ここでは簡単な実用例を示す。MinGWをC:\msys\mingw-3にインストールしているとする。
システムインクルードパスの追加
もっともよく使う例。specsファイル中で
*cpp: %{posix:-D_POSIX_SOURCE} %{mthreads:-D_MT}
という箇所を探し出し、プリプロセッサオプションの-Iを加えればよい。
*cpp: %{posix:-D_POSIX_SOURCE} %{mthreads:-D_MT} -I C:/msys/mingw-3/include
この際、Windows上での絶対パス表記にしているのがポイントだ。MinGWは元々MSYSに依存しないので、MSYS依存のパス表記は使わない方がよい。
システムライブラリパスの追加
specsファイル中で
*link_libgcc: %D
という箇所を探し出し、リンカオプションの-Lを加えればよい。
*link_libgcc: %D -L C:/msys/mingw-3/lib
その他
もう少し凝った解説は、英文だがMinGWのサイトにHOWTO Use the GCC specs fileという記事がある。また、当然だがGCCのオンラインマニュアルにもSpecifying subprocesses and the switches to pass to themという解説がある。
GCC4でのspecs
この記事の冒頭では何気なく、「GCC-3系まで」と書いた。実は、GCC-4系ではspecsファイルは標準で含まれない。細かな意図などは調査していないが、とにかくGCC-4系ではspecsファイルは通常、不要になった。ただし、特別な目的があるなら、ただ書いて置けば使用されるようになっている。よって、GCC-4.4.0のマニュアルにもspecsファイルの解説は存在する。
最終更新時間:2009年06月30日 18時55分40秒