# Setup build parameters. OBJ_DIR_STAMP := $(OBJ_DIR)/dir.stamp OBJ_INC_DIR := $(OBJ_DIR)/inc OBJ_INC_DIR_STAMP := $(OBJ_INC_DIR)/dir.stamp CLEAN_FILES := CLEAN_DIRS := EXTRA_CLEAN := # Define directories variables. # Call with: type, typevar define DIR_template $2_OBJ_TYPE_DIR := $$(OBJ_DIR)/$1 $2_OBJ_TYPE_DIR_STAMP := $$(OBJ_DIR)/$1/dir.stamp $2_OBJ_INC_DIR := $$($2_OBJ_TYPE_DIR)/inc $2_OBJ_INC_DIR_STAMP := $$($2_OBJ_INC_DIR)/dir.stamp endef $(call foreach_type,DIR_template) OBJ_TYPE_DIRS := $(call gather_type,OBJ_TYPE_DIR) OBJ_TYPE_DIR_STAMPS := $(call gather_type,OBJ_TYPE_DIR_STAMP) OBJ_INC_DIRS := $(OBJ_INC_DIR) $(call gather_type,OBJ_INC_DIR) OBJ_INC_DIR_STAMPS := $(OBJ_INC_DIR_STAMP) $(call gather_type,OBJ_INC_DIR_STAMP) # Generated program and library files. # Call with: type, typevar define PRODUCTS_template $2_PROGRAMS_LINKED := $$(filter-out %.a,$$($2_PROGRAMS)) $2_PROGRAMS_LIBS := $$(filter %.a,$$($2_PROGRAMS)) $2_EXES := $$(call prog2exe,$$($2_PROGRAMS_LINKED),$1) $2_LIBS := $$(call prog2lib,$$($2_PROGRAMS_LIBS)) ifneq ($1,host) $2_BINS := $$(call prog2bin,$$($2_PROGRAMS_LINKED)) $2_ROMS := $$(call prog2rom,$$($2_PROGRAMS_LINKED)) $2_LSTS := $$(call prog2lst,$$($2_PROGRAMS_LINKED)) $2_SIZES := $$(call prog2size,$$($2_PROGRAMS_LINKED)) endif $2_PRODUCTS = $$($2_EXES) $$($2_LIBS) $$($2_BINS) $$($2_ROMS) $$($2_LSTS) $$($2_SIZES) endef $(call foreach_type,PRODUCTS_template) ALL_PROGRAMS := $(call gather_type,PROGRAMS) # List included modules. # Call with: type, typevar define MODULES_template $2_MODULES := $$(sort $$(foreach program,$$($2_PROGRAMS),$$($$(program)_MODULES))) $2_CONFIG_MODULES := $$(sort $$(foreach program,$$($2_PROGRAMS),$$($$(program)_CONFIG_MODULES))) $2_CONFIG_MODULES += common/defs $2_MODULES_CONFIG := endef $(call foreach_type,MODULES_template) ifdef SOURCES $(error the SOURCES variable should not be defined) endif ifdef MODULES $(error the MODULES variable should not be defined) endif ifdef CONFIG $(error the CONFIG variable should not be defined) endif # For each used module, include its Module file, get its source files, and # module dependencies. # Call with: module, modulevar, type, typevar define MODULE_template # Include module file. $(call exportvars,$3,$($4_CONFIG_ITEMS)) BUILD_TYPE := $3 BUILD_TYPE_VAR := $4 MODULE := $1 MODULE_VAR := $2 include $$(BASE)/$1/Module MODULE_VAR := MODULE := BUILD_TYPE_VAR := BUILD_TYPE := $(call unexportvars,$3,$($4_CONFIG_ITEMS)) # Use defined sources or overridden ones. SOURCES := $$(call default2,$4_$2_MODULE_SOURCES,$2_MODULE_SOURCES,$$(SOURCES)) $4_$2_MODULE_SOURCES := $$(call src2src,$$(SOURCES),$1/src) SOURCES := # Merge module configuration. $4_MODULES_CONFIG += $$(if $$(CONFIG),$$(BASE)/$1/$$(CONFIG),$$(wildcard $$(BASE)/$1/Config)) CONFIG := # Add any dependent modules. MODULES := $$(call default2,$4_$2_MODULE_MODULES,$2_MODULE_MODULES,$$(MODULES)) $4_$2_MODULE_MODULES := $$(MODULES) MODULES := NEW_MODULES := $$(filter-out $$($4_MODULES),$$($4_$2_MODULE_MODULES)) $4_MODULES := $$(sort $$($4_MODULES) $$(NEW_MODULES)) # Recursively call itself on new modules. $$(foreach module,$$(NEW_MODULES),\ $$(eval $$(call MODULE_template,$$(module),$$(call mod2var,$$(module)),$3,$4))) NEW_MODULES := endef $(foreach type,$(BUILD_TYPES),\ $(foreach module,$($(call type2var,$(type))_MODULES),\ $(eval $(call MODULE_template,$(module),$(call mod2var,$(module)),$(type),$(call type2var,$(type)))))) # Add any dependent modules to programs. # Call with: program, type, typevar define PROGRAM_MODULES_template NEW_MODULES := $$(foreach module,$$($1_MODULES),$$($3_$$(call mod2var,$$(module))_MODULE_MODULES)) NEW_MODULES := $$(filter-out $$($1_MODULES),$$(NEW_MODULES)) $1_MODULES := $$(sort $$($1_MODULES) $$(NEW_MODULES)) $$(if $$(NEW_MODULES),$$(eval $$(call PROGRAM_MODULES_template,$1,$2,$3))) NEW_MODULES := endef $(foreach type,$(BUILD_TYPES),\ $(foreach program,$($(call type2var,$(type))_PROGRAMS),\ $(eval $(call PROGRAM_MODULES_template,$(program),$(type),$(call type2var,$(type)))))) # For each module included only for configuration # Call with: module, modulevar, type, typevar define MODULE_CONFIG_template # Include module file. $(call exportvars,$3,$($4_CONFIG_ITEMS)) BUILD_TYPE := $3 MODULE := $1 include $$(BASE)/$1/Module MODULE := BUILD_TYPE := $(call unexportvars,$3,$($4_CONFIG_ITEMS)) # Ignore sources SOURCES := # Merge module configuration. $4_MODULES_CONFIG += $$(if $$(CONFIG),$$(BASE)/$1/$$(CONFIG),$$(wildcard $$(BASE)/$1/Config)) CONFIG := # Add any dependent modules. MODULES := $$(call default2,$4_$2_MODULE_MODULES,$2_MODULE_MODULES,$$(MODULES)) $4_$2_MODULE_MODULES := $$(MODULES) MODULES := NEW_MODULES := $$(filter-out $$($4_MODULES) $$($4_CONFIG_MODULES),$$($4_$2_MODULE_MODULES)) $4_CONFIG_MODULES := $$(sort $$($4_CONFIG_MODULES) $$(NEW_MODULES)) # Recursively call itself on new modules. $$(foreach module,$$(NEW_MODULES),\ $$(eval $$(call MODULE_CONFIG_template,$$(module),$$(call mod2var,$$(module)),$3,$4))) NEW_MODULES := endef $(foreach type,$(BUILD_TYPES),\ $(foreach module,$($(call type2var,$(type))_CONFIG_MODULES),\ $(eval $(call MODULE_CONFIG_template,$(module),$(call mod2var,$(module)),$(type),$(call type2var,$(type)))))) # For each program, list sources and objects. # Call with: program, type, typevar define PROGRAM_template $1_SOURCES := $$(call src2src,$$($1_SOURCES),src) $1_OBJECTS := $$(call src2obj,$$($1_SOURCES),$2) $1_MODULES_SOURCES := $$(foreach module,$$($1_MODULES),$$($3_$$(call mod2var,$$(module))_MODULE_SOURCES)) $1_MODULES_OBJECTS := $$(call src2obj,$$($1_MODULES_SOURCES),$2) endef $(foreach type,$(BUILD_TYPES),\ $(foreach program,$($(call type2var,$(type))_PROGRAMS),\ $(eval $(call PROGRAM_template,$(program),$(type),$(call type2var,$(type)))))) # Define sources lists for each build types. # Call with: type, typevar define SOURCES_template $2_SOURCES := $$(sort $$(foreach program,$$($2_PROGRAMS),$$($$(program)_SOURCES) $$($$(program)_MODULES_SOURCES))) endef $(call foreach_type,SOURCES_template) vpath %.c $(BASE) vpath %.cpp $(BASE) vpath %.S $(BASE)