- ソースファイル
- ヘッダファイル
- 静的ライブラリ
- 動的ライブラリ
- プリプロセッサ
- コンパイラ
- アセンブラ
- 静的リンカ
- ローダ
- 動的リンカ
- デバッガ
高水準言語の多くは,プログラムを実行するために複数のファイルを使用する.ここではC++を例に説明を行う.
GCCがC++のファイルからプログラムを生成する場合,次のような流れで行われる.ここで,丸記号は言語処理系を,それ以外の記号はファイルの種類を表している.なお四角記号はバイナリファイルを表す.
各ファイルに関する詳細を以下に示す.
ファイル | 言語 | 説明 | ファイル拡張子の例 | 扱う者 |
---|---|---|---|---|
ソースファイル | C++とマクロ | プリプロセッサがマクロ部分が解読し,それに従った処理を施したファイルを生成する. | .cpp, .cxx, .C, .cc | プリプロセッサ |
ソースファイル | C++とコンパイラ用の命令 | コンパイラが解読しアセンブリファイルを生成する. | .ii | コンパイラ |
ヘッダファイル | C++とマクロ | ヘッダファイルもまたソースファイルである.C++では,ヘッダに宣言文を記述し,前述のソースファイルに定義文を書く.プリプロセッサはソースファイルのマクロを解読した際にソースファイルに展開する. | なし, .h | プリプロセッサ |
アセンブリファイル | アセンブリとアセンブラ用の命令 | アセンブラが解読しオブジェクトファイルを生成する. | .s | アセンブラ |
オブジェクトファイル | 機械語 | オブジェクトファイルは,プログラムファイルやライブラリを作るために使用される. | .o | 静的リンカなど |
静的ライブラリ | 静的リンカがプログラムファイルを生成するために使用する. | .a | 静的リンカ | |
動的ライブラリ | 機械語 | プログラム実行時に,動的リンカが動的ライブラリにある何かにアクセスした際にメモリ上に呼び出し,リンクする. | .so | 動的リンカ |
プログラムファイル | 機械語 | プログラムは,OSの機能のローダによってメモリ上に読み込まれ実行される. | なし, .out, .exe | ローダ |
ライブラリ
ライブラリの作成
静的ライブラリと共有ライブラリはそれぞれ次のように行う。
- 静的ライブラリ
-
いくつかのオブジェクトファイルを圧縮したもの.
-
オブジェクトファイルの生成。
user% g++ -c object1.cpp -o object1.o
-
ライブラリの生成。
user% ar rv libtarget.a object1.o object2.o
-
オブジェクトファイルの生成。
- 動的ライブラリ
- 共有ライブラリ
-
複数のプロセスで利用されるライブラリのこと。プログラム実行中にロードされる。
user% g++ -fPIC -shared source1.cpp source2.cpp -o libtarget.so
ライブラリの使用
ライブラリは次のように使用される。
user% g++ -o a.out main.cpp -ltarget -L. -I.
- -l
- 使用するライブラリを指定。
- -L
- ライブラリを検索する場所を追加
- -I
- ヘッダファイルを検索する場所を追加。
user% g++ -o a.out main.cpp -lgrandchild -lchild -lparent -L. -I.
- 検索場所(例:/libや/usr/libなど)にライブラリを移動
- 検索場所を追加。検索場所は/etc/ld.so.confで設定されているので,それを修正。
- 検索場所を追加。検索場所は環境変数でも追加可能である。
export LD_LIBRARY_PATH=.
C++では,templateやinline関数をサポートしている。templateの詳細は「ジェネリックプログラミング」,inline関数の詳細は「関数」で説明するが,それらの関数はコンパイルの際に処理を行う。それゆえ,これらをライブラリで定義してそれをインクルードして利用することはできない。templateについては,言語仕様でexportと呼ばれる指定子を付けることで別ファイルで定義できるとしているが,それらをサポートする言語処理系は多くない。inline関数については,GCCのようなコンパイラでは最適化を行う際に使用され,コードが展開されて外部ファイルから関数にアクセスできなくなる。それゆえ,外部ファイルからも使いたいような関数はinline化は避けたほうが無難である。このような問題があるため,外部ファイルでtemplateやinline関数を使用する場合,ヘッダファイルで定義される。ただし,本来ヘッダには定義を書くようなことはしないため,それに伴うエラーが発生することがある。例えばgccで-O0を指定して最適化を行わない場合,inline指定子は無視される。このような場合,通常の関数の定義と同様に扱われるため,インクルードした各ファイルでそれぞれ定義される。この時関数がstaticでない場合は,コンパイラは最終的に多重定義によるエラーを返す。
ファイルフォーマット
未完成-_-.