気の向くままに辿るIT/ICT/IoT
UNIX/Linux

UNIX/Linux makefile フォニーターゲット

ホーム前へ次へ
makefileのフォニーターゲットとは?

UNIX/Linux makefile フォニーターゲット

makefile フォニーターゲット

 UNIX/Linux及びシェルにおいてmakefileとは、makeコマンドによって実行されることを想定してファイル間の依存関係とタイムスタンプに基づくルールを羅列またはパターンによって記述したテキストファイルです。

 makeコマンドとmakefilemakefileを書く、更にはmakefileのパターン・自動変数・変数でターゲットの羅列、劇的な記述の簡略化までできるようになりましたが、ここでは更に便利なコンパイル以外でも大活躍するフォニーターゲットについて見てみます。

 尚、特別な記述がない限り、C言語用のmakefile作成を想定しているものとします。

フォニーターゲット

%.o : %.c 

    cc -c $< 

.SUFFIXES: .c 

foo.o : foo.h 

 前回はこのような普通の人が見ても一見するとなんのことやらさっぱりわからない文字列が、これまでの2~3ページを読むことでソフトウェア、システム開発の開発工程における作業を劇的に効率アップしてくれるmakefileという便利な代物であり、それが一体どんなもので、どうやって書くかまでものすごく詳しくなった!?かと思います。

 ここではフォニーターゲットというものを見ていくわけですが、ページを順に読み進めたり、フォニーターゲットのリンクをクリックしてここにいる場合には、記憶にあるであろう初っ端の例のtarget/it_is_not_targetなどと書いたあれのことで、ファイルとして実在しない前提でmakefileターゲットに書くことができるということでした。

all : foo bar hoge 

foo : foo.c 

    cc -c $< 

bar : bar.c 

    cc -c $< 

hoge : hoge.c 

    cc -c $< 

 実在しない名前。。。フォニーターゲットのフォニー(phony)とは、「偽の」といった意味でフォニーターゲットは偽のターゲットということですが、これはネガティブな話ではなく、makefileではターゲットにファイル名を書くのが本来の姿ですが、実はファイルとして存在しない名前を書くことが許されていてラベルだけ書いて依存するターゲットを指定しないか、他のターゲットのラベルを書くと便利なことが多く

 このallターゲットのように他のターゲット(foo,bar,hoge)に依存し、その全てを必要があれば実行するというケースが既定であるなら、makeコマンドで引数を省略した場合にも、allが実行されるので便利ですし、

SOURCES = foo.c bar.c 

foobar : $(SOURCES) 

    cc -o $@ -c $^ 

clean : 

    rm -f $(SOURCES:.c=.o) 

 このcleanターゲットはオブジェクトファイルを一気に削除する場合に便利です。

 ここで$(SOURCES:.c=.o)は、パターンマッチングで変数SOURCES内の.c(ドットc)という拡張子を.o(ドットo)に変換したものを表し、この場合、ボディファイル/ソースファイル(.c)ではなく、オブジェクトファイル(.o)を全て削除するという意味になります。

SOURCES = foo.c bar.c 

foobar : $(SOURCES) 

    cc -o $@ -c $^ 

clean : 

    rm -f $(SOURCES:.c=.o) 

veryclean : clean

    rm -f $(SOURCES:.c=.c~) 

 もし、.c~といったバックアップとおぼしきファイルがやたらと存在するなら、これらも不要になった時点で全て削除、その時点ではオブジェクトファイルも削除したいかもしれません、そんな時verycleanターゲットでcleanターゲットを指定しておくとコマンドラインからmake verycleanと実行すればバックアップと思しきファイルやオブジェクトファイルが期待通り全て削除されます。

 ちなみにフォニーターゲットのラベルは、同名のファイル名がないことが前提ですが、万一、そういうファイルが存在する場合、期待した結果になりませんが、実行した人は、実行できたものと思い込んでしまうかもしれません。

SOURCES = foo.c bar.c 

foobar : $(SOURCES) 

    cc -o $@ -c $^ 

. PHONY clean : 

    rm -f $(SOURCES:.c=.o) 

. PHONY veryclean : clean

    rm -f $(SOURCES:.c=.c~) 

 この思い込みの問題が他の問題を生む可能性を回避する為に他のファイルではなくフォニーターゲットであることを宣言する「. PHONY」を付加したラベルを記述することができます。

 こうすることでmake cleanやmake verycleanが実行される際に仮に同名ファイルが実在する場合でも同名のファイルのターゲットではなく、フォニーターゲットを探すようになります。

 ちなみに、このmakefile内に. PHONYで指定したcleanやverycleanとは別にclean、verycleanというターゲットのないラベルは、ないというのは大前提です。

SUBDIR = foo bar hoge hogehoge makemakermakest \ 

goodjob badjob jabjob ...etc. 

 尚、実運用上では、変数に大量のファイルを記述しなくてはならないケースもあるかもしれませんが、行が長すぎて改行したい場合には、コマンドラインエディタを改行して利用する時のようにbashの文法同様、行末尾にバックスラッシュを入れると改行しても一行として続けて記述することができますが改行の直前にバックスラッシュを入れないと見つけにくいバグやエラーの原因になりますから複数行にまたがる場合には、必ずバックスラッシュの直後に改行します。

 また、全ての環境を整える為にinstallというターゲットを書く場合もあるかもしれませんが、必ずしもこうしたラベルで書かなければいけないと決まっているわけではないですし、これらのラベル名を流用したラベル名を付けてはいけない決まりもないので、そのあたりは状況に応じて臨機応変に対応します。

 更にコマンドは書かなくてもよいし、必要なら一行だけでなく複数行記述することもできますし、コマンドもcc/gcc/rmに限らず基本的にUNIX/Linuxコマンド、シェルコマンドはmake含め全て記述できますし、シェルのフロー制御構文も利用できるので、コンパイルや削除に留まることなく、また業務システム、組み込み用途などのソフトウェア開発やアプリケーションのインストールでもなく、また別の要件で使いたくなるかもしれませんね。

LINK

ホーム前へ次へ