我有一个 makefile,它有一个“应急步骤”来引导环境(如果任务在没有事先关键设置的情况下运行):
bootstrap: ensure_opam_switch_once build
.ONESHELL:
$(FRONTEND_OPAM_SWITCH):
@echo ''
@echo "$(bold)[make bootstrap]$(sgr0) An opam-switch doesn't exist for frontend/, creating one ..."
OPAMYES=true $(MAKE) init
opam exec --sw="${FRONTEND_DIR}" -- $(MAKE) bootstrap
@EXIT_CODE=$$?
@exit $$EXIT_CODE
ensure_opam_switch_once: | $(FRONTEND_OPAM_SWITCH)
init:
# this does critical first-time setup
build:
# ... everything else happens here
问题是需要为 makefile 的其余部分设置几个 shell 变量 - 并且我不能保证知道这些变量。 (
opam
用eval
设置一些东西;想想rbenv
、nvm
、pyenv
等)
我的计划/黑客是在设置后重新执行 make 任务,并在调用 make 的环境中配置这些 shell 变量。 (在上面的示例中,这就是
opam exec
线。)
但是,我现在的问题是,如果子make成功退出,那么我的
@exit $$EXIT_CODE
不会导致Make退出!它继续运行并尝试执行其他依赖项,这显然会失败,因为 outer Make 调用没有任何必要的 shell 环境。
有没有办法通过成功的退出代码来停止Make?
您可以使用条件来隐藏或不隐藏 Makefile 的某些部分。使用
PASS
make 变量定义应使用 Makefile 的哪一部分的示例:
$ cat Makefile
.PHONY: all
all:
ifeq ($(PASS),)
@echo 'PASS = $(PASS), VAR = $(VAR)'
export VAR=VAL; $(MAKE) PASS=1
else
@echo 'PASS = $(PASS), VAR = $(VAR)'
endif
$ make
PASS = , VAR =
export VAR=VAL; make PASS=1
make[1]: Entering directory 'foo'
PASS = 1, VAR = VAL
make[1]: Leaving directory 'foo'
Fwiw,
$(MAKE) exit-make
符合规则
exit-make: $(error exit-make)
.PHONY: exit-make
停止
make
,但退出代码为1“失败”,而不是您想要的0“成功”。例如
bigtmp=`find ~ -name 'tmp*.n*'`; \
if [[ $$bigtmp ]]; then echo $$bigtmp; $(MAKE) exit-make; fi
...mk:29: *** exit-make. Stop.