Files
wild-cloud/tools/makefiles/recursive.mk

113 lines
4.0 KiB
Makefile

# Runs make in all recursive subdirectories with a Makefile, passing the make target to each.
# Directories are make'ed in top down order.
# ex: make (runs DEFAULT_GOAL)
# ex: make clean (runs clean)
# ex: make install (runs install)
mkfile_dir = $(patsubst %/,%,$(dir $(realpath $(lastword $(MAKEFILE_LIST)))))
# if IS_RECURSIVE_MAKE is set, then this is being invoked by another recursive.mk.
# in that case, we don't want any targets
ifndef IS_RECURSIVE_MAKE
.DEFAULT_GOAL := help
# make with VERBOSE=1 to print all outputs of recursive makes
VERBOSE ?= 0
RECURSIVE_TARGETS = clean test check lock install
# You can pass in a list of files or directories to retain when running `clean/git-clean`
# ex: make clean GIT_CLEAN_RETAIN=".env .data"
# As always with make, you can also set this as an environment variable
GIT_CLEAN_RETAIN ?= .env
GIT_CLEAN_EXTRA_ARGS = $(foreach v,$(GIT_CLEAN_RETAIN),--exclude !$(v))
ifeq ($(VERBOSE),0)
GIT_CLEAN_EXTRA_ARGS += --quiet
endif
.PHONY: git-clean
git-clean:
git clean -dffX . $(GIT_CLEAN_EXTRA_ARGS)
FILTER_OUT = $(foreach v,$(2),$(if $(findstring $(1),$(v)),,$(v)))
MAKE_FILES = $(shell find . -mindepth 2 -name Makefile)
ALL_MAKE_DIRS = $(sort $(filter-out ./,$(dir $(MAKE_FILES))))
ifeq ($(suffix $(SHELL)),.exe)
MAKE_FILES = $(shell dir Makefile /b /s)
ALL_MAKE_DIRS = $(sort $(filter-out $(subst /,\,$(abspath ./)),$(patsubst %\,%,$(dir $(MAKE_FILES)))))
endif
MAKE_DIRS := $(call FILTER_OUT,site-packages,$(call FILTER_OUT,node_modules,$(ALL_MAKE_DIRS)))
.PHONY: .clean-error-log .print-error-log
MAKE_CMD_MESSAGE = $(if $(MAKECMDGOALS), $(MAKECMDGOALS),)
.clean-error-log:
@$(rm_file) $(call fix_path,$(mkfile_dir)/make*.log) $(ignore_output) $(ignore_failure)
.print-error-log:
ifeq ($(suffix $(SHELL)),.exe)
@if exist $(call fix_path,$(mkfile_dir)/make_error_dirs.log) ( \
echo Directories failed to make$(MAKE_CMD_MESSAGE): && \
type $(call fix_path,$(mkfile_dir)/make_error_dirs.log) && \
($(rm_file) $(call fix_path,$(mkfile_dir)/make*.log) $(ignore_output) $(ignore_failure)) && \
exit 1 \
)
else
@if [ -e $(call fix_path,$(mkfile_dir)/make_error_dirs.log) ]; then \
echo "\n\033[31;1mDirectories failed to make$(MAKE_CMD_MESSAGE):\033[0m\n"; \
cat $(call fix_path,$(mkfile_dir)/make_error_dirs.log); \
echo ""; \
$(rm_file) $(call fix_path,$(mkfile_dir)/make*.log) $(ignore_output) $(ignore_failure); \
exit 1; \
fi
endif
.PHONY: $(RECURSIVE_TARGETS) $(MAKE_DIRS)
clean: git-clean
$(RECURSIVE_TARGETS): .clean-error-log $(MAKE_DIRS) .print-error-log
$(MAKE_DIRS):
ifdef FAIL_ON_ERROR
$(MAKE) -C $@ $(MAKECMDGOALS) IS_RECURSIVE_MAKE=1
else
@$(rm_file) $(call fix_path,$@/make*.log) $(ignore_output) $(ignore_failure)
@echo make -C $@ $(MAKECMDGOALS)
ifeq ($(suffix $(SHELL)),.exe)
@$(MAKE) -C $@ $(MAKECMDGOALS) IS_RECURSIVE_MAKE=1 1>$(call fix_path,$@/make.log) $(stderr_redirect_stdout) || \
( \
(findstr /c:"*** No" $(call fix_path,$@/make.log) ${ignore_output}) || ( \
echo $@ >> $(call fix_path,$(mkfile_dir)/make_error_dirs.log) && \
$(call touch,$@/make_error.log) \
) \
)
@if exist $(call fix_path,$@/make_error.log) echo make -C $@$(MAKE_CMD_MESSAGE) failed:
@if exist $(call fix_path,$@/make_error.log) $(call touch,$@/make_print.log)
@if "$(VERBOSE)" neq "0" $(call touch,$@/make_print.log)
@if exist $(call fix_path,$@/make_print.log) type $(call fix_path,$@/make.log)
else
@$(MAKE) -C $@ $(MAKECMDGOALS) IS_RECURSIVE_MAKE=1 1>$(call fix_path,$@/make.log) $(stderr_redirect_stdout) || \
( \
grep -qF "*** No" $(call fix_path,$@/make.log) || ( \
echo "\t$@" >> $(call fix_path,$(mkfile_dir)/make_error_dirs.log) ; \
$(call touch,$@/make_error.log) ; \
) \
)
@if [ -e $(call fix_path,$@/make_error.log) ]; then \
echo "\n\033[31;1mmake -C $@$(MAKE_CMD_MESSAGE) failed:\033[0m\n" ; \
fi
@if [ "$(VERBOSE)" != "0" -o -e $(call fix_path,$@/make_error.log) ]; then \
cat $(call fix_path,$@/make.log); \
fi
endif
@$(rm_file) $(call fix_path,$@/make*.log) $(ignore_output) $(ignore_failure)
endif # ifdef FAIL_ON_ERROR
endif # ifndef IS_RECURSIVE_MAKE
include $(mkfile_dir)/shell.mk