## ## General helpers for simplified Makefiles. ## MAKEFLAGS := -r -R --no-print-directory targets := deps := deps-after := all-objs := incdeps := _all := _cleanup-y := include scripts/Makefile.rules include $(obj)/$(makefile) ## ## Append targets to be auto-cleanuped define add-cleanup-obj-c-by-name _cleanup-y+= $(1).o _cleanup-y+= $(1).i _cleanup-y+= $(1).d _cleanup-y+= $(1).s endef define add-cleanup-obj-S-by-name _cleanup-y+= $(1).o _cleanup-y+= $(1).d _cleanup-y+= $(1).i endef ## ## ## Generate a bundle of rules for C files define gen-target-c-bundle $(eval $(call gen-rule-o-from-c-by-name,$(1),$(2),$(3))) $(eval $(call gen-rule-i-from-c-by-name,$(1),$(2),$(3))) $(eval $(call gen-rule-d-from-c-by-name,$(1),$(2),$(3))) $(eval $(call gen-rule-s-from-c-by-name,$(1),$(2),$(3))) $(eval $(call add-cleanup-obj-c-by-name,$(1))) endef ## ## ## Generate a bundle of rules for S files define gen-target-S-bundle $(eval $(call gen-rule-o-from-S-by-name,$(1),$(2),$(3))) $(eval $(call gen-rule-d-from-S-by-name,$(1),$(2),$(3))) $(eval $(call gen-rule-i-from-S-by-name,$(1),$(2),$(3))) $(eval $(call add-cleanup-obj-S-by-name,$(1))) endef ## ## ## Shared or standalone targets ifneq ($(obj-y),) obj-y := $(addprefix $(obj)/, $(obj-y)) $(foreach file, \ $(obj-y), \ $(eval \ $(call gen-target-c-bundle, \ $(file:.o=),$(file:.o=)))) all-objs += $(obj-y) deps += $(obj-y:.o=.d) endif ifneq ($(obj-x),) obj-x := $(addprefix $(obj)/, $(obj-x)) obj-x := $(addsuffix $(xsuffix).o, $(obj-x:.o=)) $(foreach file, \ $(obj-x), \ $(eval \ $(call gen-target-c-bundle, \ $(file:$(xsuffix).o=),$(file:.o=)))) all-objs += $(obj-x) deps += $(obj-x:.o=.d) cleanup-y += $(obj-x) $(obj-x:.o=.d) endif ifneq ($(obj-e),) $(foreach file, \ $(obj-e), \ $(eval \ $(call gen-target-c-bundle, \ $(file:.o=),$(file:.o=)))) all-objs += $(obj-e) deps += $(obj-e:.o=.d) endif ifneq ($(asm-y),) asm-y := $(addprefix $(obj)/, $(asm-y)) $(foreach file, \ $(asm-y), \ $(eval \ $(call gen-target-S-bundle, \ $(file:.o=),$(file:.o=)))) all-objs += $(asm-y) deps += $(asm-y:.o=.d) endif ifneq ($(asm-e),) $(foreach file, \ $(asm-e), \ $(eval \ $(call gen-target-S-bundle, \ $(file:.o=),$(file:.o=)))) all-objs += $(asm-e) deps += $(asm-e:.o=.d) endif ## ## ## Standalone files where sources are kept in external ## directories. Usually needed when same source files ## are compiled with different flags. ifneq ($(obj-ext-src-y),) __obj-ext-src-y := $(addprefix $(obj)/, $(notdir $(obj-ext-src-y))) $(foreach file, \ $(obj-ext-src-y), \ $(eval \ $(call gen-target-c-bundle, \ $(file:.o=), \ $(addprefix $(obj)/,$(notdir $(file:.o=)))))) all-objs += $(__obj-ext-src-y) deps += $(__obj-ext-src-y:.o=.d) cleanup-y += $(__obj-ext-src-y) $(__obj-ext-src-y:.o=.d) endif ## ## ## Generate rules for a target define gen-target-rules $(1)-all-objs := ifneq ($($(1)-obj-y),) $(foreach file, \ $($(1)-obj-y), \ $(eval \ $(call gen-target-c-bundle, \ $(obj)/$(file:.o=), \ $(obj)/$(file:.o=), \ $($(1)-obj-y-cflags)))) $(1)-all-objs += $$(addprefix $(obj)/, $($(1)-obj-y)) deps += $$(addprefix $(obj)/, $($(1)-obj-y:.o=.d)) endif ifneq ($($(1)-obj-e),) $(foreach file, \ $($(1)-obj-e), \ $(eval \ $(call gen-target-c-bundle, \ $(file:.o=), \ $(file:.o=), \ $($(1)-obj-e-cflags)))) $(1)-all-objs += $$($(1)-obj-e) deps += $$($(1)-obj-e:.o=.d) endif ifneq ($($(1)-asm-y),) $(foreach file, \ $($(1)-asm-y), \ $(eval \ $(call gen-target-S-bundle, \ $(obj)/$(file:.o=), \ $(obj)/$(file:.o=), \ $($(1)-asm-y-asmflags)))) $(1)-all-objs += $$(addprefix $(obj)/, $($(1)-asm-y)) deps += $$($(1)-asm-y:.o=.d) endif ifneq ($($(1)-asm-e),) $(foreach file, \ $($(1)-asm-e), \ $(eval \ $(call gen-target-S-bundle, \ $(file:.o=), \ $(file:.o=), \ $($(1)-asm-e-asmflags)))) $(1)-all-objs += $$($(1)-asm-e) deps += $$($(1)-asm-e:.o=.d) endif $(1)-all-objs += $(all-objs) $$(obj)/$(1).built-in.o: $$($(1)-all-objs) $$($(1)-libs-e) $(libs-e) $$(E) " LINK " $$@ $$(Q) $$(LD) $$(ldflags-y) -r -o $$@ $$^ _all += $$(obj)/$(1).built-in.o cleanup-y += $$(obj)/$(1).built-in.o endef ## ## ## Walk over all targets and generate rules they require $(foreach target, \ $(targets), \ $(eval \ $(call gen-target-rules,$(target)))) ## ## ## No targets -- just builtin default one ifeq ($(targets),) ifneq ($(all-objs),) $(obj)/built-in.o: $(all-objs) $(libs-e) $(E) " LINK " $@ $(Q) $(LD) $(ldflags-y) -r -o $@ $^ _all += $(obj)/built-in.o cleanup-y += $(obj)/built-in.o endif endif ## ## A rule for building library. ifneq ($(lib-so),) $(obj)/$(lib-so).so: $(all-objs) $(libs-e) $(E) " LINK " $@ $(Q) $(CC) -shared $(cflags-so) -o $@ $^ $(ldflags-so) $(LDFLAGS) _all += $(obj)/$(lib-so).so cleanup-y += $(obj)/$(lib-so).so endif ## ## ## Include deps if requested ifneq ($(incdeps),) ifneq ($(deps-after),) $(deps): | $(deps-after) endif -include $(deps) endif ## ## ## Autocomplete cleanups cleanup-y += $(_cleanup-y) ## ## Predefined .PHONY targets .PHONY: all clean all: $(_all) @true clean: $(E) " CLEANUP " $(obj) $(Q) $(RM) $(cleanup-y)