( - )
Makefileの書き方
このページでは、Makfileの書き方について学んだことを記していきます。
最終更新日:2008年01月07日 (月) 22時27分47秒;
そもそもMakefileって何?
Makefileは大きなアプリケーションを自動ビルドするためのユーティリティ「make」で用いられるルール記述ファイル。ソースファイル群の依存関係を定義しておくことで、自動的にビルド対象を選び、必要なぶんだけコンパイルしてくれたりする便利なもの。
一般的にはC/C++プログラムのビルドにのみ用いられることが多いが、「インプット」→「プロセス」→「アウトプット」をなすものであれば何でも記述することができる。
(Texファイルからdvi,psファイルを作成することもできる)
(Texファイルからdvi,psファイルを作成することもできる)
基本的な構造
# '#'で始まる行はコメントを表す <ターゲット>: <依存ファイル/ターゲット> <コマンド1> <コマンド2> <コマンド3> : <コマンドn>
これは状態遷移図をイメージすると分かりやすい。
- 依存ファイルまたはターゲットから、
- コマンド1...nが実行されることで、
- ターゲット名が生成される
という流れ。つまるところ基本はこれだけでしかなく、あとはこの記述をいかに楽して入力するかにすぎない(ちょっと乱暴だけどね)。
ここでの注意点は以下のとおり:
ここでの注意点は以下のとおり:
- コマンドの最初は必ずタブ記号で始まること。連続した空白ではエラーになる。
- ルールの記述順序は関係ない(ただし最初に書いたものがデフォルトゴールとなり、コマンドラインからmakeだけで実行された場合のターゲットになる)
最初の注意点は初心者(僕のことだ)はよく陥りがちなので、特に注意しないといけない。とはいえ、タブでないとならないなんていうルールが良いとはとても思えないけれど。
何よりまずはHello, World!
hello: echo Hello, World! .PHONY: hello
$ make -s # -sは実行するコマンドを表示しないためのオプション Hello, World.
ごめんなさい。
冗談はさておき、簡単な例
簡単な例から、記述方法を考えていく。
補足
「.PHONY」って何?
ターゲットが、アウトプットとなるファイルではないことを示す。
.PHONY:(ターゲットが指定されたときに)必ず実行させたいターゲット一覧
と書いておくことで、ターゲットが評価される際は必ずコマンドが実行されることが保証される。
たとえば、
たとえば、
clean: rm -f *.o
だけ書いてあると、ディレクトリ内にcleanというファイルが存在するときに「make clean」でファイルを消去してくれなってしまう。これは「clean」というターゲットファイルが新しくなっていない、と判断されるため。
「.PHONY」はこの問題を避けるため、実際のファイルとは関係のない、アクションであることを示すために用いる。前例を修正すると、
「.PHONY」はこの問題を避けるため、実際のファイルとは関係のない、アクションであることを示すために用いる。前例を修正すると、
.PHONY: clean clean: rm -f *.o
となる。
Makefileのデバッグ方法
「make -d」がたくさんの情報を出すようになっているが、これだと沢山の情報に必要なものが埋もれてしまい、ほとんど役に立たない(と、僕は思っている)。しかし実際にもあまり有効な方法がないらしく、Wikipedia(en)の記事の記事でも
- 一つ一つの情報を注意深く調べる
- コマンドにechoを記述して、状況を見る
くらいしか書かれていない。
自動変数
- 「$?」
- 変更のあったファイルのみを表す
- 「$<」
- 依存ファイルの先頭に書かれたファイル
- 「$^」
- すべての依存ファイル名
- 「$*」
- サフィックスを除いたターゲット名
- 「$@」
- ターゲット名。次のようにして用いることもできる。
TEST_compile NORMAL_compile: hoge.c cc -D$(subst _compile,,$@) $@ -o hoge
- 上記は下の記述と等価。
TEST_compile: hoge.c cc -DTEST $^ -o hoge NORMAL_compile: hoge.c cc -DNORMAL $^ -o hoge
参考サイト
- Wikipedia(en)の記事。デバッグ方法についても若干触れられている。