build: add root Makefile [1/1]

PD#SWPL-61282

Problem:
Add root Makefile

Solution:
Add root Makefile

Verify:
ad401_a113l

Signed-off-by: kelvin.zhang <kelvin.zhang@amlogic.com>
Change-Id: If7357381ce2da756459fffe021ee23e0d6743c18
diff --git a/Makefile b/Makefile
new file mode 100755
index 0000000..ebbb5dc
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,258 @@
+################################################################
+# Root Makefile of the whole project
+################################################################
+
+################################################################
+# Basic Definitions
+################################################################
+BOOT		:=
+KERNEL		?= freertos
+
+################################################################
+# Directories and Files
+################################################################
+SHELL		:= /bin/bash
+PWD		:= $(shell pwd)
+PRJDIR		:= $(PWD)
+
+app_DIR		:= $(PRJDIR)/apps
+bootloader_DIR	:= $(PRJDIR)/$(BOOT)
+build_DIR	:= $(PRJDIR)/build
+docs_DIR	:= $(PRJDIR)/docs
+kernel_DIR	:= $(PRJDIR)/kernel/$(KERNEL)
+fw_DIR		:= $(PRJDIR)/firmware
+product_DIR	:= $(PRJDIR)/products
+sign_tool_DIR	:= $(PRJDIR)/tools/sign_tool
+adnl_DIR	:= $(PRJDIR)/tools/adnl
+
+BUILD_DIR		:= $(PRJDIR)/output/$(BOARD)-$(PRODUCT)
+docs_BUILD_DIR		:= $(PRJDIR)/output/docs
+bootloader_BUILD_DIR	:= $(BUILD_DIR)/$(BOOT)
+kernel_BUILD_DIR	:= $(BUILD_DIR)/$(KERNEL)
+sign_tool_BUILD_DIR	:= $(sign_tool_DIR)
+adnl_BUILD_DIR		:= $(adnl_DIR)
+
+bootloader_BIN		:= $(bootloader_BUILD_DIR)/$(BOOT)/ext/mcuboot/mcuboot.bin
+kernel_BIN		:= $(kernel_BUILD_DIR)/$(KERNEL).bin
+fw_BIN			:= $(fw_DIR)/wcn-modem.bin
+adnl_BIN		:= $(adnl_BUILD_DIR)/adnl
+
+DIST_DIR		:= $(BUILD_DIR)/images
+bootloader_dist_BIN	:= $(DIST_DIR)/mcuboot-signed.bin
+kernel_dist_BIN		:= $(DIST_DIR)/$(KERNEL)-signed.bin
+fw_dist_BIN		:= $(DIST_DIR)/wcn-modem.bin
+adnl_dist_BIN		:= $(DIST_DIR)/adnl
+
+bootloader_KEYPATH	= $(build_DIR)/key/rsa/3072
+kernel_KEYPATH		= $(build_DIR)/key/rsa/2048
+SIGNTOOL		= $(sign_tool_DIR)/imgtool.py
+
+SDK_BASE	:= $(PRJDIR)
+toolchain_DIR	:= $(build_DIR)/toolchains/$(COMPILER)-$(TOOLCHAIN_KEYWORD)
+CROSSTOOL	:= $(build_DIR)/toolchains/$(COMPILER)*$(TOOLCHAIN_KEYWORD)*.tar.xz
+PATH		:= $(toolchain_DIR)/bin:$(PATH)
+
+export PATH ARCH BOARD KERNEL SDK_BASE
+
+################################################################
+# Macros
+################################################################
+# MESSAGE Macro -- display a message in bold type
+MESSAGE = echo "$(TERM_BOLD)>>> $(1)$(TERM_RESET)"
+TERM_BOLD := $(shell tput smso 2>/dev/null)
+TERM_RESET := ${shell tput rmso 2>/dev/null}
+
+SDK_VERSION := "$(shell date +%g.%V.%u)"
+RELEASE_VERSION := "$(shell date +%g.%V.%u_%H_%M_%S)"
+
+# Macro of Generating Buildsystem
+# $(1): Target
+define GENERATE_BUILDSYSTEM
+$($(1)_BUILD_DIR): board
+	@ mkdir -p $($(1)_BUILD_DIR)
+	@ if [ ! -f $($(1)_BUILD_DIR)/build.ninja ]; then \
+		cmake -G Ninja -DBOARD=$(BOARD) -DCMAKE_TOOLCHAIN_FILE=$(build_DIR)/cmake/toolchains/$(ARCH)-gcc.cmake -S $(product_DIR)/$(PRODUCT) -B $($(1)_BUILD_DIR); \
+	fi
+endef
+
+# Macro of Building CMake Targets
+# $(1): Target
+define GENERATE_CMAKE_TARGET
+.PHONY: $(1)
+$(1): toolchain $($(1)_BUILD_DIR)
+	@ $(call MESSAGE,"Building $(1)")
+	@ (if [ $(1) == kernel ]; then \
+		cmake --build $($(1)_BUILD_DIR); \
+	else \
+		if [ $(1) == bootloader ]; then \
+			if [ ! -d $(kernel_KEYPATH) ]; then \
+				mkdir -p $(kernel_KEYPATH); \
+			fi; \
+			if [ ! -f $(kernel_KEYPATH)/*private.pem -o ! -f $(kernel_KEYPATH)/*public.pem ]; then \
+				$(call MESSAGE,"Generating kernel key pair ..."); \
+				python3 $(SIGNTOOL) keygen -k $(kernel_KEYPATH) -t rsa-2048; \
+			fi; \
+			$(call MESSAGE,"Attach kernel public key"); \
+			python3 $(SIGNTOOL) getpub -k $(kernel_KEYPATH)/rsa2048-private.pem > $($(1)_DIR)/bl2/ext/mcuboot/rsa_pub_key.h; \
+			if [ ! -d $($(1)_KEYPATH) ]; then \
+				$(call MESSAGE,"Generating $(1) key pair ..."); \
+				mkdir -p $($(1)_KEYPATH); \
+			fi; \
+			if [ ! -f $($(1)_KEYPATH)/*private.pem -o ! -f $($(1)_KEYPATH)/*public.pem ]; then \
+				python3 $(SIGNTOOL) keygen -k $($(1)_KEYPATH) -t rsa-3072; \
+			fi; \
+		fi; \
+		cmake $($(1)_DIR)/ -G"Unix Makefiles" -DBOARD=$(BOARD) -DPRODUCT=$(PRODUCT) -DCOMPILER=$(ARCH)-gcc; \
+		cmake --build ./ -- install; \
+	fi \
+	)
+endef
+
+# Macro of Building Targets
+# $(1): Target
+define GENERATE_MAKE_TARGET
+.PHONY: $(1)
+$(1): toolchain
+	@ $(call MESSAGE,"Building $(1)")
+	@ (cd $($(1)_DIR) && $(MAKE))
+endef
+
+# Macro of Menuconfig Targets
+# $(1): Target
+# $(2): Target suffix
+define GENERATE_MENUCONFIG_TARGET
+.PHONY: $(if $(2),$(1)-$(2),$(1))
+$(if $(2),$(1)-$(2),$(1)): $($(1)_BUILD_DIR)
+	@ cmake --build $($(1)_BUILD_DIR) --target $(2)
+endef
+
+# Macro of Building Dist Targets
+# $(1): Target
+# $(2): Target suffix
+define GENERATE_DIST_TARGET
+.PHONY: $(if $(2),$(1)-$(2),$(1))
+$(if $(2),$(1)-$(2),$(1)): $(1) $(DIST_DIR)
+	@ if [ -f $($(1)_BIN) ]; then install -p $($(1)_BIN) $($(1)_$(2)_BIN); fi
+endef
+
+# Macro of Cleaning Targets
+# $(1): Target
+# $(2): Target suffix
+define GENERATE_CLEAN_TARGET
+.PHONY: $(if $(2),$(1)-$(2),$(1))
+$(if $(2),$(1)-$(2),$(1)):
+	@ $(call MESSAGE,"Cleaning $(1)")
+	@ if [ -d $($(1)_BUILD_DIR) ]; then cmake --build $($(1)_BUILD_DIR) --target $(2); fi
+endef
+
+# Macro of Signing Image
+# $(1): target binary
+# $(2): header length
+define SIGN_IMAGE
+	if [ $(1) == bootloader ]; then \
+		python3 $(SIGNTOOL) sign_bl2 -P $($(1)_KEYPATH) -H $(2) $($(1)_BIN) $($(1)_dist_BIN); \
+	else \
+		python3 $(SIGNTOOL) sign -k $($(1)_KEYPATH)/rsa2048-private.pem -H $(2) $($(1)_BIN) $($(1)_dist_BIN); \
+	fi
+endef
+
+################################################################
+# Targets
+################################################################
+BUILDSYSTEM_TARGETS	:= kernel
+CMAKE_TARGETS		:= kernel
+#MAKE_TARGETS		:= adnl
+MENUCONFIG_TARGETS	:= kernel
+INSTALL_TARGETS		:= $(CMAKE_TARGETS)
+ALL_TARGETS		:= $(CMAKE_TARGETS) $(MAKE_TARGETS)
+DIST_TARGETS		:= $(addsuffix -dist,$(INSTALL_TARGETS))
+CLEAN_TARGETS		:= $(addsuffix -clean,$(ALL_TARGETS))
+
+.PHONY: dist
+dist: all $(DIST_TARGETS)
+	mkimage -A arm64 -O u-boot -T standalone -C none -a 0x1000 -e0x1000 -n rtos -d $(kernel_dist_BIN) $(DIST_DIR)/rtos-uImage
+#	$(call SIGN_IMAGE,bootloader,512)
+#	$(call SIGN_IMAGE,kernel,1024)
+
+$(DIST_DIR):
+	@ install -d $(DIST_DIR)
+
+.PHONY: all
+all: $(ALL_TARGETS)
+
+.PHONY: clean
+clean: $(CLEAN_TARGETS)
+
+.PHONY: distclean
+distclean:
+	@ if [ -d $(BUILD_DIR) ]; then rm -rf $(BUILD_DIR); fi
+
+.PHONY: board
+board:
+ifndef BOARD
+	$(error BOARD is not set, Please execute source scripts/choose.sh)
+endif
+	@ echo "Board: $(BOARD)"
+ifndef PRODUCT
+	$(error PRODUCT is not set, Please execute source scripts/choose.sh)
+endif
+	@ echo "PRODUCT: $(PRODUCT)"
+
+.PHONY: docs
+docs:
+	@ cmake $($(1)_DIR)
+	@ cmake --build ./
+
+################################################################
+# Respective Targets
+################################################################
+# Buildsystem Targets
+$(foreach target,$(BUILDSYSTEM_TARGETS),$(eval $(call GENERATE_BUILDSYSTEM,$(target))))
+
+# CMake Build Targets
+$(foreach target,$(CMAKE_TARGETS),$(eval $(call GENERATE_CMAKE_TARGET,$(target))))
+
+# Build Targets
+$(foreach target,$(MAKE_TARGETS),$(eval $(call GENERATE_MAKE_TARGET,$(target))))
+
+# Menuconfig Targets
+$(foreach target,$(MENUCONFIG_TARGETS),$(eval $(call GENERATE_MENUCONFIG_TARGET,$(target),menuconfig)))
+
+# Dist Targets
+$(foreach target,$(ALL_TARGETS) fw,$(eval $(call GENERATE_DIST_TARGET,$(target),dist)))
+
+# Clean Targets
+$(foreach target,$(ALL_TARGETS),$(eval $(call GENERATE_CLEAN_TARGET,$(target),clean)))
+
+.PHONY: toolchain
+toolchain:
+ifndef COMPILER
+	$(error COMPILER is not set, Please execute source scripts/choose.sh)
+endif
+	@ if [ ! -d $($@_DIR) ]; then \
+		$(call MESSAGE,"Preparing $@"); \
+		mkdir -p $($@_DIR); \
+		tar -xf $(CROSSTOOL) -C $($@_DIR) --strip-components=1; \
+		touch $($@_DIR); \
+	fi
+	@ if ( find $(CROSSTOOL) -newer $($@_DIR) | grep -q $(CROSSTOOL) ); then \
+		$(call MESSAGE,"Updating $@"); \
+		rm -rf $($@_DIR)/*; \
+		tar -xf $(CROSSTOOL) -C $($@_DIR) --strip-components=1; \
+		touch $($@_DIR); \
+        fi
+
+.PHONY: flash
+flash:
+	@ if [ -d $(DIST_DIR) ]; then \
+		(cd $(DIST_DIR) && \
+		./update_fw.sh;) \
+	fi
+
+.PHONY: release
+release:
+	@ (cd .. && \
+	tar --exclude-vcs --exclude=cscope.* --exclude=.repo --exclude=output --exclude=cmake-Linux-x86_64 --exclude=gcc-arm-none-eabi \
+	-cJf unisoc_mcu_sdk_$(RELEASE_VERSION).tar.xz $(notdir $(PRJDIR)); \
+	rm -f $(product_DIR)/$(PRODUCT)/include/version.h; \
+	mv unisoc_mcu_sdk_$(RELEASE_VERSION).tar.xz $(PRJDIR))