コンパイル、リンク、ビルドの違いについて考えよう![コンパイラ、リンカ]

妹「お兄ちゃん、コンパイルってなにかな……。リンクとビルドの違いがよく解らないよ」
兄「えっと、簡単に言うとコンパイルが 『 ソースコード 』から『オブジェクトコード 』 に変換する事だね。コンパイラを使うよ」
妹「オブジェクトコード?」
兄「001.cというソースがあって、コンパイルをかけると001.objが得られます 」
妹「001.exeじゃないんだ?」
兄「この時点では実行できないんだ。リンクをすると001.objから001.exeが作られる。これをリンクって言うね」

妹「なんでオブジェクトファイルっていう物に分けてるの?」
兄「分担してプログラムを作るんだよ。サブルーチンとかを妹が002.cとして作って、兄が001.cとしてメインを作って呼び出す。二つのプログラムをリンクして完成。分担しやすくなるし機能がソース毎に分かれるから、Cではそうやって管理してたんだよね」
妹「そっか。チェックアウトしてみんなで触れたらいいのにね」
兄「特にこのobjは昔からの人だとそういう動きを知ってるんだよね。最近の言語だとコンパイラ・リンカと別れてないけど、C#等の.netの実行ファイルを直接参照すると中身の関数が使えるよね?ああいう感じ」
妹「ふーん、そうなんだ。C#知らないけどね」

//------- 001.c ---------
 void function();
 int main()
 {
    function();
    return 0;
 }
//------- 002.c ---------
#include "stdio.h"
void function()
 {
   printf("Hello,World");
 }


兄「実際にやってみるとこういうソースがあったとして、001.cをコンパイルして001.objを作ります」
妹「コンパイルエラーになるよね?」
兄「Cだとコンパイルエラーにはならないよ。Functionはプロトタイプ宣言されてるし、文法的に間違ってないよね」

tiny-cを使うと、01.cをコンパイル・リンクまでするとリンクエラーになるが、コンパイルだけする-cを付けるとエラーにならない。

妹「通るんだ……」
兄「次に02.cをコンパイルします」
妹「こっちも通るんだ……」
兄「メイン関数が無いからこっちもこれだけでリンクするとエラーになるよ」

02.cをビルドし、01.o 02.oを作成後、01.oと02.oをリンクして01.exeを作る

妹「無事にできたね!じゃぁビルドって何が違うの?」
兄「こういうコンパイル・リンク一連の流れを記述したシェルやバッチ、プログラムをビルドと呼ぶね」
妹「コンパイルでオブジェクトを作る、リンクで実行ファイルを作る、バッチは一連の流れを示した物なんだね」
兄「うん、そうだね」