2013年7月22日月曜日

Makefileを書いてみる その2

B4のtyadです。 今日は前回のMakefileのについての続きです。

前回はMakefileをつりあえず使ってみました。
今回はもう少し詳しく説明します。


依存関係

最初の例では依存ファイルは1つでした。
しかし依存ファイルが以下のように2つ以上の場合、
sample: main.c hoge.c 
 gcc -o sample main.c hoge.c
このようにMakefileに記述していると、main.c、hoge.cのどちらかが更新されただけで、
main.c、hoge.c、両方のコンパイルが行われてしまいます。 そこで、
main.o: main.c
 gcc -o main.o -c main.c 
hoge.o: hoge.c
 gcc -o hoge.o -c hoge.c 
smaple: main.o hoge.o
 gcc -o sample main.o hello.o
とします。こうすることでmain.cからmain.o、hoge.cからhoge.oが生成され、sampleはmain.oとhoge.oから生成されます。
そのため、hoge.cのみが更新された際にはhoge.oがコンパイルされ、 依然コンパイルしたmain.oを利用してsampleがコンパイルされます。
これにより、コンパイルの効率化が図れます!便利!


自動変数

さっきのMakefileを書いていると、
何回も同じファイル名を書くことがありましたが、これは面倒ですね。
そこでMakefileの自動変数というものを利用します。
main.o: main.c
 gcc -o $@ -c $^
hoge.o: hoge.c
 gcc -o $@ -c $^
sample: main.o hoge.o
 gcc -o $@ $^
「$@」がターゲットファイル名、「$^」が依存するすべてのファイル名となります。 これでさっきのMakefileと全く同じ動作をしてくれます。便利! 自動変数はこの二つの他にも、
  • 「$% : ターゲットがアーカイブメンバだったときのターゲットメンバ名
  • 「$<」 : 最初の依存するファイルの名前
  • 「$?」 : ターゲットより新しいすべての依存するファイル名
  • 「$+」 : Makefileと同じ順番の依存するファイルの名前
  • 「$*」 : サフィックスを除いたターゲットの名前
などがあります。


変数とマクロ

Makefileの中で変数を自分で定義することができます。 またマクロの置換も行えます。
SRC = main.c hoge.c
OBJ = $(SRC:%.c=%.o)
sample: $(OBJ)
 gcc -o $@ $(OBJ)
ここでは「SRC」という変数に「main.c hoge.c」を代入し、 「%」記号によってマクロの置換で「OBJ」という変数に「main.o hello.o」が代入されています。


関数の利用

Makefileには変数に代入された文字列を操作するための関数もあります。 一例として、$(patsubst pattern,replacement,text)という関数を使って、
SRC = main.c hello.c
%.o : %.c
 gcc -o $@ -c $<
OBJ = $(patsubst %.c,%.o,$(SRC))
sample: $(OBJ)
 gcc -o $@ $(OBJ)
このように書くことで、textからpatternに一致するものをreplacementに置換できます。 他の関 数はいっぱいあるので機会があれば調べてみてください。


まとめ

変数や自動変数、マクロ、関数を使うことで、Makefileをプログラム的に書くことができ、
非常に便利になります。
また、依存関係の記述は大規模プログラムの開発では、重要になると思います。
今日紹介したもの以外にも、様々な書き方があるみたいです。
Makefileは奥が深いですね!



0 件のコメント:

コメントを投稿