この節では、プログラムのコンパイルとリンクについていくつかの側面から説明します。次の例では、CC を使って 3 つのソースファイルをコンパイルし、オブジェクトファイルをリンクして prgrm という実行可能ファイルを作成します。
example% CC file1.cc file2.cc file3.cc -o prgrm |
前の例では、コンパイラがオブジェクトファイル (file1.o、file2.o、file3.o)を自動的に生成し、次にシステムリンカーを起動してファイル prgrm の実行可能プログラムを作成します。
コンパイル後も、オブジェクトファイル (file1.o、file2.o、file3.o) はそのまま残ります。この規則のおかげで、ファイルの再リンクと再コンパイルを簡単に行えます。
ソースファイルが 1 つだけであるプログラムに対してコンパイルとリンクを同時に行なった場合は、対応する .o ファイルが自動的に削除されます。複数のソースファイルをコンパイルする場合を除いて、すべての .o ファイルを残すためにはコンパイルとリンクを別々に行なってください。
コンパイルが失敗すると、エラーごとにメッセージが返されます。エラーがあったソースファイルの .o ファイルは生成されず、実行可能プログラムも作成されません。
コンパイルとリンクは別々に行うことができます。-c オプションを指定すると、ソースファイルがコンパイルされて .o オブジェクトファイルが生成されますが、実行可能ファイルは作成されません。 -c オプションを指定しないと、コンパイラはリンカーを起動します。コンパイルとリンクを分離すれば、1 つのファイルを修正するためにすべてのファイルを再コンパイルする必要はありません。次の例では、最初の手順で 1 つのファイルをコンパイルし、次の手順でそれをほかのファイルとリンクします。
example% CC -c file1.cc 新しいオブジェクトファイルを作成する example% CC -o prgrm file1.o file2.o file3.o 実行可能ファイルを作成する |
リンク時には (2 行目)、完全なプログラムを作成するのに必要なすべてのオブジェクトファイルを必ず 指定してください。オブジェクトファイルが足りないと、リンクは「undefined external reference (未定義の外部参照がある)」エラーで、ルーチンがないために失敗します。
コンパイルとリンクを別々に実行する場合で、次のコンパイラオプションを使用する場合は、コンパイルとリンクの整合性を保つことが非常に重要です。
-B
-compat
-fast
-g
-g0
-library
-misalign
-mt
-p
-xa
-xarch
-xcg92 および -xcg89
-xipo
-xpagesize
-xpg
-xprofile
-xtarget
これらのオプションのいずれかを使用してサブプログラムをコンパイルした場合は、リンクでも同じオプションを使用してください。
-library、-fast、-xtarget、-xarch オプションの場合、コンパイルとリンクを同時に行えば渡されるはずのリンカーオプションも含める必要があります。
-p、-xpg、-xprofile オプションの場合、ある段階ではオプションを指定して別の段階では指定しないと、プログラムの正しさには影響はありませんが、プロファイル処理ができなくなります。
-g、-g0 オプションの場合、ある段階ではオプションを指定して別の段階では指定しないと、プログラムの正しさには影響はありませんが、プログラムを正しくデバッグできなくなります。これらのオプションでコンパイルされず、-g または -g0 でリンクされるいずれのモジュールも、デバッグには使用できません。-g または -g0 オプション付きの main 関数を含むモジュールをコンパイルすることは、通常はデバッグに必要になります。
次の例では、-xcg92 コンパイラオプションを使用してプログラムをコンパイルしています。このオプションは -xtarget=ss1000 用のマクロであり、-xarch=v8 -xchip=super -xcache=16/64/4:1024/64/1 と展開されます。
example% CC -c -xcg92 sbr.cc example% CC -c -xcg92 smain.cc example% CC -xcg92 sbr.o smain.o |
プログラムがテンプレートを使用する場合は、リンク時にその中のいくつかがインスタンス化される可能性があります。 その場合、インスタンス化されたテンプレートは最終行 (リンク行) のコマンド行オプションを使用してコンパイルされます。
64 ビットオブジェクトのコンパイル、リンク、および実行は、V9 SPARC の Solaris 8 以降のオペレーティングシステムで 64 ビットカーネルが動作しているものだけがサポートされています。64 ビットのコンパイルは、-xarch=v9 オプション、-xarch=v9a オプションまたは、-xarch=v9b オプションで指定します。
-verbose オプションを使用すると、呼び出される名前やバージョン番号および各コンパイル段階のコマンド行など、プログラムのコンパイル中に役立つ情報を表示できます。
コマンド行に指定された引数をコンパイラが認識できない場合には、それらはリンカーオプション、オブジェクトプログラムファイル名、ライブラリ名のいずれかとみなされます。
基本的には次のように区別されます。
認識できない非オプション (先頭にダッシュかプラス符号 (+) が付いていないもの)には、警告が生成されません。ただし、リンカーへの引き渡しは行われます。リンカーも認識できないと、リンカーからエラーメッセージが生成されます。
次の例で、 -bit は CC によって認識されないため、リンカー (ld) に渡されます。リンカーはこれを解釈しようとします。単一文字の ld オプションは連続して指定できるので、リンカーは -bit を -b、-i、-t とみなします。これらはすべて有効な ld オプションです。しかし、これは本来の意図とは異なります。
example% CC -bit move.cc <- -bit は CC オプションとして認識されない CC: 警告: ld が起動される場合は、オプション -bit は ld に渡されます。 それ以外は無視されます。 |
次の例では、CC オプション -fast を指定しようとしましたが、先頭のダッシュ (-) を入力しませんでした。コンパイラはこの引数もリンカーに渡します。リンカーはこれをファイル名とみなします。
example% CC fast move.cc <- ユーザーは -fast と入力したつもりだった move.CC: ld: 重大なエラー: ファイル fast: ファイルをオープンできません: ファイルも ディレクトリもありません。 ld: 重大なエラー: ファイル処理エラー。a.out に書き込まれる出力はありません。 |
C++ コンパイラパッケージは、フロントエンド (CC コマンド本体)、オプティマイザ (最適化)、コードジェネレータ (コード生成)、アセンブラ、テンプレートのプリリンカー (リンクの前処理をするプログラム)、リンクエディタから構成されています。コマンド行オプションでほかの指定を行わないかぎり、CC コマンドはこれらの構成要素をそれぞれ起動します。
これらの構成要素はいずれもエラーを生成する可能性があり、構成要素はそれぞれ異なる処理を行うため、エラーを生成した構成要素を識別することがエラーの解決に役立つことがあります。 それには、-v オプションと -dryrun オプションを使用します。
次の表に示すように、コンパイラの構成要素への入力ファイルには異なるファイル名接尾辞が付いています。どのようなコンパイルを行うかは、この接尾辞で決まります。ファイル名接尾辞の意味については、表 2–1 を参照してください。
表 2–2 C++ コンパイルシステムの構成要素
構成要素 |
内容の説明 |
使用時の注意 |
---|---|---|
フロントエンド (コンパイラプリプロセッサ (前処理系) とコンパイラ) | ||
SPARC: コードオプティマイザ |
-xO[2-5]、-fast |
|
x86: 中間言語トランスレータ |
-xO[2-5]、-fast |
|
SPARC: アセンブリ言語テンプレートのインライン展開 |
.il ファイルを指定 |
|
x86: 内部手続きアナライザ |
-xO4、-xO5、あるいは -fast 付きの -xcrossfile=1 |
|
アセンブラ | ||
SPARC: コード生成、インライン機能、アセンブラ |
|
|
ube |
x86: コードジェネレータ |
-xO[2-5]、-fast |
テンプレートのプリリンカー | ||
従来のリンクエディタ |