Makefileを書いてみる.1
基本文法?
Makefileの文法は以下の通り。
# Makefile
ターゲット: 依存ファイル1 依存ファイル2 依存ファイル3
コマンド行1
コマンド行2
コマンド行3
ターゲットは作りたい「料理」、依存ファイルは必要な「材料」、コマンドは材料を変換する「レシピ」と考えればよさそう。また、"#"以降はコメントになる。
(例) hello.cから実行形式ファイルhelloをビルドしたい
まず以下のhello.cを作成。
/* hello.c */ #include <stdio.h> int main() { printf("Hello World!\n"); return 0; }
hello.cと同じディレクトリに"Makefile"というファイルを作成。
# Makefile hello: hello.c gcc -o hello hello.c
ターミナルでmakeを実行すると以下のようビルドしてくれる。
$ make gcc -o hello hello.c
もう一度makeしてみると
$ make make: `hello' は更新済みです
と表示される.つまりhello.cが更新されてるか確認して,必要なときだけビルドしてくれるみたい。
(例)hello.cとthank.cから実行形式ファイルhelloをビルドしたい
以下のようにhello.cとthank.cを作成する。
/* hello.c */ #include<stdio.h> void thank(void); int main(){ thank(); return 0; } /* thank.c */ #include<stdio.h> void thank(void); void thank(void){ printf("Thank you!\n"); }
先ほどと同様にMakefileを作成する。
#Makefile hello: hello.c thank.c gcc -o hello hello.c thank.c
これでmakeすると、問題なくhelloがビルドされる。しかし、hello.cを更新してmakeすると、更新していないthank.cも再度コンパイルされてしまい無駄。よって以下のようにMakefileを書く方が良いみたい。
#Makefile hello: hello.o thank.o gcc -o hello hello.o thank.o hello.o: hello.c gcc -c hello.c thank.o: thank.c gcc -c thank.c
(例)hello.cからhelloを、sorry.cからsorryをビルドしたい
以下のようにhello.cとsorry.cを作成する。
/* hello.c */ #include<stdio.h> int main(){ printf("Hello World!\n"); return 0; } /* thank.c */ #include<stdio.h> int main(){ printf("I'm sorry!\n"); return 0; }
次に、Makefileを作成する。
#Makefile hello: hello.c gcc -o hello hello.c sorry: sorry.c gcc -o sorry sorry.c
これでmakeすると、helloしかビルドできない。よって以下のようにする。
#Makefile all: hello sorry hello: hello.c gcc -o hello hello.c sorry: sorry.c gcc -o sorry sorry.c
これで、makeを実行すると、
$ make gcc -o hello hello.c gcc -o sorry sorry.c
となり両方のファイルがビルドできる。ちなみに「make "ターゲット"」とすることでビルドするファイルを指定することができる。例えば、helloだけビルドしたい場合はmake helloを実行する。
中間ファイルを削除したい。 それと.PHONYって何?
ビルドするファイルが増えれば増えるほど、中間ファイルも増えてしまうので一括でそれらを削除できたら便利。よってMakefileに以下のように、cleanを加える。
# Makefile ターゲット: 依存ファイル1 依存ファイル2 依存ファイル3 コマンド行1 コマンド行2 コマンド行3 clean: rm -f 消去したいファイル
(例)ビルド後hello.oとsorry.oを消去したい
さっきの例でのビルド後にhello.oとsorry.oを削除するため、Makefileにcleanを追加。
#Makefile all: hello sorry hello: hello.c gcc -o hello hello.c sorry: sorry.c gcc -o sorry sorry.c clean: rm -f hello.o sorry.o
これでmake cleanを実行すると、hello.oとsorry.oが削除される。
ターゲットにcleanを指定しているが、cleanという名前のファイルを作るよう操作しているわけではない点に注意。こういったターゲットを"phony target"というらしい。(さっきの例のallもphony target。)
(例)ディレクトリにphony targetと同じ名前のファイルがあると困る
cleanというファイルを作ってからmake cleanを実行してみる。
$ touch clean $ make clean make: 'clean' は更新済みです.
となりmake cleanが実行できない。解決策として、以下のようにMakefileのcleanの上に".PHONY"と追記する(allも同様なので追記しとく)。
#Makefile .PHONY: all all: hello sorry hello: hello.c gcc -o hello hello.c sorry: sorry.c gcc -o sorry sorry.c .PHONY: clean clean: rm -f hello.o sorry.o
これでmake cleanが実行できるようになる。