9.プリプロセッサとメイクファイル

9-5. ヘッダーとリンク

分割コンパイルとヘッダーファイル関係を説明します。

今度はソースファイルをもう一つ増やして、file3.cそのヘッダーのfile3.hを
追加します。そして依存関係は次のようになります。

   ┌────┐┌────┐
   │file2.h ││file3.h │
   └────┘└────┘
    /  \  /  \
┌────┐┌────┐┌────┐
│file1.c ││file2.c ││file3.c │
└────┘└────┘└────┘

つまり、filr3.c で定義した関数はfile2.cで利用ということにします。
まずは3つのソースファイルをコンパイルします。

>lcc -c file1.c file2.c file3.c

これで3つオブジェクトファイル

file1.obj file2.obj file3.obj

が生成されます。(gcc の方もそれぞれ読み替えてください)
それで、実行ファイルを作る時

>lcc file1.obj file2.obj file3.obj

とすれば file1.exe ができます。(gcc では a.out)
そしてこの時、file1.c を修正したとします。
その時は、file1.c だけ再コンパイルすれば済みます。

>lcc -c file1.c
>lcc file1.obj file2.obj file3.obj

もちろん lcc はリンカも兼ねているので。

>lcc file1.c file2.obj file3.obj

としてもうまく行きます。
file2.c file3.c についても変更したら変更したファイルのみ再コンパイルするだけで済みます。

これこそ分割コンパイルの利点になります。
まず、修正があっても部分的に再コンパイルすればいいので
コンパイルにかかる時間が最小限で済みます。

そしてヘッダーファイルを作っているとコンパイル済みのライブラリーの場合、利用したい時にヘッダーファイルをインクルードすればよいことです。
そうすれば、ライブラリーがコンパイル済みでソース内容がわからなくてもヘッダーファイルによりどんな関数があるのか、どのように呼び出すのかが分かります。

次に、ヘッダーファイルを書き換えた場合はどうなるでしょう。
この場合、そのヘッダーファイルをインクルードしているファイル全てを再コンパイルしなくてはなりません。
(ソースに挿入されるわけですから当然ですね)
file2.h を変更した時は file1.c と file2.c
file3.h を変更した時は file2.c と file3.c
を再コンパイルしなければなりません。

こうやって、ソースファイルを分担する事により、複数のプログラマーで開発したり、再利用したりしやすくなります。

ただ、このまま、ソースファイルが100個、200個になるとリンクするとき

>lcc file1.obj file2.obj file3.obj file4.obj file5.obj file6.obj …

とてもじゃないけどやってられないです。
ハッキリ言って改変するたびこんなコマンドを打つのは面倒な上にタイプミスによるエラー続発の温床になります。

こんなことならコンパイル・リンクのためのバッチファイルがあればいいのに・・・

実は make という開発支援するためのプログラムが存在します。
それは次回で・・・