makeコマンドを使ってみよう #3
マクロの使用
#1で紹介した以下のMakefileをさらにシンプルにします。
hello: hello.c
gcc hello.c -o hello
ターゲットのプログラム名と依存するファイルを、コマンドに直接書かずに次のようにマクロで代用することができます。$^は、コロンの右側の依存ファイルに置き換えられます。$@は、ターゲットのファイル名に置換されます。
hello: hello.c
gcc $^ -o $@
複数ソースプロジェクトへの応用
前回の記事(#2)で紹介した複数のソースファイルを扱うMakefileをマクロを使って書きなおすと次のようになります。マクロ$<は、コロン右側の依存ファイルのうち、最初のひとつのファイルに置き換えられます。favaroite-ex.cは依存ファイルがひとつしかないので、すべての依存ファイルへ置換される$^でも、$<でも同じコマンドが実行されます。しかし、myfood.oの作成においては、gccに与えるのはソースファイルmyfood.cだけにする必要があります。そのため、$<を使いました。
favorite-ex: favorite-ex.o myfood.o
gcc $^ -o $@
favorite-ex.o: favorite-ex.c
gcc $< -c -o $@
myfood.o: myfood.c myfood.h
gcc $< -c -o $@
パターンルール
上記Makefileでは、favorite-ex.oを作成するコマンドとmyfood.oを作成するコマンドが同じです。C言語のソースファイルのコンパイル方法は基本的に同じなので、ソースファイルが増えるたびに、同様のルールをMakefileに追加していくことになりますが、同じ記述を繰り返すことを回避するパターンルールという機能があります。この機能を使ったMakefileを以下に示します。
favorite-ex: favorite-ex.o myfood.o
gcc $^ -o $@
%.o: %.c
gcc $< -c -o $@
favorite-ex.o: favorite-ex.c
myfood.o: myfood.c myfood.h
%.o: %.cの箇所には、.oという拡張子のファイルを、拡張子以外が同じ名前で、拡張子が.cのファイルから作成するルールを定義します。なので、これはfavorite-ex.oをfavroite-ex.cから作成したり、myfood.oをmyfood.cから作成する一般的なルールに与えます。そして各オブジェクトファイルの作成ルールにあたっては依存関係のみ記述し、コマンド部を省略することができます。
組み込みルール
実は、Makeには組み込みルールと呼ばれるさらに記述をシンプルにできる機能が搭載されています。それを使うと上記のMakefileは次のように書けます。
favorite-ex: favorite-ex.o myfood.o
gcc $^ -o $@
%.o: %.c
gcc $< -c -o $@
myfood.o: myfood.h
makeは、n.oというファイルは、n.cに依存していると想定します。つまり、favroite-ex.oは、favorite-ex.cに、myfood.oはmyfood.cにそれぞれ依存していることは、明示的に記述しなくてもよいのです。
さらに驚くべきことに、n.oをn.cから作るルールと、n.oから実行ファイルを作るルールもmakeは組み込みルールを持っています。それは、いままで記述してきたgccを実行するコマンドそのものです。したがって、次のようにMakefileを極めてシンプルに記述することが可能です。
favorite-ex: favorite-ex.o myfood.o
myfood.o: myfood.h
事実、3つのファイルのいずれを更新しても、以下のように実行ファイルがビルドされます。
$ touch favorite-ex.c
$ make
cc -c -o favorite-ex.o favorite-ex.c
cc favorite-ex.o myfood.o -o favorite-ex
$ touch myfood.h
$ make
cc -c -o myfood.o myfood.c
cc favorite-ex.o myfood.o -o favorite-ex
$ touch myfood.c
$ make
cc -c -o myfood.o myfood.c
cc favorite-ex.o myfood.o -o favorite-ex
$ make
make: 'favorite-ex' is up to date.
hello.cを組み込みルールを使って書く
冒頭のhello.cをビルドするMakefileは、上記の機能を活用すると実は以下のようにも書くことができます。
hello:
まとめ
今回は、重複した記述を低減するために、マクロ、パターンルールおよび組み込みルールを紹介しました。これによりMakefileを極めて単純にできることが、おわかりいただけたと思います。次回は、コンパイラやリンカに引数を渡す方法を紹介します。