如何获取GNU Makefile中使用的shell命令的退出状态?

时间:2013-05-01 08:36:44

标签: linux shell makefile gnu-make

我在执行linux工具时有一个makefile规则。我需要检查工具命令的退出状态,如果该命令失败,则必须中止make。

我试过用$ ?, $$来检查? \ $? makefile中的etc等。但是当makefile运行时,它们会给我语法错误。

这样做的正确方法是什么?

以下是Makefile中的相关规则

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

3 个答案:

答案 0 :(得分:40)

在makefile中: -

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

makefile操作中的每一行都会调用一个新shell - 必须在命令失败的操作行中检查错误。

如果mycommand失败,则逻辑分支到echo语句,然后退出。

答案 1 :(得分:12)

以下是其他几种方法:

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

它本质上是一串shell命令,用分号分隔。  逃避任何你想要的新线路是令人讨厌的,并且很容易忘记分号,但我采用这种方法纯粹是因为上面提到的警告。

答案 2 :(得分:2)

如果你想要的只是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,在第二次尝试时,make将认为是正确的。所以你需要做一些像

这样的事情
a: b
    @gena $+ > $@ || { rm $@; exit 1; }
b:
    @genb > $@