Makefile:有条件退出

问题描述 投票:3回答:2

我想在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

知道我在做什么错吗?还有更好的方法吗?

bash makefile
2个回答
2
投票

回想&&条件要求所有条件都必须为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
    ...

0
投票

似乎您正在尝试使用Makefile运行不是构建目标的命令(目标名称run是赠品)。您已经被Makefile和shell警告之一咬伤了。 Makefile警告:每行之后检查退出状态,如果不为零,则立即中止。 Shell警告:test命令([)返回非零退出状态,因此整行返回非零。

经验法则是:规则的配方应创建一个像规则目标一样的文件名。

这是一条规则(以澄清术语):

target:
  recipe command lines
  should create file named target

此经验法则有一些例外。最值得注意的是make cleanmake install。两者通常都不会创建名为cleaninstall的文件。有人可以说,make run可能也是这一经验法则的例外。

如果您的run与典型的clean一样简单,那么我可能同意例外。但是通常命令是使用命令行参数运行的。不久之后,您将希望make run接受参数。使make接受自定义命令行参数根本不好玩。

您试图使用环境变量来操纵行为,而环境变量的问题要比命令行参数要少一些。但是仍然有问题,足以使您不知所措。

我的修复建议:

  • 将复杂的配方放入外壳脚本中。在那里,您可以拥有shell脚本的所有功能和灵活性,而无需makefile的笨拙。例如,如下所述:Basic if else statement in Makefile
  • [在典型的run目标的情况下,在makefile周围编写包装程序外壳脚本,使makefile可以重建目标,然后运行目标。例如,如此处所述:Passing arguments to "make run"
© www.soinside.com 2019 - 2024. All rights reserved.