测试文件是否存在于makefile目标中,如果不存在则退出

Ale*_*lds 26 gnu makefile

如果文件不存在,有没有办法退出错误条件?我目前正在做这样的事情:

all: foo

foo:
    test -s /opt/local/bin/gsort || echo "GNU sort does not exist! Exiting..." && exit
Run Code Online (Sandbox Code Playgroud)

运行make运行all目标,运行foo.

期望是如果test -s条件失败,则echo/exit执行语句.

但是,即使/usr/bin/gsort存在,我也会获得echo语句的结果,但exit命令不会运行.这与我希望完成的事情相反.

做上述事情的正确方法是什么?

Kin*_*cal 28

我意识到这一点有点陈旧,但你甚至不需要使用子shell来测试Make中是否存在文件.

它还取决于您希望/期望它如何运行.

使用通配符函数,如下所示:

all: foo
foo:
ifeq (,$(wildcard /opt/local/bin/gsort))
    $(error GNU Sort does not exist!)
endif
Run Code Online (Sandbox Code Playgroud)

这是一个很好的方法.请注意,ifeq子句不是缩进的,因为它是在目标本身之前计算的.

如果您希望无条件地为每个目标发生这种情况,您可以将其移到目标之外:

ifeq (,$(wildcard /opt/local/bin/gsort))
$(error GNU Sort does not exist!)
endif
Run Code Online (Sandbox Code Playgroud)


Ola*_*che 20

exit单独返回最后执行的命令的状态.在这种情况下,它返回零,这意味着一切正常.

这是因为||并且&&具有相同的优先级,并且shell将命令解释为就像它被写入一样

( test ... || echo ... ) && exit
Run Code Online (Sandbox Code Playgroud)

如果要发出故障信号,则必须以非零值退出,例如exit 1.如果你想回显退出,只需按顺序将命令分开;

all: foo

foo:
    test -s /opt/local/bin/gsort || { echo "GNU sort does not exist! Exiting..."; exit 1; }
Run Code Online (Sandbox Code Playgroud)


lai*_*dir 7

make中的每个命令行都在自己的子shell中运行.所以运行exit只退出该子shell - 而不是整个makefile.默认情况下,make如果任何子shell返回不成功的退出状态,则执行将停止(按照惯例,0表示成功,因此其他任何操作都将停止执行).最简单的方法就是使用test命令的退出状态:

all: foo

foo:
    test -s /opt/local/bin/gsort
Run Code Online (Sandbox Code Playgroud)

打印诊断消息会使事情变得复杂,因为命令echo会返回退出状态0,导致make认为一切正常.要解决此问题,您需要在其后运行一个命令,使子shell具有非零退出状态:

all: foo

foo:
    test -s /opt/local/bin/gsort || { echo "GNU sort does not exist! Exiting..."; exit 1; }
Run Code Online (Sandbox Code Playgroud)

甚至只是

all: foo

foo:
    test -s /opt/local/bin/gsort || { echo "GNU sort does not exist! Exiting..."; false; }
Run Code Online (Sandbox Code Playgroud)