diff --git a/Makefile.rules b/Makefile.rules index 8769969dc..565c115b9 100644 --- a/Makefile.rules +++ b/Makefile.rules @@ -24,6 +24,17 @@ ifeq ($(DISABLE_UI),0) endif endif +define uniq = + $(eval seen :=) + $(foreach _,$1,$(if $(filter $_,${seen}),,$(eval seen += $_))) + ${seen} +endef + +define check_duplicate = + $(eval LIST := $(sort $(foreach file_h, $(notdir $1), $(notdir $(shell find $2 -name $(file_h)))))) + $(if $(LIST), $(info [WARNING] Found duplicate files in SDK and APP: ${LIST})) +endef + # adding the correct target header to sources SDK_SOURCE_PATH += target/$(TARGET)/include @@ -35,12 +46,49 @@ ifeq ($(NO_CXNG),) INCLUDES_PATH += $(BOLOS_SDK)/lib_cxng/include endif -SOURCE_PATH += $(BOLOS_SDK)/src $(foreach libdir, $(SDK_SOURCE_PATH), $(dir $(shell find $(BOLOS_SDK)/$(libdir) -name '*.[csS]'))) $(dir $(shell find $(APP_SOURCE_PATH) -name '*.[csS]')) -SOURCE_FILES += $(shell find $(SOURCE_PATH) -name '*.[csS]') $(GLYPH_DESTC) $(APP_SOURCE_FILES) -INCLUDES_PATH += $(dir $(foreach libdir, $(SDK_SOURCE_PATH), $(dir $(shell find $(BOLOS_SDK)/$(libdir) -name '*.h')))) include $(BOLOS_SDK)/include $(BOLOS_SDK)/include/arm $(dir $(shell find $(APP_SOURCE_PATH) -name '*.h')) $(GLYPH_SRC_DIR) +# Get absolute App root directory to ensure correct stem replacement +APP_DIR := $(shell git rev-parse --show-toplevel) +ifeq ($(APP_DIR),) +MSG := "[ERROR] You should be inside a git repo (you can use 'git init')" +ifneq ($(ENABLE_SDK_WERROR),0) +$(error $(MSG)) +else +$(warning $(MSG)) +endif +endif + +# Extract BOLOS_SDK source files added by the App Makefile +APP_SRC_FROM_SDK = $(filter $(BOLOS_SDK)/%, $(APP_SOURCE_FILES)) +# Extract generated and glyphs source files added by the App Makefile +APP_SRC_GEN = $(filter $(GEN_SRC_DIR)/%, $(APP_SOURCE_FILES)) +# Extract proto source files added by the App Makefile +APP_SRC_PROTOC = $(filter %.pb.c, $(APP_SOURCE_FILES) $(SOURCE_FILES)) $(shell find $(APP_SOURCE_PATH) -name '*.pb.c') +# Filter remaining real source files from App (proto filtered globally hereafter) +APP_SRC_FILTER = $(filter-out $(APP_SRC_FROM_SDK) $(APP_SRC_GEN), $(APP_SOURCE_FILES)) + +# Separate SDK and APP and GEN sources +SOURCES_SDK += $(foreach libdir, src $(SDK_SOURCE_PATH), $(shell find $(BOLOS_SDK)/$(libdir) -name '*.[csS]')) $(APP_SRC_FROM_SDK) +SOURCES_APP += $(filter-out %.pb.c, $(abspath $(SOURCE_FILES) $(foreach libdir, $(SOURCE_PATH) $(APP_SOURCE_PATH), $(shell find $(libdir) -name '*.[csS]')) $(APP_SRC_FILTER))) +SOURCES_GEN += $(GLYPH_DESTC) $(APP_SRC_GEN) +VPATH += $(call uniq, $(dir $(SOURCES_SDK) $(SOURCES_APP) $(GLYPH_DESTC))) + +# Retrieve APP header filenames +INCLUDES_APP += $(shell find $(APP_SOURCE_PATH) -name '*.h') +# Warn if a same header filename is found in both APP and SDK +$(call check_duplicate, $(INCLUDES_APP), $(BOLOS_SDK)) +# Compute header directories list +INCLUDES_PATH += $(call uniq, $(dir $(foreach libdir, $(SDK_SOURCE_PATH), $(dir $(shell find $(BOLOS_SDK)/$(libdir) -name '*.h')))) include $(BOLOS_SDK)/include $(BOLOS_SDK)/include/arm $(dir $(INCLUDES_APP)) $(GLYPH_SRC_DIR)) + +# Separate object files from SDK and APP to avoid name conflicts +OBJECTS_SDK += $(sort $(subst $(BOLOS_SDK), $(OBJ_DIR)/sdk, $(addsuffix .o, $(basename $(SOURCES_SDK))))) +OBJECTS_APP += $(sort $(addprefix $(OBJ_DIR)/app, $(addsuffix .o, $(basename $(foreach f, $(SOURCES_APP), $(shell echo $(f) | sed "s|$(APP_DIR)||" 2>/dev/null)))))) +OBJECTS_GEN += $(sort $(SOURCES_GEN:%c=%o)) +OBJECTS_PROTOC += $(sort $(addprefix $(OBJ_DIR)/, $(addsuffix .o, $(basename $(APP_SRC_PROTOC))))) +OBJECT_FILES = $(OBJECTS_GEN) $(OBJECTS_PROTOC) $(OBJECTS_APP) $(OBJECTS_SDK) +OBJECTS_DIR += $(sort $(dir $(OBJECT_FILES))) -VPATH += $(dir $(SOURCE_FILES)) -OBJECT_FILES += $(sort $(addprefix $(OBJ_DIR)/, $(addsuffix .o, $(basename $(notdir $(SOURCE_FILES)))))) -DEPEND_FILES += $(sort $(addprefix $(DEP_DIR)/, $(addsuffix .d, $(basename $(notdir $(SOURCE_FILES)))))) +# Separate dependency files from SDK and APP to avoid name conflicts +DEPEND_FILES = $(subst $(OBJ_DIR), $(DEP_DIR), $(addsuffix .d, $(basename $(OBJECT_FILES)))) +DEPEND_DIR += $(sort $(dir $(DEPEND_FILES))) include $(BOLOS_SDK)/Makefile.rules_generic diff --git a/Makefile.rules_generic b/Makefile.rules_generic index 584fe343e..a3170dccd 100644 --- a/Makefile.rules_generic +++ b/Makefile.rules_generic @@ -71,7 +71,7 @@ BUILD_DEPENDENCIES += $(APP_CUSTOM_BUILD_DEPENDENCIES) prepare: $(L)echo Prepare directories - @mkdir -p $(BIN_DIR) $(OBJ_DIR) $(DBG_DIR) $(DEP_DIR) $(GEN_SRC_DIR) bin debug + @mkdir -p $(BIN_DIR) $(OBJ_DIR) $(OBJECTS_DIR) $(DBG_DIR) $(DEP_DIR) $(DEPEND_DIR) $(GEN_SRC_DIR) bin debug $(BUILD_DEPENDENCIES): prepare @@ -80,6 +80,38 @@ DBG_TARGETS := debug/app.map debug/app.asm default: $(BIN_TARGETS) $(DBG_TARGETS) +# Glyphs target +$(GEN_SRC_DIR)/%.o: $(GEN_SRC_DIR)/%.c $(BUILD_DEPENDENCIES) prepare + @echo "[CC] $@" + $(L)$(call cc_cmdline,$(INCLUDES_PATH), $(DEFINES),$<,$@) + +# App files targets +$(OBJ_DIR)/app/%.o: $(APP_DIR)/%.c $(BUILD_DEPENDENCIES) prepare + @echo "[CC] $@" + $(L)$(call cc_cmdline,$(INCLUDES_PATH), $(DEFINES),$<,$@) + +$(OBJ_DIR)/app/%.o: $(APP_DIR)/%.s $(BUILD_DEPENDENCIES) prepare + @echo "[AS] $@" + $(L)$(call as_cmdline,$(INCLUDES_PATH), $(DEFINES),$<,$@) + +$(OBJ_DIR)/app/%.o: $(APP_DIR)/%.S $(BUILD_DEPENDENCIES) prepare + @echo "[AS] $@" + $(L)$(call as_cmdline,$(INCLUDES_PATH), $(DEFINES),$<,$@) + +# SDK files targets +$(OBJ_DIR)/sdk/%.o: $(BOLOS_SDK)/%.c $(BUILD_DEPENDENCIES) prepare + @echo "[CC] $@" + $(L)$(call cc_cmdline,$(INCLUDES_PATH), $(DEFINES),$<,$@) + +$(OBJ_DIR)/sdk/%.o: $(BOLOS_SDK)/%.s $(BUILD_DEPENDENCIES) prepare + @echo "[AS] $@" + $(L)$(call as_cmdline,$(INCLUDES_PATH), $(DEFINES),$<,$@) + +$(OBJ_DIR)/sdk/%.o: $(BOLOS_SDK)/%.S $(BUILD_DEPENDENCIES) prepare + @echo "[AS] $@" + $(L)$(call as_cmdline,$(INCLUDES_PATH), $(DEFINES),$<,$@) + +# Generic targets $(OBJ_DIR)/%.o: %.c $(BUILD_DEPENDENCIES) prepare @echo "[CC] $@" $(L)$(call cc_cmdline,$(INCLUDES_PATH), $(DEFINES),$<,$@) @@ -163,7 +195,7 @@ endif # cc_cmdline(include,defines,src,dest) Macro that is used to format arguments for the compiler # dependency files are generated along the object file -cc_cmdline = $(CC) -c $(CFLAGS) -MMD -MT $(OBJ_DIR)/$(basename $(notdir $(4))).o -MF $(DEP_DIR)/$(basename $(notdir $(4))).d $(addprefix -D,$(2)) $(addprefix -I,$(1)) -o $(4) $(3) +cc_cmdline = $(CC) -c $(CFLAGS) -MMD -MT $(4) -MF $(subst $(OBJ_DIR), $(DEP_DIR), $(addsuffix .d, $(basename $(4)))) $(addprefix -D,$(2)) $(addprefix -I,$(1)) -o $(4) $(3) as_cmdline = $(AS) -c $(AFLAGS) $(addprefix -D,$(2)) $(addprefix -I,$(1)) -o $(4) $(3)