プログラムの再コンパイル方法を教えてくれるmakefileは複数の用途で利用されます。最もシンプルな利用は更新すべきファイルごとの最コンパイルです。普通、引数なしでmakeが実行できるならそうしますが、この場合makefileはまさしくそう書かれています。
でもファイルのいくつかだけを更新したいかもしれませんし、別のコンパイラやコンパイラオプションを使いたいかもしれませんし、ファイルを変えないでどのファイルが最新じゃないかをちゃんと発見したいかもしれません。
makeを実行するときに引数を与えると、こういうことやその他多くの事ができます。
makeが終了時に返すステータスは常に下の3つのうちのどれかです。
0
makeが成功すれば0になります。
2
make実行中にいくつかのエラーに遭遇しました。特定のエラーを説明するメッセージを出力します。
1
makeがどれかファイルが最新ではないと判断した時に1になります。コマンドを実行する代わりに…の段落をご覧下さい。
makefileを指定するには、"-f"か"--file"オプションです("--makefile"でも可)。例えば、"-f altmake"は"altmake"というファイルをmakefileとして使う事を示します。
"-f"フラグを何度もそれぞれの"-f"の後に続けて使うと、すべての指定ファイルがそろってmakefileとして扱われます。
"-f"か"--file"を使わない場合、デフォルトとして"GNUmakefile"、"makefile"、"Makefile"をこの順序で試し、3つのうちで作成できるか存在する一番最初のものを使います。(訳注:Windowsの場合は大小の区別をしないので"makefile"、"Makefile"は同じです)。(Makefileの作成 を参照して下さい)
ゴールとはmakeが最終的に更新するために頑張るターゲットの事です。他のターゲットはゴールの依存関係またはゴールの依存関係の依存関係 etc.が見えればそのように更新されます。
デフォルトとして、ゴールはmakefile中の最初のターゲットです(ピリオド"."で始まる目標を除く)。だから普通、最初の目標がプログラム全体をコンパイルするか、複数のプログラムを筆記したものをコンパイルするようにmakefileを書きます。makefile内の最初のルールにいくつかのターゲットがあるなら、ルール内のリスト全てじゃなく最初のターゲットだけがデフォルトのゴールになります
ひとつまたは複数の別のゴールをmakeの引数で指定することができます。ゴールの名前を引数として使って下さい。もしそれぞれのゴールを指定するなら、makeはそれぞれを命名順に次々と処理します。
makefile内のいくつかのターゲットは多分ゴールとして指定されます(ターゲットが"-"で始まったり"="が含まれ、その場合、パラメータまたは変数の定義としてそれぞれ構文解析されない場合に限り、ですが)。ターゲットがmakefileで指定されていないと思われる場合でさえ、対象に見合った作成方法の暗黙ルールをmakeが見つけたならmakeは正常に処理されます。
Makeはコマンドラインで与えて指定されたゴールのリストをMAKECMDGOALSという特別な変数にセットします。もしコマンドラインで全くゴールが与えられなかったなら、変数の中身は空っぽになります。この変数が特殊な事情で使われているということを覚えておいて下さい。
適当な利用の一例は、".d"ファイルをcleanルールの中に含めないようにしたものです(自動的に依存関係を生成の段落を参照)。それでmakeはすぐにまた".d"ファイルを削除するために作る事はしないでしょう:
sources = foo.c bar.c ifneq ($(MAKECMDGOALS),clean) include $(sources:.c=.d) endif
ゴールの指定の一つの用途は、プログラムの一部分だけあるいはいくつかのプログラムの内から一つだけのコンパイルです。つまり作り直したいと思ったそれぞれのファイルをゴールとして指定します。例えば、いくつかのプログラムがと一つのmakefileが一つのディレクトリにあると考えて、そのmakefileはこんな風に始まるとします:
.PHONY: all all: size nm ld ar as
もしsizeプログラムを動かしているなら、そのプログラムのファイルだけを再コンパイルするために"make size"としたいかもしれません。
ゴールの指定の別の用途は、普通には作られないファイルの作成です。例えば、デバッグ用に出力したファイルや、テスト用に特別にコンパイルされたバージョンのプログラムがそうです。これらにはmakefile中のルールがあるのに、デフォルトゴールに属していません。
ゴールの指定のまた別の用途は、フォニーターゲット(偽りのターゲット(Phony)の項を参照)または空っぽのターゲット(イベントを記録するだけの空ターゲットファイルの項を参照)に関連付けられたコマンドの実行です。多くのmakefileは"clean"というフォニーターゲットを含んでいます。"clean"はソース以外なら何でも削除します。当然ですが、これは"make clean"と明示的に要求しないと実行されません。次に述べるものが典型的なフォニーターゲット名と、空ターゲット名のリストです。ユーザーのための標準ターゲットの項を参照すると、GNU ソフトウェアパッケージが利用する全ての標準ターゲット名の詳細リストがあります。
make中に正常に作られる全てのファイルを削除する。
makefileはどのターゲットが更新すべきかという判断方法と各ターゲットの更新方法を makeに教えます。でも、ターゲットを更新が必ずしもあなたの望むようになるとは限りません。ある種のオプションは makeの別の動きを指定します。
makeがターゲットをコンパイルしたフリをするだけで本当は中身をいじらないということです。
makeによって現在の日時であると記録されます。特定のファイルを修正すべき時に結果としてどんなことが起こるかを知るために`-W' フラグと一緒に`-n'フラグを利用することもできます。
`-n'フラグをつければ、makeは通常実行されるコマンドを実行せずにただ出力します。
"-t"フラグをつければ、makeはルール内のコマンドを無視し、更新されるべきそれぞれのターゲットに(結果として)コマンド修正を行います。修正コマンドは"-s"、または .SILENT が使われていなければ出力もします。実行速度を考えて、makeはプログラムの修正を実際には呼び出しません。直接ターゲットに働きかけているのです。
"-q"フラグをつければ、makeは何も出力せずどのコマンドも実行しませんが、終了ステータスコードを返します。考慮されるべきターゲットが既に最新版になっていて、結果がそれだけだったなら0が返ります。終了ステータスが1ならいくつか更新作業をする必要があります。もしmakeがエラーに出会った場合は終了ステータスは2なので、更新されていないターゲットからエラーを区別することができます。
同じmakeの発動中に上記の3つのうち1つ以上が利用されることはエラーです。
"-n"、"-t"、それから"-q"オプションは"+"という文字で始まるか、"+"という文字を含むか、"$(MAKE)"や"${MAKE}"を含むかしているコマンドラインでは効果がありません。"+"や"$(MAKE)"、"${MAKE}"を含む行はつけられたオプションに関わらず実行されるということを覚えておいて下さい。同じルール内の他の行は同じように"+"で始まるか、"$(MAKE)"か"${MAKE}"をその行が含まない限りは、同じように実行されることはありません。
"-W"フラグは二つの機能を提供します。すなわち…
"-n"、"-q"フラグも使った場合、いくつかのファイルを修正する時makeがどういう動作をするかを知ることができます。
"-n"、"-q"フラグを使わず、makeが実際にコマンドを実行していくなら、"-W"フラグはmakeにいくつかのファイルが(実際はファイルに変更がないのに)更新されていたかのように演じさせることが可能です。
"-p"と"-v"オプションでmakeについて、また用いられるmakefileについての他の情報を得る事ができることを覚えておいてください(オプション要約の項を参照)。
ときおり、ソースファイルを変更してもそのファイルに依存する全てのファイルを再コンパイルしたくないことがあります。例えば、色々なファイルが依存するヘッダファイルにマクロや宣言を追加すると仮定します。控えめに、全ての依存ファイルに再コンパイルを要求させるようなヘッダーファイルに変更を加えるとし、依存ファイルに再コンパイルの必要のない事がわかっていて、それを再コンパイルするのにかかる時間が惜しいとします。
もしヘッダーファイルを変更する前にこの問題を予想したのなら、"-t"フラグを使ってください。このフラグはルール内のコマンドを実行しないで、ターゲットの最終修正時刻を変更してターゲットを更新するんだよ、とmakeに教えます。以下の手順のようになるでしょう。
makeを実行する時にはヘッダーの変更部分は再コンパイルと無縁のものになっている。"="を含む引数は変数の値を指定する、例えば"v=x"は変数vの値をxにします。こうやって値を指定すれば、makefile内で同じ変数が使われている場合、makefile内で普通に与えられた方をを全て無視します。つまりコマンドラインの引数で変数の値が上書きされたということになります。
この機能を利用する最も一般的な方法はコンパイラへの不要なフラグを無視する事です。例えば、丁寧に書かれたmakefileではCFLAGSという変数にはCコンパイラで動くコマンド群を含んでいるので、あるファイル"foo.c"はこんな感じでコンパイルが出来るのです:
cc -c $(CFLAGS) foo.c
こうやって、どんな値をCFLAGSにセットしても、処理されるコンパイル作業それぞれに影響します。 makefileは多分こんな風に毎度の値をCFLAGSを指定します。
CFLAGS=-g
makeする度に、好きなときに上書き出来ます。例えば、"make CFLAGS='-g -O'"と書けば、それぞれのCコンパイル作業は"cc -c -g -O"コマンドで行います。(これはシェル内で変数の上書きをする際に空白や他の特別な文字を変数の値として囲むのにコーテーションを使う方法を説明しています)
CFLAGS変数はこうやって変更ができる多くの標準変数のなかの一つでしかありません。暗黙ルールに用いられる変数の項に全てのリストがあります。
変数を変更してどうmakefileが動くかを場合に応じユーザーにコントロールさせるのに独自の追加変数を試すためにmakefileを書く事もあります。
変数をコマンド引数で上書きすると、再帰拡張変数や単純拡張変数も定義できます。上の例は再帰拡張変数のものです。単純拡張変数にする場合、"="の代わりに":="を使って下さい。ただし、変数参照、すなわち変数で指定する値の中での変数関数呼び出しでインクルードしたくなければ、作成する変数には何も変化を加えません。
上書きした変数をmakefileに影響させられる方法が一つあります。その方法とは上書き命令、つまり"override variable = value"のようなものを使う事です。(上書き命令の項を参照。)
普通、シェルコマンド実行中にエラーが発生するとmakeはすぐ諦めて0以外の値を返します。それ以上ターゲットにコマンドは実行されません。ゴールが正しく作り直せなかったというのもエラーの一つで、そのときmakeはできるだけそれに気づくように報告してくれます。
変更を加えたばっかりのプログラムをコンパイルしても、思う通りの結果にならないものです。そういうときは、試しうるファイル毎にそれぞれmakeにコンパイルを試させ、出来る限り多くのコンパイル実行エラーを表示させるのが良策です。
それぞれに"-k"または"--keep-going"フラグを使うべきです。これはmakeに未決定のターゲットの別の依存関係を、考慮し続けるように命令します。すなわちmakeに途中で0以外の値を返して中断する前に、可能なら作成を行わせるようにします。例えば、一つのオブジェクトファイルのコンパイル中にエラーがあったあと、"make -k"ならたとえリンクが不可能だと既にわかっていても他のオブジェクトファイルをコンパイルし続けます。シェルコマンドが失敗しても続けることに加えて、さらに"make -k"は依存ファイルやターゲットの作り方が分からないと発見した後にできる限りたくさんの作業を続けてくれるでしょう。これは常にあるエラーメッセージの原因になります。だからといって"-k"がないと、致命的エラーになってしまいます。(オプション要約の項を参照)
普通makeは「目当てのファイル(the goals)を更新する事が目的だ」という仮定の上で動作しています。つまり、ひとたびそれが不可能なことをmakeが学習すれば、直ちに失敗を表示するほうがいいとmakeは判断します。"-k"フラグは、ちゃんとした目的はできるだけたくさんテストすることであると示します。そのテストは「プログラムが作成する違い」のテストであり、おそらく、「次回コンパイルを試すまでに全部直しておきたい類の各依存関係の問題」を発見するためのテストです。こんなわけでEmacsのM-xコンパイルコマンドは"-k"フラグをデフォルトとしています。
これがmakeの全オプション表です。
makeの互換性維持のためにあり、無視されます。
makeの再帰処理で利用されます。(makeの再帰利用の項を参照)
makeの作業に関わるか、どのファイル時刻が比較されてその結果はどうだったか、どんなファイルを本当はmakeするべきだったか、どんな暗黙ルールが関わったか、など、どれがmakeの実行に関わったかという類のことなら何でも教えてくれます。
makeが対応しているオプションのリストを表示して終了する。
makeはできるだけ多くのジョブを同時に実行します。もし"-j"オプションが一つ以上あれば、最後のものが有効になります。並列実行の項を参照すればどんなコマンドが動くかについてもっと多くの情報があります。注…このオプションはMS-DOSでは無視されます。
makeできないのに、それらのターゲット以外の依存関係を何でもなかったように処理することができる。プログラムをテストコンパイルするの項を参照。
makeの再帰利用 の項を参照)経由で、または`-k'を環境のMAKEFLAGで設定した場合に、上位レベルのmakeから受け継がれる場合の再帰makeでしか必要になりません。
makeが作動する際にmakeを騙すためです。コマンドを実行する代わりに…の項を参照。
makeプログラムのバージョンと著作権(著作者のリスト)と無保証であるという注意書きを出力して終了します。
makeコマンドで複雑に入れ子になっている場合のエラーを見つけるのにきっと役立つでしょう。makeの再帰利用の項を参照。(実際には、`make'がやってくれるのでめったにこのオプションを指定する必要がありません。詳しくは`--print-directory'オプションの項を見て下さい)。
-wのワークディレクトリの出力を使わないようにする。このオプションは余分なメッセージを見たくないのに"-w"が自動でついてくる場合に便利です。--print-directory オプションの項を参照。
make実行前に与えられたファイルでtouchコマンドを実行したのとほとんど同じです。ただしmake実行中の仮定としてのみ更新時刻が変更される事を除きます。コマンドを実行する代わりに…の項を参照。
makeが、定義されていない変数への参照を認識したときに、警告メッセージを発行する。複雑に変数が使われているmakefileをデバッグしようとするときにすごく便利な事があります