Tux*_*ude 25 shell makefile return-value gnu-make
在我的Makefile中,我需要测试当前目录是否是SVN repo,如果不是,我想在Makefile中使用$(error)指令指出错误.
所以我计划使用$(shell svn info.)的返回值,但我不确定如何从Makefile中获取此值.
注意:我不是试图在配方中获取返回值,而是在Makefile的中间.
现在我正在做这样的事情,这只是因为stdout在出错时是空白的:
SVN_INFO := $(shell svn info . 2> /dev/null)
ifeq ($(SVN_INFO),)
$(error "Not an SVN repo...")
endif
Run Code Online (Sandbox Code Playgroud)
我仍然想知道是否有可能在Makefile中获取返回值.
eri*_*ous 27
如何$?用于回显最后一个命令的退出状态?
SVN_INFO := $(shell svn info . 2> /dev/null; echo $$?)
ifeq ($(SVN_INFO),1)
$(error "Not an SVN repo...")
endif
ste*_*nct 12
如果你想保留原始输出,那么你需要做一些技巧.如果您有幸拥有GNU Make 4.2(2016-05-22发布)或更高版本,您可以.SHELLSTATUS按如下方式使用该变量.
var := $(shell echo "blabla" ; false)
ifneq ($(.SHELLSTATUS),0)
$(error shell command failed! output was $(var))
endif
all:
@echo Never reached but output would have been $(var)
Run Code Online (Sandbox Code Playgroud)
或者,您可以使用临时文件或使用Make eval来将字符串和/或退出代码存储到Make变量中.下面的例子完成了这个,但我肯定希望看到比这个令人尴尬的复杂版本更好的实现.
ret := $(shell echo "blabla"; false; echo " $$?")
rc := $(lastword $(ret))
# Remove the last word by calculating <word count - 1> and
# using it as the second parameter of wordlist.
string:=$(wordlist 1,$(shell echo $$(($(words $(ret))-1))),$(ret))
ifneq ($(rc),0)
$(error shell command failed with $(rc)! output was "$(string)")
endif
all:
@echo Never reached but output would have been \"$(string)\"
Run Code Online (Sandbox Code Playgroud)
Tux*_*ude 11
这对我来说很好 - 基于@eriktous的回答,重新定向stdout的一个小修改,以及在有效的svn repo上跳过svn info的输出.
SVN_INFO := $(shell svn info . 1>&2 2> /dev/null; echo $$?)
ifneq ($(SVN_INFO),0)
$(error "Not an SVN repo...")
endif
Run Code Online (Sandbox Code Playgroud)
也许是这样的?
IS_SVN_CHECKED_OUT := $(shell svn info . 1>/dev/null 2>&1 && echo "yes" || echo "no")
ifne ($(IS_SVN_CHECKED_OUT),yes)
$(error "The current directory must be checked out from SVN.")
endif
Run Code Online (Sandbox Code Playgroud)
我使用 .NOTPARALLEL 和 make 函数:
.NOTPARALLEL:
# This function works almost exactly like the builtin shell command, except it
# stops everything with an error if the shell command given as its argument
# returns non-zero when executed. The other difference is that the output
# is passed through the strip make function (the shell function strips only
# the last trailing newline). In practice this doesn't matter much since
# the output is usually collapsed by the surroundeing make context to the
# same result produced by strip.
SHELL_CHECKED = \
$(strip \
$(if $(shell (($1) 1>/tmp/SC_so) || echo nonempty), \
$(error shell command '$1' failed. Its stderr should be above \
somewhere. Its stdout is in '/tmp/SC_so'), \
$(shell cat /tmp/SC_so)))
Run Code Online (Sandbox Code Playgroud)