web-dev-qa-db-ja.com

GNU makeは「最初のターゲットの前にコマンドを開始する」エラーを生成します

メイクファイルで、ライブラリの存在を確認し、有益なエラーメッセージを表示したいと思います。ファイルが見つからないときにmakeプロセスを終了する条件を作成しました。

 9: ifeq ($(${JSONLIBPATH}),)
10:    JSONLIBPATH = ${ALTJSONLIBDIR}/${LIBJSON}
11: endif
12: ifeq ($(${JSONLIBPATH}),)
13:    $(error JSON library is not found. Please install libjson before building)
14: endif 

私のメイクファイルは13行目で止まっています:

Makefile:13: *** commands commence before first target.  Stop.

13行目以降、私のmakefileにはターゲットがあります。

この条件ブロックをターゲット(たとえば、isJSONLibraryInstalledというターゲット)に配置しようとしましたが、これは正しく実行されません。

ターゲットを処理する前に、ファイルの存在を確認し、エラーケースを処理する方法を教えてください。これが愚かな質問である場合はおApび申し上げます。

49
Alex Reynolds

まず、現在のパスにちなんで名付けられた変数の内容を見ていますが、これはおそらくあなたが望んでいるものではないでしょう。単純な環境変数参照は、$(name)ではなく、$(${name})または_${name}_です。このため、13行目は常に評価されます。

第二に、$(error ...)式のインデントが詰まっていると思います。式は空の文字列に解決されますが、行の先頭にはまだコマンドを示すタブ文字があります。これはルールの外に存在することはできません。

インデントにタブではなくスペースを使用するとうまくいくと思います。

75
Simon Richter

エラーメッセージを作成するときは、必ず エラーメッセージのドキュメント を確認してください。

GNU Make 3.81(errorは新しいバージョンから削除されたようです)]で、

これは、メイクファイルの最初のものがコマンドスクリプトの一部のように見えることを意味します。TAB文字で始まり、有効なmakeコマンド(変数の割り当てなど)のようには見えません。コマンドスクリプトは常にターゲットに関連付けられている必要があります。

問題をさらに混乱させているのは、「合法的なmakeコマンドではないように見える」という部分です。その理由は次のとおりです。

    a := b
    $(error a)

エラーは1行目ではなく2行目で発生します。makeは、割り当てのように解析可能なステートメントを受け入れるだけなので、次のように動作します。

    a := b
a:
    echo $a

注: SOは現在、コード内でタブをスペースに変換します なので、上記のコードをエディターにコピーすることはできません。

私にとって、これはコネクタの前の不要な空白でした。 slickEditで、すべての特殊文字を表示するオプションを選択し、黒い羊に気付きました。

1
RobGajula