10.1 Cプログラミングツールの概要

  2.コンパイラの構成
 gccコンパイラシステムはプリプロセッサ、コンパイラ、アセンブラ、およびリンカーから構成されます。gcc コマンドは、コマンド行オプションで他の指定をしない限り、この 4つの構成要素をそれぞれ自動的に起動していきます。

 次の図にgccコンパイラシステムの構成を示します。

gccコンパイラシステムの構成のイメージ

 実際に、前節でビルドしたhelloが、どのような処理プログラムと中間ファイルによって生成されていくかを見てみましょう。以下の例では、RedHat Linux上のegcs(gcc)コンパイラシステムに、冗長表示オプション -v を与えて起動し、hello.cをビルドしてa.outを生成してみました。
# gcc -v -O2 hello.c -o hello

Reading specs from /usr/lib/gcc-lib/i386-redhat-linux/egcs-2.91.66/specs
gcc version egcs-2.91.66 19990314/Linux (egcs-1.1.2 release)
/usr/lib/gcc-lib/i386-redhat-linux/egcs-2.91.66/cpp -lang-c -v -undef -D__GNUC__=2 -D__GNUC_MINOR__=91 -D__ELF__ -Dunix -Di386 -D__i386__ -Dlinux -D__ELF__ -D__unix__ -D__i386__ -D__i386__ -D__linux__ -D__unix -D__i386 -D__linux -Asystem(posix) -D__OPTIMIZE__ -Asystem(unix) -Acpu(i386) -Amachine(i386) -Di386 -D__i386
-D__i386__ -D__tune_i386__ hello.c /tmp/cceHoRL4.i
GNU CPP version egcs-2.91.66 19990314/Linux (egcs-1.1.2 release) (i386 Linux/ELF)
#include "..." search starts here:
#include <...> search starts here:
/usr/local/include
/usr/i386-redhat-linux/include
/usr/lib/gcc-lib/i386-redhat-linux/egcs-2.91.66/include
/usr/include
End of search list.
/usr/lib/gcc-lib/i386-redhat-linux/egcs-2.91.66/cc1 /tmp/cceHoRL4.i -quiet -dumpbase hello.c -O2 -version -o /tmp/ccSGwO81.s
GNU C version egcs-2.91.66 19990314/Linux (egcs-1.1.2 release) (i386-redhat-linux) compiled by GNU C version egcs-2.91.66 19990314/Linux (egcs-1.1.2 release).
as -V -Qy -o /tmp/ccy3z1b5.o /tmp/ccSGwO81.s
GNU assembler version 2.10.90 (i386-laser5-linux) using BFD version 2.10.0.18
/usr/lib/gcc-lib/i386-redhat-linux/egcs-2.91.66/collect2 -m elf_i386 -dynamic-linker /lib/ld-linux.so.2 -o hello /usr/lib/crt1.o /usr/lib/crti.o /usr/lib/gcc-lib/i386-redhat-linux/egcs-2.91.66/crtbegin.o -L/usr/lib/gcc-lib/i386-redhat-linux/egcs-2.91.66 -L/usr/i386-redhat-linux/lib /tmp/ccy3z1b5.o -lgcc -lc -lgcc /usr/lib/gcc-lib/i386-redhat-linux/egcs-2.91.66/crtend.o /usr/lib/crtn.o
 何やら難しそうでかなり込み入っていますが、注意深く見ると、cpp→cc1→as→ld(実際はcollect2)と順に実行されていることがわかります。

 途中の段階の中間ファイル(プリプロセッサ処理済みコード、アセンブリコード、オブジェクトコードなど)は、/tmp/cceHoRL4.i, /tmp/ccSGwO81.s, /tmp/ccy3z1b5.oのような一時的なファイル名がgccによって付けられ、一時ディレクトリ上で生成されていることがわかります。

 最適化オプション -O2 を与えているので、コード生成時(cc1)にOptimizeするための指示(-O2)を内部で引き継いで出していることも分かります。

 最終的なバイナリ(実行可能モジュール)は、一般的なldリンカのかわりにcollect2リンカを内部から呼び出し、Dynamic LinkなインテルCPU(i386)互換のELF形式バイナリを生成していることもわかります。

 次章から、これらの各処理プログラムの詳細について説明していきます。