Edited at

今更聞けないmakefileの書き方

More than 3 years have passed since last update.


makefileとは

大規模なプログラムを作成していると、ソースファイルを少し書き換えただけでコンパイルし直すなのは面倒!!

だったら、いっそ自動化しちゃえっていうあれ。

自分はlinuxユーザーなので、GNU makefileについてしか紹介しないが、他にも色々あるみたい。


とりあえずmakefileを書いてみる

以下のC言語のソースファイルがあると仮定して


hello.c


#include<stdio.h>

int main(){
printf("Hello,World!!\n");
return 0;
}

同じディレクトリに「GNUmakefile」という名前でmakefileを作成する。


GNUmakefile

hello: hello.c

gcc -o hello hello.c

そして、makeコマンドを実行する。

これだけでmakefileに書かれたファイルをコンパイルしてくれる。

今回で言えば、hello.cの内容を変更するたびにmakeと打つだけで全てコンパイルしてくれる。


ちょっと説明

これだけじゃちょっとわかりにくいので、さくっと説明する。

今回作成した以下の内容を含むmakefileは


GNUmakefile

hello: hello.c

gcc -o hello hello.c

次の構造をとる

ターゲット名: 依存ファイル名

コマンド行

ターゲット名は一般的には生成されるファイル名と同じ名前にする。


少しだけ応用

以下のファイルを想定する。


hello.c

#include<stdio.h>


int main(int argc,char *argv[]){
printf("Hello,World!!\n");
sayhi();
return 0;
}



sayhi.c

#include<stdio.h>


void sayhi(){
printf("hi!!\n");
}


上記の内容のファイルが存在するとして、makefileを以下の様に作成したとする。

hello: hello.c sayhi.c

gcc -o hello hello.c sayhi.c

これでもいいが、どちらかのファイルを更新するたび両方コンパイルしていたのでは効率が悪いので以下の様にしてみる

hello: hello.o sayhi.c

gcc -o hello hello.o sayhi.o
hello.o: hello.c
gcc -c hello.c
sayhi.o: sayhi.c
gcc -c sayhi.c

これをmake -f makefile名と実行すると更新されたものだけコンパイルされる

詳しくはコンパイル、リンク関連を参照


さらに応用

これまでの方法ではいらないファイルが削除できないので、いっそのことmakefileで必要のなくなったオブジェクトファイルなどのファイルを消していく


hello: hello.o sayhi.c
gcc -o hello hello.o sayhi.o
hello.o: hello.c
gcc -c hello.c
sayhi.o: sayhi.c
gcc -c sayhi.c
clean:
rm -f hello hello.o sayhi.o


さらに応用

C言語で使用するヘッダーファイルが変更された場合はどうすればいいだろうか。

例えば以下の、ファイルを想定する


hello.c

#include<stdio.h>

#include"hello.h"

int main(){
printf("%s\n",sayhi);
return 0;
}



hello.h


char sayhi[] = "Hello,World!!";


これに対してmakefileは以下のようにする

.PHONY: all

all: hello

hello: hello.o
gcc -o hello hello.o
hello.o: hello.c
gcc -c hello.c

hello.o : hello.h

.PHONY: clean
clean:
rm -rf hello hello.o


この他に

マクロがあったり色々まだ機能はあるが長くなるので紹介はしない