How to exit a makefile without running other tasks, with a successful exit-code?

987 views Asked by At

I've got a makefile that has a 'contingency step' to bootstrap the environment if the task is run without prior, critical setup:

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

The issue is that several shell-variables need to be set for the rest of the makefile — and I'm not guaranteed to know those variables. (opam sets up some stuff with eval; think rbenv, nvm, pyenv, etc.)

My plan/hack here is to re-execute the make-task after setup, with those shell-variables configured in the environment make is invoked from. (In the above example, that's the opam exec line.)

However, my issue at the moment is that, if the sub-make exits with success, then my @exit $$EXIT_CODE doesn't result in Make exiting! It continues to run and attempt to execute other dependents, which obviously fails because the outer Make invocation doesn't have any of the necessary shell-environment.

Is there a way to stop Make with a successful exit-code?

2

There are 2 answers

0
Renaud Pacalet On

You could use conditionals to hide or not parts of your Makefile. Example with a PASS make variable that defines what part of the Makefile shall be used:

$ 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'
0
denis On

Fwiw, the following stops make, but with exit code 1 "failure", not success as you want:

... $(MAKE) exit-make

exit-make:
    $(error exit-make)
.PHONY: exit-make

#   example --
bigtmp=`find ~ -name 'tmp*.n*'`; \
if [[ $$bigtmp ]]; then echo $$bigtmp; $(MAKE) exit-make; fi

...mk:29: *** exit-make.  Stop.