web-dev-qa-db-ja.com

GNU Makefileで使用されるシェルコマンドの終了ステータスを取得する方法?

Linuxツールの実行中にメイクファイルルールがあります。ツールコマンドの終了ステータスを確認する必要があり、そのコマンドが失敗した場合は、メイクを中止する必要があります。

$?、$$?で確認してみました\ $?メイクファイル内など。ただし、makefileの実行時に構文エラーが発生します。

これを行う正しい方法は何ですか?

Makefileの関連ルールは次のとおりです。

    mycommand \
    if [ $$? -ne 0 ]; \
    then \
        echo "mycommand failed"; \
        false; \
    fi
25
Lunar Mushrooms

Makefile-:で

mycommand || (echo "mycommand failed $$?"; exit 1)

Makefileアクションの各行は新しいシェルを呼び出します。コマンドが失敗したアクション行でエラーを確認する必要があります。

Mycommandが失敗すると、ロジックはechoステートメントに分岐して終了します。

43
suspectus

他のアプローチをいくつか紹介します。


Shell.SHELLSTATUS

some_recipe:
    @echo $(Shell echo 'doing stuff'; exit 123)
    @echo 'command exited with $(.SHELLSTATUS)'
    @exit $(.SHELLSTATUS)

出力:

$ make some_recipe

doing stuff
command exited with 123      
make: *** [Makefile:4: some_recipe] Error 123

Shellコマンドの出力はストリーミングされないという警告があります。そのため、終了時にstdoutにダンプするだけです。


$?

some_recipe:
    @echo 'doing stuff'; exit 123;\
    EXIT_CODE=$$?;\
    echo "command exited with $$EXIT_CODE";\
    exit $$EXIT_CODE

出力:

$ make some_recipe

doing stuff                  
command exited with 123      
make: *** [Makefile:2: some_recipe] Error 123

基本的には、セミコロンで区切られたシェルコマンドの1つの文字列です。必要な新しい行をエスケープするのは面倒で、セミコロンを忘れるのは簡単ですが、上記の警告のために純粋にこのアプローチを採用しました。

14
c24w

ツールがゼロ以外のステータスで終了する場合、makeを中止するだけであれば、makeはデフォルトで既にそれを実行しています。

Makefile

a: b
    @echo making $@
b:
    @echo making $@
    @false
    @echo already failed

。これは私のmakeで起こることです:

$ make
making b
make: *** [Makefile:6: b] Error 1

失敗した場合に備えて、部分的にまたは完全に作成されたターゲットが削除されていることを確認してください。たとえば、これ

a: b
    @gena $+ > $@
b:
    @genb > $@

間違っています:最初の試行でgenbが失敗すると、おそらく間違ったbが残ります。これは、2回目の試行でmakeが正しいと見なします。だからあなたは次のようなことをする必要があります

a: b
    @gena $+ > $@ || { rm $@; exit 1; }
b:
    @genb > $@
2
reinierpost