makeにどうやってシステムの再コンパイルをするかを指令する情報は、makefileというデータベースを読むことで伝えられます。
Makefileは5つの要素を含みます。すなわち、明示ルール、暗黙のルール、変数定義、ディレクティヴ(指令)、コメントです。ルール、変数、ディレクティヴについては後の章で詳しく説明します。
makeがmakefileを探す際、デフォルトでは`GNUmakefile'、 `makefile'、`Makefile'という名前をこの順で試します。
普通はmakefileのことを"makefile"か"Makefile"かにするべきです。(ディレクトリリストの始まりのほうで目だって見えて、"README"のような他の重要なファイルのちょうど近くになるので"Makefile"を推薦します。) 最初にチェックされる名前、"GNUmakefile"はたくさんのmakefileにつけることはお薦めしません。GNU make特有であり、他のバージョンのmakeでは理解されないようなmakefileにのみ命名すべきです。ほかのmakeプログラムは`makefile'、`Makefile'は探しますが`GNUmakefile'は歯牙にもかけません。
先に述べた名前をmakeが発見しなければ、makeはmakefileは全く使いません。そのためコマンド引数でゴールを指定しなければならなくなり、makeはビルトインされた暗黙のルールだけを使ってリメイク方法を見つけ出そうとするでしょう。暗黙のルールの利用の項を参照して下さい。
標準ではない名前をmakefileに使いたいのなら、"-f"か"--file"オプションでmakefileの名前を指定できます。`-f name'引数や`--file=name'引数はmakeにnameというファイルをmakefileとして読むように命令します。"-f"、"--file"オプションを一つ以上使うと複数のmakefileが指定できます。内部的に全てのmakefileが並べられた順番で連結されます。"-f"や"--file"を指定した場合、`GNUmakefile'、`makefile' and `Makefile'というデフォルトのmakefile名は自動ではチェックされません。
includeディレクティヴはmakeに現在のmakefileの読み込みを中断させ、続ける前に一つないしそれ以上の他のmakefileを読ませます。includeディレクティヴとは以下のようなmakefileにある一行のことです。
include filenames...
filenamesはシェルファイル名の型を含むことが可能です。
行の始まりの余分な空白は許され、また無視されますが、タブは許されません。(もしタブから始まるとコマンド行だとみなされます。) ホワイトスペース(空白)はincludeとファイル名の間に必要で、ファイル名同士の間にも必要です。間やディレクトリの行末にある余計なホワイトスペースは無視されます。"#"で始まるコメントは行末では許されています。もしもファイル名が変数や関数の参照を含むものなら名前が展開されます。変数の利用法の項を参照して下さい。
例えば、"a.mk"、"b.mk"、"c.mk"、という、3つの".mk"ファイルがあるとし、bish bashが展開される$(bar)というものがあるなら、以下のようになります。
include foo *.mk $(bar)
これはすなわち、
include foo a.mk b.mk c.mk bish bash
と同じ意味になります。
makeが一つのincludeディレクティヴを処理する時、makefileを読む作業をいったん停止し、リストされたそれぞれのファイルをたて続けに読み込んでいきます。終了してやっと、makeは元のmakefileのディレクティヴのあった場所から読み込みを再開します。
includeディレクティヴの利用場面の一つは、様々なディレクトリにある個々のmakefileで制御されているいくつかのプログラムに共通の変数定義(変数を準備するの項を参照)や型ルール(>型ルールの定義と再定義の項を参照)を設定する必要性が生じた時です。
もう一つの利用場面は、ソースファイルから自動的に依存関係を生成したい時です。つまり、依存関係は主となるmakefileでインクルードしたファイルから判断させることも可能なのです。他のmakeで伝統的な方法で行われるように、主となるmakefileの終わりにどうにかして依存関係を添えたものよりもこうしたほうがキレイになります。自動的に依存関係を生成の項を参照して下さい。
指定された名前がスラッシュ("/")で始まらず、カレントディレクトリにそのファイルがなかった場合、他のいくつかのディレクトリが検索されます。まず初めに、"-I"オプションか、"--include-dir"オプションで指定していたディレクトリが検索されます(オプション要約の項を参照)。それから以下のディレクトリが(存在すれば、)この順番で検索されます。`prefix/include' (普通は`/usr/local/include'(1))`/usr/gnu/include'、`/usr/local/include'、 `/usr/include'。
インクルードされた、あるmakefileがどのディレクトリを探しても見つからなかった場合、警告メッセージ(warning message)が発生しますが、直接の致命的なエラー(fatal error)にはなりません。つまり、includeを含めていくという、makefileの処理をそのまま続けます。いったんmakefileの読み込みを終えてしまえば、makeは存在しなかったり古かったりするものを作り直そうとします。どうMakefileが作り直されるのかの項を参照して下さい。makefileを作り直す方法を見つけようとして失敗した場合のみ、makeはmakefileの欠落を致命的なエラーとして診断します。
存在せず、作り直すことができないmakefileを、単にmakeに無視させるだけにしてエラーメッセージを出させたくない場合は、-includeディレクティヴをincludeの代わりに用いてください。このようにします、
-include filenames...
filenamesが存在しない時にエラーがない(警告さえもない)こと以外は、まったくincludeのように振舞います。ほかのmakeとの互換性をもつ方法として、-includeのもうひとつの名前であるsincludeがあります
環境変数MAKEFILESが定義されると、makeはその中身を、ほかのmakefileを読むまえに処理するべき、(空白で区切られた)追加のmakefileの名前のリストである、とみなします。includeディレクティヴのように、おおいに活躍してくれます。それで、様々なディレクトリがリストに挙げられたファイルの検索対象になります(他のMakefileをインクルードするの項を参照)。
さらに、デフォルトゴールがリストのmakefileから与えられることは決してなく、MAKEFILES
にリストされたファイルが見つからなくてもエラーにはなりません。
MAKEFILES
の主な役割はmakeの再帰起動間のコミュニケーションです(makeの再帰利用の項を参照)。大抵は外側からmakefileをかき乱さないほうがいいとされているので、makeのトップレベルの起動の前に環境変数を設定することは、普通はあまり望ましくはありません。それでもなお、makefileを指定せずにmakeを実行する場合、MAKEFILESにあるmakefileは、ビルトインされたサーチパスの定義のような暗黙のルールの助けになるものとして便利なものになり得るのです。(ディレクトリから依存ファイルを探す の項を参照)。
接続時、自動的に環境にMAKEFILESがセットされ、やって欲しいことがmakefileにプログラムされることに魅力を感じる人もいますが、これは非常に悪い考えです。なぜなら、そのようなmakefileは他の誰かが実行すると作業が失敗することになるからです。makefileで明示的にincludeと書くほうがずっと良い方法です。他のMakefileをインクルードするの項を参照して下さい。
時々、makefileはRCSやSCCSのような他のファイルによって作り直されることがあります。makefileが他のファイルによって作り変えられる可能性があるなら、多分makeに読み込むmakefileは一番最新のバージョンを取得したいはずです。
makeは全てのmakefileを読み込んだ後、最後にそれぞれをゴールターゲットとして更新しようと試みます。あるmakefile(まさしくmakefileというファイルか、ほかの名前のmakefileかです)が更新方法についてのルールを持っていた場合、または暗黙のルールが見られた場合(暗黙のルールの利用 の項を参照)は必要であればmmakefileを更新します。全てのmakefileをチェックし、実際変更されたものがあれば、makeは意気揚々と全てのmakefileを再度読み直します。(また再びそれぞれのmakefileを更新しようと試みますが、すでに更新されているのですから普通は繰り返し変更が加えられることはありません。)
makefileで二重コロン("::")ルールを、依存関係なしでコマンドを使ってファイルを作り直すのに指定すると、指定されたファイルを毎回作り直します(二重コロンルール の項を参照)。複数のmakefileがある場合、二重コロンルールがあり依存関係が一つもないmakefileはmakeが走査する度に作り直され、それからまたmakeがmakefileを繰り返し読み直す際また作り直されます。makeが耐えずmakefileを作り直していて、しかも他に何もすることがないと、無限ループができると考えられます。これは避けたいことなので、makeは二重コロンターゲットとして指定されているのに依存関係の全くないmakefileは作り直そうとはしません。
"-f"オプションや"--file"オプションで読み込み用のmakefileを指定しなければ、makeはデフォルトのmakefile名を試します。これについてはMakefileの命名方法 の項を参照して下さい。"-f"オプションや"--file"オプションで明示的に似ても似つかぬmakefileをリクエストしたなら、makeはそれらのmakefileの存在を確信していません。それでもなお、デフォルトのmakefileが存在しなくてもmakeルールの実行で作成出来るならば、makefileを使うためにmakeルールを実行してほしいと思います。
だからデフォルトのmakefileが一つも存在しなければ、どれか一つが成功するか、すべて試しきるまでは、makeは探す順番と同じ順でmakeしようと試みます(Makefileの命名方法 の項を参照)。
注意:makeがmakefileを一つも見つけられなくても、makefileが必ずしも必要というわけではないので、エラーにはなりません。
"-t"オプションか"--touch"オプション(コマンドを実行する代わりに… の項を参照)を使う際、どのターゲットを修正(touch)するかを決めるのに、古いmakefileを使いたくはないでしょう。ですから、"-t"はmakefileの更新には全く手を貸さないはずですが、実際は"-t"オプションが指定されていても更新されます。同様にして、"-q"(または"--question")や"-n"(または"--just-print")は、makefileの更新を妨げません。なぜなら古いmakefileというのは往々にして他のターゲットの間違った出力の結果だからです。こういう経緯から、`make -f mfile -n foo'は"mfile"を更新し、読み込み、"foo"とその依存関係を更新するためのコマンドを実行することなく書き出します。"foo"のために書き出されたコマンドは更新された"mfile"の内部で指定されたものになります。
それでもなお、makefileを更新することさえ防ぎたいと思うことが実際にはあるかもしれません。ゴールにmakefileを指定する作業をコマンド行でおこない、ゴールとしてmakefileを指定すれば更新を防ぐ事ができます。makefileの名前がゴールとして明示的に指定されると"-t"などのオプションはちゃんと対応してくれます。
こうして、`make -f mfile -n mfile foo'では"mfile"というmakefileを読み、実際に実行することなしにmakefileの更新に必要なコマンドを書き出し、それから、実行することなく"foo"の更新に必要なコマンドも書き出します。"foo"のためのコマンドは現存する"mfile"の中身で指定されたものになります。
makefileの大部分を別のmakefileが占めているmakefileを設ける事が便利な場合もあります。別のmakefileにあるmakefileをインクルードしたり、もっと多くのターゲットや定義を加えたりするのに"include"ディレクティヴを頻繁に使うことは可能です。ところが、同じターゲットに対して二つのmakefileで違うコマンドを与えたりすると、makeはその通りには従ってくれません。だから別の方法があります。
(他のmakefileをincludeしようとする)makefileを含む作業では、その作業で与えられた情報からでは作ることができないターゲットを作り直させるために、条件にマッチしているかを調べるための型(match-anything pattern)を利用することができます。利用することで、makeは別のmakefileの中をチェックするようになります。型ルールの詳しい情報は型ルールの定義と再定義の項を参照して下さい。
例えば、ターゲット"foo"(と、別のターゲット)をmakeする方法を決める、"Makefile"というmakefileがあるなら、以下の内容を含める"GNUmakefile"というmakefileを書くことができます。
foo: frobnicate > foo %: force @$(MAKE) -f Makefile $@ force: ;
"make foo"と命令すると、makeは"GNUmakefile"を見つけて、読みこみ、"foo"を作成するために上の内容を理解し、`frobnicate > foo'というコマンドを実行することになります。"make bar"と命令すると、makeは"bar"をmakeする方法を"GNUmakefile"では見つけられないため、型ルールにあるコマンド、つまり`make -f Makefile bar'を実行します。"Makefile"が"bar"を更新するルールを提供しているなら、makeはそのルールを充てます。"GNUmakefile"がmakeの方法を指示しない別のターゲットについても同様です。
型ルールを働かせるには、型ルールが正しく"%"という型を持っている必要があります。これがあるからこそ、どのターゲットにもマッチするのですから。"force"という依存関係を指定するルールは、ターゲットが既に存在していてもコマンドが実行されることを保証するものです。"force"ターゲットは空白にし、そうすることでmakeにビルド用の暗黙のルールを探させないようにします。そうしておかなければ同じ様な条件一致ルールを"force"自身にも充ててしまい、依存関係のループができてしまいます!!