This writes the last target name into a file, .default_make_target
, which is then used as the default target when no arguments are given. It shows the correct target name in the output and exits with Nothing to be done for 'target'.
correctly when its out of date.
DEFAULT_TARGET=debug
LAST_TARGET_FILE=.default_make_target
LAST_TARGET=$(foreach f, $(wildcard $(LAST_TARGET_FILE)), $(shell cat $(f)))
.PHONY: debug release clean
.DEFAULT_GOAL:= $(or $(LAST_TARGET),$(DEFAULT_TARGET))
debug: CFLAG_OPTS+= -g
debug: CHOSEN_TARGET=debug
debug: real_target
release: CFLAG_OPTS+= -O3
release: CHOSEN_TARGET=release
release: real_target
real_target:
@echo $(CHOSEN_TARGET) > $(LAST_TARGET_FILE)
echo '$(CFLAG_OPTS)' > real_target #just an example
clean:
rm -f real_target
Testing...
> make debug
echo '-g' > real_target
> make
make: Nothing to be done for 'debug'.
> make clean
rm -f real_target
> make release
echo '-O3' > real_target
> make
make: Nothing to be done for 'release'.
>
*UPDATED:
Previously I had @echo debug > $(LAST_TARGET_FILE)
as the body of the phony debug rule (and likewise for release), which meant debug
/release
were always out of date. Instead, it needs to be run in the body of a real target, for which CHOSEN_TARGET
is set.
Rather than default: $(if...)
, using .DEFAULT_GOAL:=
now causes the correct target to be printed when up to date. For example make: Nothing to be done for 'release'.