—> 从/src/project/echocloud_demo/gcc 输入make编译, 解析当前文件夹下的Makefile文件:
#
# Rules for building application
#
# ----------------------------------------------------------------------------
# project local config ---> 1. 包含配置文件localconfig.mk 后面分析
# ----------------------------------------------------------------------------
include localconfig.mk
# ----------------------------------------------------------------------------
# common rules ---> 定义全局变量 ROOT_PATH 为 ../../..
# ----------------------------------------------------------------------------
ROOT_PATH := ../../..
# ----------------------------------------------------------------------------
# ---> 2. 包含配置文件gcc.mk 后面分析
# ----------------------------------------------------------------------------
include $(ROOT_PATH)/gcc.mk
# ----------------------------------------------------------------------------
# project and objects ---> 定义全局变量 PROJECT
# ----------------------------------------------------------------------------
PROJECT := echocloud_demo
# ----------------------------------------------------------------------------
# ---> 给全局变量 INCLUDE_PATHS 追加值,包含路径:
# ../../../project/echocloud_demo
# ../../../project/common/framework/sys_ctrl
# ----------------------------------------------------------------------------
INCLUDE_PATHS += -I$(ROOT_PATH)/project/$(PROJECT)
INCLUDE_PATHS += -I$(ROOT_PATH)/project/common/framework/sys_ctrl/
# ----------------------------------------------------------------------------
# ---> 定义全局变量 DIRS_IGNORE 其值为:
# ../gcc%
# ../image%
# ../../../project/common/board/%
# ----------------------------------------------------------------------------
DIRS_IGNORE := ../gcc% ../image% $(ROOT_PATH)/project/common/board/%
# ----------------------------------------------------------------------------
# 定义全局变量 DIRS_ALL := $(shell find .. $(ROOT_PATH)/project/common -type d)
# 即递归包含(如果该文件夹下包含子文件夹,也包含在内):
# | 父目录 | 下所有文件夹
# | ../../../project/common | 下所有文件夹
# 先炒个手撕包菜*^_^*, 完了再分析。。。。。。
# ----------------------------------------------------------------------------
DIRS_ALL := $(shell find .. $(ROOT_PATH)/project/common -type d)
# ----------------------------------------------------------------------------
# ---> 定义全局变量 DIRS 为:
# 从 DIRS_ALL 中过滤掉 DIRS_IGNORE 之后余下的文件夹
# ../../../project/common/board/__PRJ_CONFIG_BOARD 文件夹
# ----------------------------------------------------------------------------
DIRS := $(filter-out $(DIRS_IGNORE),$(DIRS_ALL))
DIRS += $(ROOT_PATH)/project/common/board/$(__PRJ_CONFIG_BOARD)
# ----------------------------------------------------------------------------
# ---> 定义全局变量 SRCS 为:DIRS 中后缀为 *.c/*.s *.S的文件,此处只用去掉后缀的部分
# ----------------------------------------------------------------------------
SRCS := $(basename $(foreach dir,$(DIRS),$(wildcard $(dir)/*.[csS])))
# ----------------------------------------------------------------------------
# ---> 定义全局变量 OBJS 为: SRCS所代表的所有文件分别加入.o后缀
# ----------------------------------------------------------------------------
OBJS := $(addsuffix .o,$(SRCS))
# ----------------------------------------------------------------------------
# ---> extra libs:指定需要用到的静态链接库
# ----------------------------------------------------------------------------
PRJ_EXTRA_LIBS := -lechocloud
# ----------------------------------------------------------------------------
# override project variables
# ----------------------------------------------------------------------------
# linker script path/file 自定义链接脚本、路径
# - relative to "./"
# - define your own "LINKER_SCRIPT_PATH" and/or "LINKER_SCRIPT" to override
# the default one
#LINKER_SCRIPT_PATH := .
#LINKER_SCRIPT := ./xr871_appos_xip.ld
# image config path/file 自定义镜像文件路径
# - relative to "../image/xxxxx/", eg. "../image/xr871/"
# - define your own "IMAGE_CFG_PATH" and/or "IMAGE_CFG" to override the
# default one
# ----------------------------------------------------------------------------
# ---> 3. 如果镜像需要压缩, 指定 IMAGE_CFG_PATH 为当前路径,IMAGE_CFG 为 ./image_xip.cfg (后面分析)
# ----------------------------------------------------------------------------
ifeq ($(__PRJ_CONFIG_IMG_COMPRESS), y)
IMAGE_CFG_PATH := .
IMAGE_CFG := ./image_xip.cfg
endif
# image name, default to xr_system 镜像文件名称
# IMAGE_NAME :=
# project make rules 包含make规则,PRJ_MAKE_RULES 指定
include $(PRJ_MAKE_RULES)
# ---> 工程本地配置文件,覆盖掉公共的配置文件;
# project local config options, override the common config options
#
# ----------------------------------------------------------------------------
# board definition ---> 指定单板类型
# ----------------------------------------------------------------------------
__PRJ_CONFIG_BOARD := xr871_evb_audio
# ----------------------------------------------------------------------------
# override global config options ---> 覆盖全局配置操作
# export: 将特定变量导出到 sub-make
# ----------------------------------------------------------------------------
# set y to enable bootloader and disable some features, for bootloader only
# export __CONFIG_BOOTLOADER := y
# set n to disable dual core features, for bootloader only
# export __CONFIG_ARCH_DUAL_CORE := n
# ----------------------------------------------------------------------------
# override project common config options
# ----------------------------------------------------------------------------
# support both sta and ap, default to n
# __PRJ_CONFIG_WLAN_STA_AP := y
# ---> 定义全局变量 __PRJ_CONFIG_XPLAYER
# support xplayer, default to n
__PRJ_CONFIG_XPLAYER := y
# ---> 定义全局变量 __PRJ_CONFIG_XIP
# enable XIP, default to n
__PRJ_CONFIG_XIP := y
# ---> 链接函数级别的text/rodata/data段到.xip 段中
# set y to link function level's text/rodata/data to ".xip" section
ifeq ($(__PRJ_CONFIG_XIP), y)
export __CONFIG_XIP_SECTION_FUNC_LEVEL := y
endif
# enable OTA, default to n
# __PRJ_CONFIG_OTA := y
# enable image compress
# __PRJ_CONFIG_IMG_COMPRESS := y
#
# Common rules for GCC Makefile ---> gcc Makefile 通用规则
#
# ----------------------------------------------------------------------------
# cross compiler ---> 交叉编译器
# ----------------------------------------------------------------------------
#CC_DIR := ~/tools/gcc-arm-none-eabi-4_9-2015q2/bin
# 定义全局变量 ---> 交叉编译器路径
CC_DIR := /opt/gcc-arm-none-eabi-4_9-2015q3/bin
# 定义全局变量 ---> 交叉编译器命令
CC_PREFIX := $(CC_DIR)/arm-none-eabi-
AS := $(CC_PREFIX)as
CC := $(CC_PREFIX)gcc
CPP := $(CC_PREFIX)g++
LD := $(CC_PREFIX)ld
AR := $(CC_PREFIX)ar
OBJCOPY := $(CC_PREFIX)objcopy
OBJDUMP := $(CC_PREFIX)objdump
SIZE := $(CC_PREFIX)size
STRIP := $(CC_PREFIX)strip
# ----------------------------------------------------------------------------
# tools ---> | -u copy only when the SOURCE file is newer than the
# destination file or when the destination file is missing |
# ----------------------------------------------------------------------------
CP := cp -u
# ---> 根据宿主平台,定义 makeimage 命令
# $(MKIMAGE) is a tool for creating image
ifeq ($(shell uname -o), Cygwin)
MKIMAGE := mkimage.exe
else
MKIMAGE := mkimage
endif
# ----------------------------------------------------------------------------
# global configuration ---> 2.1 全局配置文件 ../../../config.mk
# ----------------------------------------------------------------------------
include $(ROOT_PATH)/config.mk
# ----------------------------------------------------------------------------
# options 全局变量
# ----------------------------------------------------------------------------
QUIET ?= n
OPTIMIZE := y
MDK_DBG_EN := y
HARDFP := n
# building display ---> 静默编译
ifeq ($(QUIET), y)
Q := @
S := -s
endif
# ---> 优化标志 -Os -DNDEBUG
# Level 2.5,-Os 相当于-O2.5
# 专门优化目标文件大小,执行所有的不增加目标文件大小的-O2优化选项.并且执行专门减小目标文件大小的优化选项
ifeq ($(OPTIMIZE), y)
OPTIMIZE_FLAG := -Os -DNDEBUG
else
OPTIMIZE_FLAG := -O0 -DDEBUG
endif
# ---> 调试选项,-gdwarf-2: 产生DWARF version2 的格式的调试信息,常用于IRIXX6上的DBX调试器.GCC会使用DWARF version3的一些特性
ifeq ($(MDK_DBG_EN), y)
DBG_FLAG := -gdwarf-2
else
DBG_FLAG := -g
endif
# ---> FPU,这里是softfp
ifeq ($(HARDFP), y)
FLOAT_ABI := hard
else
FLOAT_ABI := softfp
endif
# ----------------------------------------------------------------------------
# flags for compiler and linker ---> 编译连接标志;
# ----------------------------------------------------------------------------
# CPU/FPU options ---> ok 此处为 m4
ifeq ($(__CONFIG_CPU_CM4F), y)
CPU := -mcpu=cortex-m4 -mthumb -mfpu=fpv4-sp-d16 -mfloat-abi=$(FLOAT_ABI)
else
CPU := -mcpu=cortex-m3 -mthumb
endif
# ---> 编译标志
CC_FLAGS = $(CPU) -c $(DBG_FLAG) -fno-common -fmessage-length=0 \
-fno-exceptions -ffunction-sections -fdata-sections -fomit-frame-pointer \
-Wall -Werror -Wpointer-arith -Wno-error=unused-function \
-MMD -MP $(OPTIMIZE_FLAG)
# ---> 链接标志, 其中 -Wl,-Map=$(basename $@).map ---> 指定生成的map文件名称:echocloud_demo.map
LD_FLAGS = $(CPU) -Wl,--gc-sections --specs=nano.specs \
-Wl,-Map=$(basename $@).map,--cref
# config symbols --> 在2.1全局配置文件 ../../../config.mk中定义
CC_SYMBOLS = $(CONFIG_SYMBOLS)
AS_SYMBOLS = $(CONFIG_SYMBOLS)
# 串口重定向以及打印浮点型数字
ifeq ($(__CONFIG_LIBC_PRINTF_FLOAT), y)
LD_FLAGS += -u _printf_float
endif
ifeq ($(__CONFIG_LIBC_SCANF_FLOAT), y)
LD_FLAGS += -u _scanf_float
endif
# ---> 使用ld的wrap选项替换已有库函数,链接时library interpositioning库内插技术
LD_FLAGS += -Wl,--wrap,main
LD_FLAGS += -Wl,--wrap,malloc
LD_FLAGS += -Wl,--wrap,realloc
LD_FLAGS += -Wl,--wrap,free
LD_FLAGS += -Wl,--wrap,_malloc_r
LD_FLAGS += -Wl,--wrap,_realloc_r
LD_FLAGS += -Wl,--wrap,_free_r
# ---> 如果启动了malloc trace
ifeq ($(__CONFIG_MALLOC_TRACE), y)
LD_FLAGS += -Wl,--wrap,calloc
LD_FLAGS += -Wl,--wrap,strdup
endif
# standard libraries ---> 系统标准库
LD_SYS_LIBS := -lstdc++ -lsupc++ -lm -lc -lgcc -lnosys
# include path ---> 头文件包含路径 INCLUDE_PATHS 全局变量
INCLUDE_ROOT_PATH := $(ROOT_PATH)/include
INCLUDE_PATHS = -I$(INCLUDE_ROOT_PATH) \
-I$(INCLUDE_ROOT_PATH)/libc \
-I$(INCLUDE_ROOT_PATH)/driver/cmsis
ifeq ($(__CONFIG_OS_FREERTOS), y)
INCLUDE_PATHS += -I$(INCLUDE_ROOT_PATH)/kernel/FreeRTOS
ifeq ($(__CONFIG_CPU_CM4F), y)
INCLUDE_PATHS += -I$(INCLUDE_ROOT_PATH)/kernel/FreeRTOS/portable/GCC/ARM_CM4F
else
INCLUDE_PATHS += -I$(INCLUDE_ROOT_PATH)/kernel/FreeRTOS/portable/GCC/ARM_CM3
endif
endif
# ---> lwip-1.4.1 网络协议库版本
ifeq ($(__CONFIG_LWIP_V1), y)
LWIP_DIR := lwip-1.4.1
else
LWIP_DIR := lwip-2.0.3
endif
INCLUDE_PATHS += -I$(INCLUDE_ROOT_PATH)/net/$(LWIP_DIR)
ifeq ($(__CONFIG_LWIP_V1), y)
INCLUDE_PATHS += -I$(INCLUDE_ROOT_PATH)/net/$(LWIP_DIR)/ipv4
endif
# ----------------------------------------------------------------------------
# common makefile for library and project ---> 库和工程的通用配置文件
# 2.2 ---> 分析 ../../../src/lib.mk
# 2.3 ---> 分析 ../../../project/project.mk
# ----------------------------------------------------------------------------
LIB_MAKE_RULES := $(ROOT_PATH)/src/lib.mk
PRJ_MAKE_RULES := $(ROOT_PATH)/project/project.mk
# ----------------------------------------------------------------------------
# common rules of compiling objects 编译目标文件的通用规则
# $(Q):静默编译,此处不使能
# $(CC): arm-none-eabi-gcc
# $(CPU): -mcpu=cortex-m4 -mthumb -mfpu=fpv4-sp-d16 -mfloat-abi=softfp
# -x assembler-with-cpp,明确指定后面的输入语言文件为:已经预处理的汇编文件???
# 例如:gcc –c hello.s –o hello.o,得到一个.o为后缀的目标文件
# 即:此处为将全部的.asm/.s/.S/.c/.cpp 文件编译得到对应的.o目标文件
# ----------------------------------------------------------------------------
%.o: %.asm
$(Q)$(CC) $(CPU) $(AS_SYMBOLS) -c -x assembler-with-cpp -o $@ $<
%.o: %.s
$(Q)$(CC) $(CPU) $(AS_SYMBOLS) -c -x assembler-with-cpp -o $@ $<
%.o: %.S
$(Q)$(CC) $(CPU) $(AS_SYMBOLS) -c -x assembler-with-cpp -o $@ $<
# 此处用 INCLUDE_PATHS 即 -I 指定头文件路径
%.o: %.c
$(Q)$(CC) $(CC_FLAGS) $(CC_SYMBOLS) -std=gnu99 $(INCLUDE_PATHS) -o $@ $<
# -fno-rtti 禁止运行时类型识别
%.o: %.cpp
$(Q)$(CPP) $(CC_FLAGS) $(CC_SYMBOLS) -std=gnu++98 -fno-rtti $(INCLUDE_PATHS) -o $@ $<
#
# global config options
#
# ----------------------------------------------------------------------------
# config options 配置
# ----------------------------------------------------------------------------
# chip and cpu 芯片及cpu内核
__CONFIG_CHIP_XR871 ?= y
__CONFIG_CPU_CM4F ?= y
# arch and core 架构及其核数
__CONFIG_ARCH_DUAL_CORE ?= y
__CONFIG_ARCH_APP_CORE ?= y
__CONFIG_ARCH_NET_CORE ?= n
# redefine int32_t to signed int, but not signed long
__CONFIG_LIBC_REDEFINE_GCC_INT32_TYPE ?= y
# support printf float variables ---> 使能串口重定向以及打印浮点型数字
__CONFIG_LIBC_PRINTF_FLOAT ?= y
# support scanf float variables
__CONFIG_LIBC_SCANF_FLOAT ?= y
# heap managed by stdlib ---> 堆管理使用标准库的malloc
__CONFIG_MALLOC_USE_STDLIB ?= y
# trace heap memory usage and error when using malloc, free, etc.
# ---> 禁止跟踪堆内存的使用和错误
__CONFIG_MALLOC_TRACE ?= n
# os ---> 指定使用的操作系统FREERTOS
__CONFIG_OS_FREERTOS ?= y
# lwIP ---> 指定使用的网络协议栈lwIP 1.4.1
# - y: lwIP 1.4.1, support IPv4 stack only
# - n: lwIP 2.x.x, support dual IPv4/IPv6 stack
__CONFIG_LWIP_V1 ?= y
# mbuf implementation mode ---> mbuf的实现方式0
# - mode 0: continuous memory allocated from net core
# - mode 1: continuous memory (lwip pbuf) allocated from app core
__CONFIG_MBUF_IMPL_MODE ?= 0
# link function level's text/rodata/data to ".xip" section
# ---> 禁止链接函数级别的text/rodata/data段到.xip 段中
__CONFIG_XIP_SECTION_FUNC_LEVEL ?= n
# bin compression ---> 禁止二进制文件压缩
__CONFIG_BIN_COMPRESS ?= n
# enable/disable bootloader, y to enable bootloader and disable some features
# ---> 禁止bootloader
__CONFIG_BOOTLOADER ?= n
# ----------------------------------------------------------------------------
# config symbols ---> 定义宏配置 CONFIG_SYMBOLS 全局变量
# ----------------------------------------------------------------------------
CONFIG_SYMBOLS =
# ---> ok
ifeq ($(__CONFIG_CHIP_XR871), y)
CONFIG_SYMBOLS += -D__CONFIG_CHIP_XR871
endif
# ---> ok
ifeq ($(__CONFIG_CPU_CM4F), y)
CONFIG_SYMBOLS += -D__CONFIG_CPU_CM4F
endif
# ---> ok
ifeq ($(__CONFIG_ARCH_DUAL_CORE), y)
CONFIG_SYMBOLS += -D__CONFIG_ARCH_DUAL_CORE
endif
# ---> ok
ifeq ($(__CONFIG_ARCH_APP_CORE), y)
CONFIG_SYMBOLS += -D__CONFIG_ARCH_APP_CORE
endif
# ---> n
ifeq ($(__CONFIG_ARCH_NET_CORE), y)
CONFIG_SYMBOLS += -D__CONFIG_ARCH_NET_CORE
endif
# ---> ok
ifeq ($(__CONFIG_LIBC_REDEFINE_GCC_INT32_TYPE), y)
CONFIG_SYMBOLS += -D__CONFIG_LIBC_REDEFINE_GCC_INT32_TYPE
endif
# ---> ok
ifeq ($(__CONFIG_MALLOC_USE_STDLIB), y)
CONFIG_SYMBOLS += -D__CONFIG_MALLOC_USE_STDLIB
endif
# ---> n
ifeq ($(__CONFIG_MALLOC_TRACE), y)
CONFIG_SYMBOLS += -D__CONFIG_MALLOC_TRACE
endif
# ---> ok
ifeq ($(__CONFIG_OS_FREERTOS), y)
CONFIG_SYMBOLS += -D__CONFIG_OS_FREERTOS
endif
# ---> ok
ifeq ($(__CONFIG_LWIP_V1), y)
CONFIG_SYMBOLS += -D__CONFIG_LWIP_V1
endif
# ---> 0
CONFIG_SYMBOLS += -D__CONFIG_MBUF_IMPL_MODE=$(__CONFIG_MBUF_IMPL_MODE)
# ---> n
ifeq ($(__CONFIG_XIP_SECTION_FUNC_LEVEL), y)
CONFIG_SYMBOLS += -D__CONFIG_XIP_SECTION_FUNC_LEVEL
endif
# ---> n
ifeq ($(__CONFIG_BIN_COMPRESS), y)
CONFIG_SYMBOLS += -D__CONFIG_BIN_COMPRESS
endif
# ---> n
ifeq ($(__CONFIG_BOOTLOADER), y)
CONFIG_SYMBOLS += -D__CONFIG_BOOTLOADER
endif
# ----------------------------------------------------------------------------
# config chip name ---> 芯片名称 全局变量 CONFIG_CHIP_NAME
# ----------------------------------------------------------------------------
ifeq ($(__CONFIG_CHIP_XR871), y)
CONFIG_CHIP_NAME = xr871
else
error "CONFIG_CHIP_NAME" is not defined!
endif
#
# Rules for building library ---> 库构件规则
#
# ----------------------------------------------------------------------------
# common targets and building rules
# ----------------------------------------------------------------------------
# ---> 安装路径: INSTALL_PATH
INSTALL_PATH := $(ROOT_PATH)/lib
.PHONY: all install size clean install_clean
all: $(LIBS)
# ---> 将.o目标文件 归档打包为库文件
$(LIBS): $(OBJS)
$(Q)$(AR) -crs $@ $^
# ---> 安装到指定目录下:
# cp -t, --target-directory=DIRECTORY copy all SOURCE arguments into DIRECTORY
install: $(LIBS)
$(Q)$(CP) -t $(INSTALL_PATH) $^
# ---> arm-none-eabi-size
# The GNU size utility lists the section sizes—and the total size—for each of
# the object or archive files objfile in its argument list. By default,
# one line of output is generated for each object file or each module in an archive.
# -t Show totals of all objects listed (Berkeley format listing mode only).
size:
$(Q)$(SIZE) -t $(LIBS)
clean:
$(Q)-rm -f $(LIBS) $(OBJS) $(DEPS)
install_clean:
$(Q)-rm -f $(INSTALL_PATH)/$(LIBS)
# ----------------------------------------------------------------------------
# dependent rules 依赖文件 把$(OBJS)中的变量符合后缀是.o的全部替换成.d
# linux shell规则:
# - 表示:使任何命令行的任何非零退出状态都被忽略,就是,忽略当前此行命令执行时候所遇到的错误
# @ 表示在make执行时候,输出的信息中,不要显示此行命令,静默编译;
# ----------------------------------------------------------------------------
DEPS = $(OBJS:.o=.d)
-include $(DEPS)
#
# Rules for building project ---> 构件工程规则
#
# ----------------------------------------------------------------------------
# project common config ---> 2.3.1 工程通用配置文件 后面分析
# ----------------------------------------------------------------------------
include $(ROOT_PATH)/project/prjconfig.mk
# ----------------------------------------------------------------------------
# library ---> 指定链接库的路径
# ----------------------------------------------------------------------------
LIBRARY_PATHS := -L$(ROOT_PATH)/lib
# There are strong and weak symbols in "lchip", it may link to the weak symbol
# as they are static libraries, so use --whole-archive to solve this problem.
# ---> --whole-archive:For each archive mentioned on the command line after the --whole-archive
# option, include every object file in the archive in the link, rather than
# searching the archive for the required object files.
# 在代码中定义的符号(如函数名)还未使用到之前,链接器并不会把它加入到连接表中,使用--whole-archive 强制读取
# 此处为将chip库中的所有符号都加载到连接表中;
LIBRARIES := -Wl,--whole-archive -lchip -Wl,--no-whole-archive -lota -limage
# add extra libs from specific project
# ---> 顶层/src/project/echocloud_demo/gcc/Makefile:
# PRJ_EXTRA_LIBS := -lechocloud
LIBRARIES += $(PRJ_EXTRA_LIBS)
ifneq ($(__CONFIG_BOOTLOADER), y)
# audio player libs
# ---> ok
ifeq ($(__PRJ_CONFIG_XPLAYER), y)
LIBRARIES += \
-lcedarx \
-lmp3 \
-lamr \
-lamren \
-laac \
-lcedarx
endif
# network libs
# ---> ok
LIBRARIES += -lmqtt \
-lnopoll \
-llibwebsockets \
-lhttpd \
-lhttpcli \
-lmbedtls \
-lsntp \
-lping \
-ludhcpd \
-lxrsys \
-lwlan \
-lsmartlink \
-lairkiss_aes \
-lsc_assistant \
-llwip \
-lxrsys
# ---> ok
LIBRARIES += -lcjson -lfs -lconsole -lcomponent -lefpg -lpm -laudmgr -lpcm \
-luncompress -ladt -lutil
endif # __CONFIG_BOOTLOADER
# ---> ok os
LIBRARIES += -los
# ---> ok freertos
ifeq ($(__CONFIG_OS_FREERTOS), y)
LIBRARIES += -lfreertos
endif
# ---> LD_SYS_LIBS 在2. ../../../gcc.mk 中
LIBRARIES += $(LD_SYS_LIBS) -lxrc
# ----------------------------------------------------------------------------
# extra include path
# ----------------------------------------------------------------------------、
# ---> ok
ifeq ($(__PRJ_CONFIG_XPLAYER), y)
CEDARX_INC_DIRS := $(shell find $(ROOT_PATH)/include/cedarx -type d)
INCLUDE_PATHS += $(foreach dir, $(CEDARX_INC_DIRS), -I$(dir))
endif
INCLUDE_PATHS += -I$(ROOT_PATH)/project
# ---> 单板 __PRJ_CONFIG_BOARD := xr871_evb_audio
ifneq ($(__PRJ_CONFIG_BOARD),)
INCLUDE_PATHS += -I$(ROOT_PATH)/project/common/board/$(__PRJ_CONFIG_BOARD)
else
$(error board is not defined!)
endif
# ----------------------------------------------------------------------------
# include config header for all project
# ----------------------------------------------------------------------------
CC_FLAGS += -include common/prj_conf_opt.h
# ----------------------------------------------------------------------------
# common suffix
# ----------------------------------------------------------------------------
# ---> n
ifeq ($(__PRJ_CONFIG_WLAN_STA_AP), y)
SUFFIX_WLAN := _sta_ap
endif
# ---> ok
ifeq ($(__PRJ_CONFIG_XIP), y)
SUFFIX_XIP := _xip
endif
# ---> n
ifeq ($(__CONFIG_XIP_SECTION_FUNC_LEVEL), y)
LINKER_SCRIPT_SUFFIX := _max
endif
# ----------------------------------------------------------------------------
# linker script
# ----------------------------------------------------------------------------
# linker script, maybe override by the specific project ---> ?= 如果未赋值,则赋值
# := 是覆盖之前的值
LINKER_SCRIPT_PATH ?= $(ROOT_PATH)/project/linker_script/gcc/$(CONFIG_CHIP_NAME)
# ---> ./project/linker_script/gcc/xr871/appos_xip.ld
LINKER_SCRIPT ?= $(LINKER_SCRIPT_PATH)/appos$(SUFFIX_XIP)$(LINKER_SCRIPT_SUFFIX).ld
# ----------------------------------------------------------------------------
# image ---> xr871
# ----------------------------------------------------------------------------
# original path of bin files
BIN_PATH := $(ROOT_PATH)/bin/$(CONFIG_CHIP_NAME)
# output image path ---> xr871
IMAGE_PATH := ../image/$(CONFIG_CHIP_NAME)
# $(IMAGE_TOOL) is relative to $(IMAGE_PATH) ---> mkimage
IMAGE_TOOL := ../$(ROOT_PATH)/tools/$(MKIMAGE)
# image config file, maybe override by the specific project
# $(IMAGE_CFG_PATH) is relative to $(IMAGE_PATH)
IMAGE_CFG_PATH ?= ../$(ROOT_PATH)/project/image_cfg/$(CONFIG_CHIP_NAME)
# ./project/image_cfg/xr871/image_xip.cfg
IMAGE_CFG ?= $(IMAGE_CFG_PATH)/image$(SUFFIX_WLAN)$(SUFFIX_XIP).cfg
# image tool's options to enable/disable OTA
# ---> n
ifeq ($(__PRJ_CONFIG_OTA), y)
IMAGE_TOOL_OPT := -O
else
IMAGE_TOOL_OPT :=
endif
# image name, maybe override by the specific project ---> 镜像名称xr_system
IMAGE_NAME ?= xr_system
# ----------------------------------------------------------------------------
# common targets and building rules
# ----------------------------------------------------------------------------
CC_SYMBOLS += $(PRJ_CONFIG_SYMBOLS)
# ---> axf
ifeq ($(MDK_DBG_EN), y)
ELF_EXT = axf
else
ELF_EXT = elf
endif
# ---> echocloud_demo.axf
.PHONY: all $(PROJECT).$(ELF_EXT) objdump size clean lib lib_clean \
lib_install_clean install image image_clean build build_clean
# ---> echocloud_demo.bin
all: $(PROJECT).bin size
# ---> echocloud_demo.axf
$(PROJECT).$(ELF_EXT): $(OBJS)
$(Q)$(CC) $(LD_FLAGS) -T$(LINKER_SCRIPT) $(LIBRARY_PATHS) -o $@ $(OBJS) $(LIBRARIES)
%.bin: %.$(ELF_EXT)
# ---> ok
# -R .xip (--remove-section) 输出文件中不要.xip这个section,缩小了文件尺寸
# -j Copy only the indicated sections from the input file to the output file.
ifeq ($(__PRJ_CONFIG_XIP), y)
$(Q)$(OBJCOPY) -O binary -R .xip $< $@
$(Q)$(OBJCOPY) -O binary -j .xip $< $(basename $@)$(SUFFIX_XIP).bin
else
$(Q)$(OBJCOPY) -O binary $< $@
endif
# -S Display source code intermixed with disassembly, if possible
# -d disassemble Display the assembler mnemonics for the machine instructions from objfile
# -h Display summary information from the section headers of the object file
%.objdump: %.$(ELF_EXT)
$(Q)$(OBJDUMP) -Sdh $< > $@
objdump: $(PROJECT).objdump
size:
$(Q)$(SIZE) $(PROJECT).$(ELF_EXT)
clean:
$(Q)-rm -f $(PROJECT).* *.bin $(OBJS) $(DEPS)
# ---> 执行src目录下面的makefile文件:2.3.2
# MAKE_COMMAND := make
# MAKE = $(MAKE_COMMAND)
# 即$(MAKE) = make
# make -C: Change to DIRECTORY before doing anything
lib:
$(Q)$(MAKE) $(S) -C $(ROOT_PATH)/src install
lib_clean:
$(Q)$(MAKE) $(S) -C $(ROOT_PATH)/src clean
lib_install_clean:
$(Q)$(MAKE) $(S) -C $(ROOT_PATH)/src install_clean
# ---> n
ifeq ($(__CONFIG_BOOTLOADER), y)
install:
$(Q)$(CP) $(PROJECT).bin $(ROOT_PATH)/bin/$(CONFIG_CHIP_NAME)/boot.bin
build: lib all install
build_clean: clean lib_clean lib_install_clean
else # __CONFIG_BOOTLOADER
install:
# ---> 创建镜像目录
@mkdir -p $(IMAGE_PATH)
# ---> echocloud_demo.bin 拷贝重命名为 app.bin
$(Q)$(CP) $(PROJECT).bin $(IMAGE_PATH)/app.bin
# ---> n
ifeq ($(__PRJ_CONFIG_IMG_COMPRESS), y)
rm -f $(PROJECT).bin.xz
xz -k --check=crc32 --lzma2=preset=6e,dict=32KiB $(PROJECT).bin
$(Q)$(CP) $(PROJECT).bin.xz $(IMAGE_PATH)/app.bin.xz
rm -f $(PROJECT).bin.xz
endif
# ---> echocloud_demo_xip.bin 拷贝重命名为 app_xip.bin
ifeq ($(__PRJ_CONFIG_XIP), y)
$(Q)$(CP) $(PROJECT)$(SUFFIX_XIP).bin $(IMAGE_PATH)/app$(SUFFIX_XIP).bin
endif
# ---> image 依赖于install
# -t target directories
# ../../../bin/xrb71/*.bin
image: install
$(Q)$(CP) -t $(IMAGE_PATH) $(BIN_PATH)/*.bin
# ---> n
ifeq ($(__PRJ_CONFIG_IMG_COMPRESS), y)
rm -f $(BIN_PATH)/*.bin.xz
xz -k --check=crc32 --lzma2=preset=6e,dict=32KiB $(BIN_PATH)/net.bin
xz -k --check=crc32 --lzma2=preset=6e,dict=32KiB $(BIN_PATH)/net_ap.bin
$(Q)$(CP) -t $(IMAGE_PATH) $(BIN_PATH)/*.bin.xz
rm -f $(BIN_PATH)/*.bin.xz
endif
cd $(IMAGE_PATH) && \
chmod a+rw *.bin && \
# 通过mkimage 和 image配置文件 生成 xr_system.img
$(IMAGE_TOOL) $(IMAGE_TOOL_OPT) -c $(IMAGE_CFG) -o $(IMAGE_NAME).img
image_clean:
-rm -f $(IMAGE_PATH)/*.bin $(IMAGE_PATH)/*.xz $(IMAGE_PATH)/*.img
build: lib all image
build_clean: image_clean clean lib_clean lib_install_clean
endif # __CONFIG_BOOTLOADER
# ----------------------------------------------------------------------------
# dependent rules
# ----------------------------------------------------------------------------
DEPS = $(OBJS:.o=.d)
-include $(DEPS)
#
# project common config options
#
# ----------------------------------------------------------------------------
# config options
# ----------------------------------------------------------------------------
# support both sta and ap
__PRJ_CONFIG_WLAN_STA_AP ?= n
# support xplayer
__PRJ_CONFIG_XPLAYER ?= n
# enable XIP
__PRJ_CONFIG_XIP ?= n
# enable OTA
__PRJ_CONFIG_OTA ?= n
# enable ETF CLI
__PRJ_CONFIG_ETF_CLI ?= n
# enable image compress
__PRJ_CONFIG_IMG_COMPRESS ?= n
# ----------------------------------------------------------------------------
# config symbols ---> 由工程通用配置文件,转换为 PRJ_CONFIG_SYMBOLS 宏配置来干预工程编译
# ----------------------------------------------------------------------------
PRJ_CONFIG_SYMBOLS :=
ifeq ($(__PRJ_CONFIG_WLAN_STA_AP), y)
PRJ_CONFIG_SYMBOLS += -D__PRJ_CONFIG_WLAN_STA_AP
endif
ifeq ($(__PRJ_CONFIG_XPLAYER), y)
PRJ_CONFIG_SYMBOLS += -D__PRJ_CONFIG_XPLAYER
endif
ifeq ($(__PRJ_CONFIG_XIP), y)
PRJ_CONFIG_SYMBOLS += -D__PRJ_CONFIG_XIP
endif
ifeq ($(__PRJ_CONFIG_OTA), y)
PRJ_CONFIG_SYMBOLS += -D__PRJ_CONFIG_OTA
endif
ifeq ($(__PRJ_CONFIG_ETF_CLI), y)
PRJ_CONFIG_SYMBOLS += -D__PRJ_CONFIG_ETF_CLI
endif
ifeq ($(__PRJ_CONFIG_IMG_COMPRESS), y)
PRJ_CONFIG_SYMBOLS += -D__PRJ_CONFIG_IMG_COMPRESS
endif
#
# Rules for building sub-modules
#
# ----------------------------------------------------------------------------
# common rules
# ----------------------------------------------------------------------------
ROOT_PATH := ..
# ---> gcc Makefile 通用规则
include $(ROOT_PATH)/gcc.mk
# ----------------------------------------------------------------------------
# sub-modules
# ----------------------------------------------------------------------------
SUBDIRS := driver/chip libc ota image ------------- 子模块目录
ifeq ($(__CONFIG_OS_FREERTOS), y)
SUBDIRS += kernel/FreeRTOS kernel/os/FreeRTOS
endif
ifneq ($(__CONFIG_BOOTLOADER), y)
SUBDIRS += driver/component \ ------------- 子模块目录
pm \
console \
efpg \
fs/fatfs \
audio/pcm \
audio/manager \
sys \
net/wlan \
net/$(LWIP_DIR) \
net/ping \
net/HTTPClient \
net/mbedtls-2.2.0 \
net/nopoll \
net/libwebsockets/lib \
net/mqtt \
net/shttpd-1.42 \
net/sntp \
net/udhcp-0.9.8 \
net/cloud/aliyun \
smartlink \
cjson \
atcmd \
xz \
util \
echocloud --------------- 此处用的 demo 模块目录
endif
# ----------------------------------------------------------------------------
# building rules
# ----------------------------------------------------------------------------
.PHONY: all install clean install_clean $(SUBDIRS) _all _install _clean _install_clean
all:
$(Q)$(MAKE) _all TARGET=all
install:
$(Q)$(MAKE) _install TARGET=install
clean:
$(Q)$(MAKE) _clean TARGET=clean
install_clean:
$(Q)$(MAKE) _install TARGET=install_clean
# ---> 进入每个子模块目录执行Makefile,此处分析 echocloud 目录下的 Makefile 2.3.2.1 分析
$(SUBDIRS):
$(Q)$(MAKE) $(S) -C $@ $(TARGET)
_all: $(SUBDIRS)
_install: $(SUBDIRS)
_clean: $(SUBDIRS)
_install_clean: $(SUBDIRS)
#
# Rules for building library
#
# ----------------------------------------------------------------------------
# common rules
# ----------------------------------------------------------------------------
ROOT_PATH := ../..
include $(ROOT_PATH)/gcc.mk
# ----------------------------------------------------------------------------
# library and objects
# ----------------------------------------------------------------------------
LIBS := libechocloud.a
DIRS := .
SRCS := $(basename $(foreach dir,$(DIRS),$(wildcard $(dir)/*.[csS])))
OBJS := $(addsuffix .o,$(SRCS))
# library make rules
include $(LIB_MAKE_RULES)
{
"magic" :"AWIH",
"version" :"0.3",
"OTA" :{"addr": "1024K", "size": "32K"},
"count" :7,
"section" :[
{"id": "0xa5ff5a00", "bin" :"boot.bin", "cert": "null", "flash_offs": "0K", "sram_offs": "0x00067000", "ep": "0x00067101", "attr":"0x1"},
{"id": "0xa5fe5a01", "bin" :"app.bin", "cert": "null", "flash_offs": "32K", "sram_offs": "0x00010000", "ep": "0x00010101", "attr":"0x1"},
{"id": "0xa5fd5a02", "bin" :"app_xip.bin", "cert": "null", "flash_offs": "161K", "sram_offs": "0xffffffff", "ep": "0xffffffff", "attr":"0x2"},
{"id": "0xa5fc5a03", "bin" :"net.bin", "cert": "null", "flash_offs": "650K", "sram_offs": "0x60000000", "ep": "0xffffffff", "attr":"0x1"},
{"id": "0xa5fa5a05", "bin" :"wlan_bl.bin", "cert": "null", "flash_offs": "872K", "sram_offs": "0xffffffff", "ep": "0xffffffff", "attr":"0x1"},
{"id": "0xa5f95a06", "bin" :"wlan_fw.bin", "cert": "null", "flash_offs": "875K", "sram_offs": "0xffffffff", "ep": "0xffffffff", "attr":"0x1"},
{"id": "0xa5f85a07", "bin" :"wlan_sdd.bin", "cert": "null", "flash_offs": "1006K", "sram_offs": "0xffffffff", "ep": "0xffffffff", "attr":"0x1"}
]
}
➜ 在xr871sdk目录下运行$: tree -L 2
.
├── bin
│ └── xr871
├── config.mk ------------------- 全局配置文件 上面 2.1 分析
├── gcc.mk ------------------- gcc Makefile 通用规则 上面 2 分析
├── include ------------------- 头文件路径
│ ├── compiler.h
│ ├── driver
│ ├── echocloud
│ ├── fs
│ ├── kernel
│ ├── types.h
│ ├── version.h …
├── lib ------------------- 生成的静态库 install 目录
│ ├── libechocloud.a
│ ├── libfreertos.a
│ ├── libfs.a …
├── project ------------------- 工程路径
│ ├── bootloader
│ ├── common
│ ├── echocloud_demo ------------------- make 运行的示例工程
│ │ ├── command.c
│ │ ├── command.h …
│ │ ├── gcc ------------------- 此处执行 make 命令
│ │ │ ├── echocloud_demo.axf
│ │ │ ├── echocloud_demo.bin
│ │ │ ├── echocloud_demo.map
│ │ │ ├── echocloud_demo_xip.bin
│ │ │ ├── echocloud.map
│ │ │ ├── image_xip.cfg
│ │ │ ├── localconfig.mk ---------------- 上面的 1 分析
│ │ │ ├── Makefile ---------------- 根Makefile
│ │ │ └── xr871_appos_xip.ld ---------------- 自定义链接脚本(此工程中未使用)
│ │ ├── image ---------------- 生成的镜像文件路径
│ │ │ └── xr871
│ │ │ ├── app.bin
│ │ │ ├── app_xip.bin
│ │ │ ├── boot.bin
│ │ │ ├── net_ap.bin
│ │ │ ├── net.bin
│ │ │ ├── wlan_bl.bin
│ │ │ ├── wlan_fw.bin
│ │ │ ├── wlan_sdd.bin
│ │ │ └── xr_system.img
│ │ ├── main.c
│ │ ├── prj_config.h …
│ ├── image_cfg
│ ├── linker_script ------------------- linker_script/gcc/xr871/appos_xip.ld 默认链接脚本
│ ├── prjconfig.mk ------------------- 工程通用配置文件 2.3.1 中分析
│ ├── project.mk ------------------- 工程构建编译规则 2.3 中分析
├── README
├── src ------------------- 每个子模块目录下包含自己的 makefile 文件
│ ├── driver
│ ├── echocloud
│ │ ├── Makefile … 子模块echocloud目录下的 makefile 文件 2.3.2.1
│ ├── fs
│ ├── kernel
│ ├── lib.mk ------------------- 库构件规则 2.2 中分析
│ ├── Makefile ------------------- 负责各个子模块的编译规则 2.3.2 # Rules for building sub-modules
│ ├── net
└── tools
├── mkimage
├── mkimage.exe
├── phoenixMC
└── phoenixMC.exe
├── project ------------------- 工程路径
│ ├── echocloud_demo ------------------- make 运行的示例工程
│ │ ├── gcc ------------------- 此处执行 make 命令
│ │ │ ├── Makefile ---------------- 根Makefile
│ │ │ ├── localconfig.mk--------- 1. project local config
├── gcc.mk -------------------------- 2. gcc Makefile 通用规则
├── config.mk ----------------------- 2.1 全局配置文件
├── src
│ ├── lib.mk --------------------------2.2 库构件规则
├── project ------------------- 工程路径
│ ├── project.mk --------------------2.3 工程构建编译规则
│ ├── prjconfig.mk ------------------2.3.1 工程通用配置文件
├── src
│ ├── Makefile -----------------------2.3.2 负责各个子模块的编译规则
│ ├── echocloud
│ │ ├── Makefile --------------------2.3.2.1 子模块echocloud目录下的 makefile 文件