我想在Makefile中执行某些代码之前检查是否已设置环境变量。如果未设置,我想使用简单的错误消息抛出错误:
run:
[ -z "$(MY_APP)" ] && echo "MY_APP must be set" && exit 1
echo "MY_APP is set. Yay!"
echo "Let's continue on with the command..."
未设置MY_APP
时出现以下错误,这是所希望的:
[ -z "" ] && echo "MY_APP must be set" && exit 1
MY_APP must be set
make: *** [run] Error 1
但是,当设置为MY_APP
时,出现以下错误:
[ -z "EXAMPLE_NAME" ] && echo "MY_APP must be set" && exit 1
make: *** [run] Error 1
知道我在做什么错吗?还有更好的方法吗?
回想&&条件要求所有条件都必须为TRUE才能通过。由于第一个条件失败,因此整个命令将返回状态1,有效地停止了make
您可以使用以下内容,以便仅在缺少MY_APP时测试才会失败。
请注意,我使用的是'false'而不是'exit 1'。也最好使用'$ {MY_APP}',这样可以更轻松地从Make复制/粘贴到Shell提示符/脚本。
run:
{ [ -z "$(MY_APP)" ] && echo "MY_APP must be set" && false } || true
...
# Or just if-Then-Else
if [ -z "${MY_APP} ] ; then echo "MY_APP must be set" ; false ; fi
...
似乎您正在尝试使用Makefile运行不是构建目标的命令(目标名称run
是赠品)。您已经被Makefile和shell警告之一咬伤了。 Makefile警告:每行之后检查退出状态,如果不为零,则立即中止。 Shell警告:test
命令([
)返回非零退出状态,因此整行返回非零。
经验法则是:规则的配方应创建一个像规则目标一样的文件名。
这是一条规则(以澄清术语):
target:
recipe command lines
should create file named target
此经验法则有一些例外。最值得注意的是make clean
和make install
。两者通常都不会创建名为clean
或install
的文件。有人可以说,make run
可能也是这一经验法则的例外。
如果您的run
与典型的clean
一样简单,那么我可能同意例外。但是通常命令是使用命令行参数运行的。不久之后,您将希望make run
接受参数。使make接受自定义命令行参数根本不好玩。
您试图使用环境变量来操纵行为,而环境变量的问题要比命令行参数要少一些。但是仍然有问题,足以使您不知所措。
我的修复建议:
run
目标的情况下,在makefile周围编写包装程序外壳脚本,使makefile可以重建目标,然后运行目标。例如,如此处所述:Passing arguments to "make run"