summaryrefslogtreecommitdiff
path: root/mk/footer.mk
diff options
context:
space:
mode:
Diffstat (limited to 'mk/footer.mk')
-rw-r--r--mk/footer.mk119
1 files changed, 119 insertions, 0 deletions
diff --git a/mk/footer.mk b/mk/footer.mk
new file mode 100644
index 0000000..c6d19d3
--- /dev/null
+++ b/mk/footer.mk
@@ -0,0 +1,119 @@
+define FOOTER
+SUBDIRS_$(d) := $(patsubst %/,%,$(addprefix $(d)/,$(SUBDIRS)))
+
+ifneq ($(strip $(OBJS)),)
+OBJS_$(d) := $(addprefix $(OBJPATH)/,$(OBJS))
+else # Populate OBJS_ from SRCS
+
+# Expand wildcards in SRCS if they are given
+ifneq ($(or $(findstring *,$(SRCS)),$(findstring ?,$(SRCS)),$(findstring ],$(SRCS))),)
+ SRCS := $(notdir $(foreach sd,. $(SRCS_VPATH),$(wildcard $(addprefix $(d)/$(sd)/,$(SRCS)))))
+ SRCS := $(filter-out $(SRCS_EXCLUDES), $(SRCS))
+endif
+
+OBJS_$(d) := $(addprefix $(OBJPATH)/,$(addsuffix .o,$(basename $(SRCS))))
+endif
+
+CLEAN_$(d) := $(CLEAN_$(d)) $(filter /%,$(CLEAN) $(TARGETS)) $(addprefix $(d)/,$(filter-out /%,$(CLEAN)))
+
+ifdef TARGETS
+abs_tgts := $(filter /%, $(TARGETS))
+rel_tgts := $(filter-out /%,$(TARGETS))
+TARGETS_$(d) := $(abs_tgts) $(addprefix $(OBJPATH)/,$(rel_tgts))
+$(foreach tgt,$(filter-out $(AUTO_TGTS),$(rel_tgts)),$(eval $(call save_vars,$(OBJPATH)/,$(tgt))))
+# Absolute targets are entry points for external (sub)projects which
+# have their own build system - what is really interesting is only CMD
+# and possibly DEPS however I use this general save_vars (two more vars
+# that are not going to be used should not be a problem :P).
+$(foreach tgt,$(abs_tgts),$(eval $(call save_vars,,$(tgt))))
+else
+TARGETS_$(d) := $(OBJS_$(d))
+endif
+
+# Save user defined vars
+$(foreach v,$(VERB_VARS),$(eval $(v)_$(d) := $($v)))
+$(foreach v,$(OBJ_VARS),$(eval $(v)_$(d) := $(addprefix $(OBJPATH)/,$($v))))
+$(foreach v,$(DIR_VARS),$(eval $(v)_$(d) := $(filter /%,$($v)) $(addprefix $(d)/,$(filter-out /%,$($v)))))
+
+# Update per directory variables that are automatically inherited
+ifeq ($(origin INHERIT_DIR_VARS_$(d)),undefined)
+ INHERIT_DIR_VARS_$(d) := $(or $(INHERIT_DIR_VARS_$(parent_dir)), $(INHERIT_DIR_VARS))
+endif
+$(foreach v,$(INHERIT_DIR_VARS_$(d)),$(if $($(v)_$(d)),,$(eval $(v)_$(d) := $($(v)_$(parent_dir)))))
+
+########################################################################
+# Inclusion of subdirectories rules - only after this line one can #
+# refer to subdirectory targets and so on. #
+########################################################################
+$(foreach sd,$(SUBDIRS),$(eval $(call include_subdir_rules,$(sd))))
+
+.PHONY: dir_$(d) clean_$(d) clean_extra_$(d) clean_tree_$(d) dist_clean_$(d)
+.SECONDARY: $(OBJPATH)
+
+# Whole tree targets
+all :: $(TARGETS_$(d))
+
+clean_all :: clean_$(d)
+
+# dist_clean is optimized in skel.mk if we are building in out of project tree
+ifeq ($(strip $(TOP_BUILD_DIR)),)
+dist_clean :: dist_clean_$(d)
+
+# No point to enforce clean_extra dependency if CLEAN is empty
+ifeq ($(strip $(CLEAN_$(d))),)
+dist_clean_$(d) :
+else
+dist_clean_$(d) : clean_extra_$(d)
+endif
+ rm -rf $(DIST_CLEAN_DIR)
+endif
+
+########################################################################
+# Per directory targets #
+########################################################################
+
+# Again - no point to enforce clean_extra dependency if CLEAN is empty
+ifeq ($(strip $(CLEAN_$(d))),)
+clean_$(d) :
+else
+clean_$(d) : clean_extra_$(d)
+endif
+ rm -f $(CLEAN_DIR)/*
+
+# clean_extra is meant for the extra output that is generated in source
+# directory (e.g. generated source from lex/yacc) so I'm not using
+# TOP_BUILD_DIR below
+clean_extra_$(d) :
+ rm -rf $(filter %/,$(CLEAN_$(subst clean_extra_,,$@))); rm -f $(filter-out %/,$(CLEAN_$(subst clean_extra_,,$@)))
+
+clean_tree_$(d) : clean_$(d) $(foreach sd,$(SUBDIRS_$(d)),clean_tree_$(sd))
+
+# Skip the target rules generation and inclusion of the dependencies
+# when we just want to clean up things :)
+ifeq ($(filter clean clean_% dist_clean,$(MAKECMDGOALS)),)
+
+SUBDIRS_TGTS := $(foreach sd,$(SUBDIRS_$(d)),$(TARGETS_$(sd)))
+
+# Use the skeleton for the "current dir"
+$(eval $(call skeleton,$(d)))
+# and for each SRCS_VPATH subdirectory of "current dir"
+$(foreach vd,$(SRCS_VPATH),$(eval $(call skeleton,$(d)/$(vd))))
+
+# Target rules for all "non automatic" targets
+$(foreach tgt,$(filter-out $(AUTO_TGTS),$(TARGETS_$(d))),$(eval $(call tgt_rule,$(tgt))))
+
+# Way to build all targets in given subtree (not just current dir as via
+# dir_$(d) - see below)
+tree_$(d) : $(TARGETS_$(d)) $(foreach sd,$(SUBDIRS_$(d)),tree_$(sd))
+
+# If the directory is just for grouping its targets will be targets from
+# all subdirectories
+ifeq ($(strip $(TARGETS_$(d))),)
+TARGETS_$(d) := $(SUBDIRS_TGTS)
+endif
+
+# This is a default rule - see Makefile
+dir_$(d) : $(TARGETS_$(d))
+
+endif
+endef