ビルドとは
ソースコードを人間語から機械語に翻訳すること
Cプログラムを実行ファイルにする流れ
-
プリプロセス
#include や #define を展開
例: #include "util.h" → util.h の中身をソースに埋め込む -
コンパイル
C言語のソースコード(.c)を アセンブリ言語 に変換 -
アセンブル
アセンブリ言語を 機械語 に変換して オブジェクトファイル(.o) を作る -
リンク
複数のオブジェクトファイル + ライブラリを結合して 実行ファイル を作る
実際にCソースを動かしてみる
ディレクトリ構成と中身
project/
├── main.c
├── util.c
└── util.h
main.c
#include <stdio.h>
#include "util.h"
int main(){
int a = 2, b = 3;
int sum = add(a,b);
printf("sum = %d\n",sum);
return 0;
}
util.c
#include "util.h"
int add(int x, int y){
return x + y;
}
util.h
int add(int x, int y);
以下のコマンドを実行してコンパイルを行う
gcc -c main.c # → main.o(前処理+コンパイル+アセンブル)
gcc -c util.c # → util.o
gcc -o prog main.o util.o # → 実行ファイル prog(標準Cライブラリも自動リンク)
./prog # 実行: sum = 5
処理を一つづつ見てみる
- gcc -c main.c
main.cのincludeを展開しmain.oを生成する
この時、util.hにadd関数の宣言があるため、add関数の実装を行っていなくてもエラーにならない。 - gcc -c util.c
util.cのincludeを展開しutil.oを生成する
add関数の実装はutil.cで行っている。 - gcc -o prog main.o util.o
main.oとutil.oをリンクして実行ファイルのprogを生成する
add関数の実態はutil.oにあるため、main.cで記載していたaddの処理がそのまま使用できる
※util.oをリンクしなかった場合「undefined reference to `add'」になる