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

9-4. 分割コンパイル

◆分割コンパイル

まず最初にソースファイルをコンパイルしてからアプリケーションができるまでの流れを図に示します。

◇実行ファイルができるまでの流れ

ソースファイル
   │
   │←プリコンパイル(マクロ等の処理)
   │←コンパイル(機械語に変換)
   ↓
オブジェクトファイル
   │
   │←リンク(機械語ファイルを結合)
   ↓
アプリケーション

これは基本的な流れです。開発環境によって多少の違いはあります。
因みに、lcc や gcc コンパイラでは標準でコンパイルとリンクを実行するので簡単なプログラムではあまりリンクを意識する事は無いと思います。
また、VC++ではリンクのことをビルドと言います。
(実際の動作は make そのものですが・・・)

これでは、次のプログラムを例にしてみます。

#include<stdio.h>
main()
{
  printf("C-Production\n");
}

そして、コンパイラのコマンドに -c を付けます。(コンパイルのみ実行)
例:lcc -c main.c

すると、まずプリコンパイルでソールファイルに stdio.h の内容が挿入されます。その状態がコンパイルの対象になります。
そして、コンパイルが終了すると機械語のオブジェクトファイルが生成されます。(.o または.obj)

ここでは、まだ実行することができません。stdio.hをインクルードしてprintf()が利用できるようになっても、printf()本体はstdio.hに含まれてません。次に、ライブラリとリンクすることによってprintf()が実装され、アプリケーションが完成します。

例 lcc main.obj

これが実際の流れになります。
ここではまだ分割コンパイルについては説明していません。

#include で取りこんだファイルはコンパイルの前に挿入され一つのファイルになるので、コンパイルは分割でなく一括です。

それでは最後に、分割コンパイルでアプリケーションを作成してみます。

次の3つのファイルから構成して。
file1にmain()
file2に別の関数(今回はfadd())
file2.hにはfile2で定義する関数の宣言をそれぞれ書きます。

/* file1.c */
#include<stdio.h>
#include"file2.h"

main()
{
  int a=2,b=3,c;
  c=fadd(a,b);
  printf("c = %d\n",c);
}
/* End Of File */
/* file2.h */
int fadd(int, int);
/* End Of File */
/* file2.c */
#include "file2.h"
int fadd(int a,int b)
{
	int x;
	x = a + b;
	return x;
}
/* End Of File */

そしてコンパイル時には(例:LSI-C)
> lcc -c file1.c
> lcc -c file2.c

でそれぞれ、file1.obj file2.obj が作成されます。
そして、2つのオブジェクトファイルをリンクして完成させます。

lcc file1.obj file2.obj

これでfile1.exeという名のアプリケーションができます。
(UNIX系のコンパイラではa.out)

特に名前を指定したい時は、

lcc file.exe file1.obj file2.obj

のようにしてください。