ここでは、make が出力する代表的なエラーを一覧にまとめ、それぞれが何を意味し、どう対処すればよいかを説明します。
make のエラーは、必ずしも致命的なものとは限りません。とくにレシピ行の先頭に - を付けていた場合や、コマンドラインで -k オプションを指定していた場合には、致命的にはなりません。致命的なエラーには、先頭に *** という文字列が付きます。
エラーメッセージにはすべて、プログラム名(ふつうは「make」)が頭に付くか、あるいはエラーが makefile の中で見つかった場合には、問題のある行を含むファイル名と行番号が頭に付きます。
以下の表では、こうした共通の接頭辞は省いてあります。
これらは、実のところ make 自身のエラーではありません。make がレシピの一部として起動したプログラムが、0 以外のエラーコード(「Error NN」)を返した——make はこれを失敗とみなします——か、あるいは何らかの異常な形で(何らかのシグナルを伴って)終了した、ということを意味します。レシピでのエラーの項を参照してください。
メッセージに *** が付いていない場合は、サブプロセスは失敗したものの、makefile のそのルールに特別な文字 - が前置されていたため、make がそのエラーを無視した、ということを意味します。
これは、いま読み込んだ makefile の行について、make がほとんど何も理解できなかったことを意味します。GNU make は、いま解析しているのがどんな種類の行なのかを判断するために、さまざまな区切り文字(:、=、レシピの接頭文字など)を探します。このメッセージは、その有効な区切り文字を見つけられなかった、ということを意味します。
このメッセージが出る最もよくある原因は、あなた(あるいは、多くの MS-Windows 用エディタがそうであるように、おせっかいなエディタ)が、レシピ行をタブ文字ではなく空白でインデントしてしまっていることです。この場合、make は上記の2番目の形のエラーを出します。レシピの各行は、必ずタブ文字で始めなければならないことを思い出してください(.RECIPEPREFIX を設定している場合を除きます。その他の特別な変数を参照してください)。8 個の空白では代わりになりません。ルールの構文を参照してください。
これは、makefile の最初に書かれているものがレシピの一部であるように見える、ということを意味します。つまり、その行はレシピの接頭文字で始まっていて、しかも(変数代入のような)正当な make ディレクティブには見えない、というわけです。レシピは、必ず何らかのターゲットと結び付いていなければなりません。
2番目の形は、その行の最初の非空白文字がセミコロンである場合に出ます。make はこれを、ルールの「target: prerequisite」の部分を書き忘れた、という意味に解釈します。ルールの構文を参照してください。
これは、make があるターゲットをビルドする必要があると判断したものの、それをどう作ればよいかという指示が、明示的にも暗黙的にも(デフォルトのルールデータベースを含めて)makefile の中に見つからなかった、ということを意味します。
そのファイルをビルドしたいのであれば、そのターゲットをどう作るかを記述したルールを makefile に追加する必要があります。この問題の原因として他に考えられるのは、makefile 内のタイプミス(そのファイル名が間違っている場合)や、ソースツリーの破損(そのファイルは本来ビルドされるべきものではなく、単なる前提条件であるはずなのに見つからない場合)です。
前者は、コマンドラインでビルドすべきターゲットを一つも指定しておらず、しかも make が読み込める makefile を一つも見つけられなかった、ということを意味します。後者は、makefile は見つかったものの、その中にデフォルトゴールが含まれておらず、コマンドラインでもゴールが指定されなかった、ということを意味します。こうした状況では、GNU make にはやるべきことが何もありません。Makefileを指定する引数の項を参照してください。
コマンドラインで指定された makefile(1番目の形)、または include された makefile(2番目の形)が見つからなかった、ということです。
GNU make では、(ダブルコロンルールを除いて)一つのターゲットにつき指定できるレシピは一つだけです。すでにレシピが定義されているターゲットに対して別のレシピを与えると、この警告が出され、2番目のレシピが1番目を上書きします。一つのターゲットに複数のルールを参照してください。
これは、make が依存関係グラフの中にループを検出した、ということを意味します。つまり、ターゲット xxx の前提条件 yyy をたどり、さらにその前提条件をたどり……と追っていったところ、そのどれかがふたたび xxx に依存していた、というわけです。
これは、ふつうの(再帰展開)make 変数 xxx を定義したが、その変数を展開すると、めぐりめぐって自分自身(xxx)を参照してしまう、ということを意味します。これは許されていません。単純展開変数(「:=」または「::=」)を使うか、追加演算子(「+=」)を使ってください。変数の使い方を参照してください。
これは、変数参照または関数参照の中で、対応する閉じ括弧(丸括弧または波括弧)を書き忘れた、ということを意味します。
これは、その関数に必要な数の引数を渡していない、ということを意味します。引数の説明については、その関数のドキュメントを参照してください。テキストを変換する関数を参照してください。
これらのエラーは、形式の崩れた静的パターンルールに対して出されます(静的パターンルールの構文を参照してください)。1番目は、ルールのターゲットパターン部分が空であることを意味します。2番目は、ターゲットパターン部分に複数のパターン文字(%)があることを意味します。3番目は、ターゲットパターン部分にパターン文字が一つもないことを意味します。そして4番目は、静的パターンルールの3つの部分すべてにパターン文字(%)が含まれていることを意味します——本来、最初の部分にパターン文字を含めてはいけません。
静的パターンルールを作ろうとしているわけでもないのにこれらのエラーが出る場合は、ターゲットや前提条件のリストで使っている変数の値に、コロンが含まれていないかを確認してください。
この警告と次の警告は、サブmakeどうしが通信できるシステムにおいて、make が並列処理に関するエラー状態を検出した場合に出されます(サブmakeへのオプションの伝達を参照してください)。この警告は、make プロセスの再帰的な起動が、引数リストに「-jN」(ここで N は 1 より大きい数)を強制的に持たされた場合に出されます。たとえば、MAKE 環境変数に「make -j2」を設定していると、こうしたことが起こり得ます。この場合、そのサブmakeは他の make プロセスとは通信せず、単に自分専用のジョブが2つあるかのように振る舞います。
make プロセスどうしが通信するためには、親が子に情報を渡します。ただし、もし子プロセスが実際には make でなかった場合に問題が起こり得るため、親は子が make であると判断したときにかぎってこれを行います。親はこの判断に通常のアルゴリズムを使います(MAKE 変数の働きを参照してください)。makefile の書き方によっては、親が子を make プロセスだと認識できないことがあり、その場合、子は必要な情報の一部しか受け取れません。すると子はこの警告メッセージを出し、逐次的(シーケンシャル)な方法でビルドを進めます。
POSIX によれば、サフィックスルールに前提条件を含めることはできません。サフィックスルールになり得るルールが前提条件を持っている場合、それは奇妙なターゲット名を持つ単純な明示的ルールとして解釈されます。この要件は、POSIX 準拠モードが有効なとき(.POSIX ターゲットが定義されているとき)に守られます。GNU make の 4.3 より前のバージョンでは、警告は出されず、サフィックスルールが作られていましたが、前提条件はすべて無視され、サフィックスルールの一部にはなりませんでした。GNU make 4.3 以降では、挙動は同じですが、加えてこの警告が出されるようになりました。将来のバージョンでは、POSIX 準拠の挙動だけが唯一の挙動となります。すなわち、前提条件を持つルールはサフィックスルールにはなれなくなり、この警告も削除される予定です。