LV01-01-AliOSThings-09-源码与编译-05-AliosThings顶层Makefile

本文主要是源码与编译——AliosThings顶层Makefile的相关笔记,若笔记中有错误或者不合适的地方,欢迎批评指正😃。

点击查看使用工具及版本
Windows版本 windows11
Ubuntu版本 Ubuntu22.04的64位版本
VMware® Workstation 16 Pro 16.2.3 build-19376536
终端软件 MobaXterm(Professional Edition v23.0 Build 5042 (license))
点击查看本文参考资料
分类 网址 说明
官方网站 阿里云 阿里云官网主页
阿里生活物联平台 生活物联网平台(飞燕平台)主页
AliGenie 天猫精灵开放平台AliGenie主页
阿里物联网平台 阿里物联网平台主页
Bluetooth 技术网站 蓝牙协议规范什么的可以来这里找
Telink Telink | Chips for a Smarter IoT (telink-semi.com)
Telink中文官网
开发手册 AliOS Things开发指南 AliOS Things开发指南,这里是最新版本,可以直接从官网找到
AliOS Things开发指南 AliOS Things应用开发指南,这里应该是3.3版本的完整开发文档
AliOS Things开发指南(3.0) AliOS Things应用开发指南,这里应该是3.0版本的完整开发文档
生活物联网平台开发文档 生活物联网平台(飞燕平台)开发文档
《设备端开发指南》
Wi-Fi IoT品类定义与功能开发 天猫精灵IoT开放平台——Wi-Fi IoT品类定义与功能开发
硬件平台 mk3080 WiFi开发板 WiFi开发板使用指南-阿里云开发者社区
esp8266开发板 一个教程:ESP8266-NodeMCU开发板详解-太极创客 (taichi-maker.com)
TLSR8258 Datasheet Datasheet for Telink BLE + IEEE802.15.4 MultiStandard Wireless SoC TLSR8258
参考资料 AliOS Things 3.0 应用开发指南 这个只是一篇参考文章,里面是一些环境搭建相关的,可以参考
IP知识百科 - 华为 (huawei.com) IP的一些相关知识点
点击查看相关文件下载
分类 网址 说明
蓝牙规范相关文档 Core Specification 5.2 核心规格 5.2,该规范定义了创建可互操作的Bluetooth 设备所需的技术。
《Core_v5.2.pdf》
Mesh Model(v1.1) 本Bluetooth 规范定义了模型(以及它们所需的状态和消息),这些模型用于在mesh 网络中的节点上执行基本功能,超出了Bluetooth Mesh 配置文件 规范中定义的基础模型。
本规范包括定义跨设备类型标准功能的通用模型,以及支持关键mesh 场景的模型,如照明控制、传感器、时间和场景。
《MshMDL_v1.1.pdf》
Mesh Profile(v1.0.1) 该Bluetooth 规范定义了基本要求,以实现可互操作的mesh 网络解决方案,用于Bluetooth 低能量无线技术。
《MshPRFv1.0.1.pdf》
Mesh Device Properties 本规范包含Bluetooth Mesh 配置文件 和Bluetooth Mesh 模型规范所要求的设备属性的定义。
但是跟之前的有些区别,我主要看的之前的版本:《MMeshDeviceProperties_v1.2.pdf》
GATT Specification Supplement GATT Specification Supplement | Bluetooth® Technology Website。
好像可以在线看:《GATT Specification Supplement》
Assigned Numbers GATT的一些类型定义可以在这里找。
AliOS Things alios-things/AliOS-Things Gitee上的AliOSThings SDK源码仓库
alibaba/AliOS-Things GitHub上的AliOSThings SDK源码仓库
天猫精灵蓝牙Mesh协议栈 alibaba-archive/genie-bt-mesh-stack GitHub上的天猫精灵蓝牙Mesh协议栈源码仓库。
之前是在alibaba/genie-bt-mesh-stack这个仓库。
写笔记的时候最新提交为faf523618a6a2560090fc423222b9db80984bb7a
蓝牙Mesh设备开发指南 阿里云生活服务平台开发手册——蓝牙设备开发一节中的内容

接下来我们来分析AliosThings顶层源码目录的makefile文件,这个文件位于:

1
AliOS-Things-SDK/build/Makefile

接下来我们就来简单分析一下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
# makefile 默认目标
default: all

unexport NAME # For compatibility with Windows Subsystem Linux

export HOST_OS
EXPECTED_HOST_OS := Linux64 Win32 OSX
# 检查是否支持此操作系统
$(if $(filter $(EXPECTED_HOST_OS),$(HOST_OS)),,$(error Sorry your OS($(HOST_OS)) is not supported, please use one of $(subst Win32,Windows,$(EXPECTED_HOST_OS))))

export SOURCE_ROOT ?= ./
export BUILD_DIR ?= out
export MAKEFILES_PATH := $(SOURCE_ROOT)/build/build_rules
export SCRIPTS_PATH := $(SOURCE_ROOT)/build/scripts

# 制定make编译时的作业数量,也就是使用多少个内核去参与编译过程 -j4
JOBS ?=4
ifeq (,$(SUB_BUILD))
JOBSNO := -j$(JOBS)
endif
# makefile 目标
MAKEFILE_TARGETS := clean distclean help # targets used by makefile

# 不同操作系统下的执行命令解析
include $(MAKEFILES_PATH)/aos_host_cmd.mk
# kconfig 支持,调用 aos_kconfig.mk
include $(MAKEFILES_PATH)/aos_kconfig.mk
# 检查aos-cube版本号
define CHECK_UCUBE_VERSION
$(if $(findstring 0.2,$(shell aos --version)),$(error aos-cube 0.3.x or newer is required, please update your aos-cube first! (eg. $$ aos upgrade or $$ aos upgrade aos-cube, depends on the version of aos tool you are using)),)
endef

$(call CHECK_UCUBE_VERSION)
# 没有配置文件打印错误函数
define NO_CONFIG_ERROR
$(info Please configure first:)
$(info *********************************************************************)
$(info $$ aos make <app>@<board> -c config)
$(info ---> Or more config: $$ aos make menuconfig)
$(info *********************************************************************)
$(error No Config Found!)
endef
# 目标平台无效 打印错误函数
define TARGET_DEPRECATED_ERROR
$(error Build Target Deprecated!)
endef
# 编译不兼容 错误打印
define BUILD_INCOMPATIBLE_ERROR
$(info *********************************************************************)
$(info The $(1) is incompatible with "aos make")
$(info )
$(info Please refer to its README and build it with proper tools)
$(info *********************************************************************)
$(error Build Incompatible!)
endef
# all目标生成,检查是否有 .config 文件,在 aos_kconfig.mk 指定
all:
$(QUIET)$(if $(wildcard $(AOS_CONFIG)),,$(call NO_CONFIG_ERROR))

#
# Process build strings
#
# MAKECMDGOALS 执行make 命令时指定的参数
BUILD_SUBTARGETS := .config .menuconfig
# 除去 SDK自定义的目标
MAKEFILE_TARGETS += export_linkkit_sdk restore_linkkit_sdk export-keil export-iar 2ndboot
export BUILD_STRING ?= $(strip $(filter-out $(MAKEFILE_TARGETS), $(MAKECMDGOALS)))

# Set IDE if export-* is specified
# 配置IDE 主要时针对keil和iar
ifneq ($(filter export-keil, $(MAKECMDGOALS)),)
export IDE := keil
else ifneq ($(filter export-iar, $(MAKECMDGOALS)),)
export IDE := iar
endif
# make 目标是否位 生成.config ,则先删除之前的配置文件
ifneq ($(filter %.config %.menuconfig, $(MAKECMDGOALS)),)
$(shell rm -rf .config .defconfig out/config)
endif
# 是否执行menuconfig
ifneq ($(filter menuconfig, $(MAKECMDGOALS)),)
export BUILD_STRING :=
# 如果编译字符串为空,则.config文件中获取
else ifeq ($(BUILD_STRING),)
# Get BUILD_STRING from AOS_CONFIG
ifneq ($(wildcard $(AOS_CONFIG)),)
include $(AOS_CONFIG)
# 首先从.config文件中获取到AOS_BUILD_APPAOS_BUILD_BOARD
# 比如 esp8266
# AOS_BUILD_BOARD="esp8266"
# AOS_BUILD_APP="helloworld_esp8266"
# 最终 BUILD_STRING = helloworld_esp8266@board_esp8266
BUILD_STRING = $(strip $(subst @board_,@,$(subst ",,$(AOS_BUILD_APP)@$(AOS_BUILD_BOARD))))
endif
endif

# Strip subtargets from BUILD_STRING
# 生成子目标需要做写处理
$(foreach subtarget, $(BUILD_SUBTARGETS), $(eval BUILD_STRING := $(subst $(subtarget),,$(BUILD_STRING))))
subtarget := $(lastword $(subst @, ,$(BUILD_STRING)))
$(if $(findstring .,$(subtarget)),$(error Parameter for "-c" option Unknown "$(lastword $(subst ., ,$(subtarget)))"!),)
export CLEANED_BUILD_STRING := $(BUILD_STRING)

export OUTPUT_DIR := $(BUILD_DIR)/$(CLEANED_BUILD_STRING)$(MBINS)
export AUTO_COMPONENT_DIR := $(OUTPUT_DIR)/auto_component

#
# PreCheck for build configs
#

# Enable .config and autoconf.h in build
ifeq ($(NOCONFIG),)

# Get AOS_BUILD_APP, AOS_BUILD_BOARD from BUILD_STRING for creating
# AOS_CONFIG if it is not existing
ifneq ($(BUILD_STRING),)

ifeq ($(wildcard $(AOS_CONFIG)),)
ifneq ($(findstring @, $(MAKECMDGOALS)),)
ifeq ($(filter %.config %.menuconfig, $(MAKECMDGOALS)),)
$(info )
$(info Build command updated, please follow steps:)
$(info *********************************************************************)
$(info Step 1: config:)
$(info $$ aos make $(BUILD_STRING) -c config)
$(info ---> Or more config: $$ aos make menuconfig)
$(info )
$(info Step 2: build:)
$(info $$ aos make # append VAR=value if needed)
$(info *********************************************************************)
$(call TARGET_DEPRECATED_ERROR)
endif
endif

else
ifneq ($(findstring @, $(MAKECMDGOALS)),)
ifeq ($(filter %.config %.menuconfig, $(MAKECMDGOALS)),)
$(info )
$(info Config completed, please run build directly: $$ aos make)
$(info )
$(call TARGET_DEPRECATED_ERROR)
endif
endif
endif

ifeq ($(findstring @,$(BUILD_STRING)),)
$(error Unknown Target "$(BUILD_STRING)"!)
endif
# 获取组件
components := $(subst @, ,$(BUILD_STRING))
ifneq ($(words $(components)),2)
$(error App/Board Unknown, Please check your config!)
endif

# get real app name and check if it available
# 获取app名字
appname = $(firstword $(components))
# 获取app目录
appdir = $(subst .,/,$(appname))
# 获取app makefile
appmkfile = $(wildcard $(APPDIR)/../$(appdir)/aos.mk $(SOURCE_ROOT)/application/*/$(appdir)/aos.mk $(SOURCE_ROOT)/application/*/*/$(appdir)/aos.mk $(SOURCE_ROOT)/application/$(appdir)/aos.mk $(SOURCE_ROOT)/test/develop/$(appdir)/aos.mk)
$(if $(appmkfile),\
$(eval include $(appmkfile)) $(eval real_appname = $(NAME)),\
$(if $(filter distclean clean help, $(MAKECMDGOALS)),,$(error App Unknown, Please make sure the "$(appname)" is existing!)))

# determine what app type should be enabled: example, profile, test
ifneq ($(findstring profile/,$(appmkfile)),)
export AOS_APP_TYPE := AOS_APP_PROFILE
else ifneq ($(findstring example/,$(appmkfile)),)
export AOS_APP_TYPE := AOS_APP_EXAMPLE
else ifneq ($(findstring develop/,$(appmkfile)),)
export AOS_APP_TYPE :=
else
export AOS_APP_TYPE := AOS_APP_LOCALAPP
endif
# 获取开发板名字
boardname = $(word 2, $(components))
# 获取开发板mk
boardmkfile = $(wildcard $(SOURCE_ROOT)/platform/board/$(boardname)/aos.mk)
boardmkfile_legacy = $(wildcard $(SOURCE_ROOT)/platform/board/board_legacy/$(boardname)/aos.mk)
ifneq ($(boardmkfile),)
ifneq ($(boardmkfile_legacy),)
$(error ***** boardname Error, Mutiple boardname***** ***)
endif
endif

$(if $(boardmkfile),\
$(eval include $(boardmkfile)) $(eval real_boardname = $(NAME)),\
$(eval real_boardname = $(boardname)))

$(if $(boardmkfile_legacy),\
$(eval include $(boardmkfile_legacy)) $(eval real_boardname = $(NAME)),\
$(eval real_boardname = $(boardname)))

$(if $(filter no,$(AOS_BUILD_COMPATIBLE)), $(call BUILD_INCOMPATIBLE_ERROR,$(boardname)))
ifneq ($(boardmkfile),)
defconfig = $(wildcard $(SOURCE_ROOT)/platform/board/$(boardname)/defconfig)
else
ifneq ($(boardmkfile_legacy),)
defconfig = $(wildcard $(SOURCE_ROOT)/platform/board/board_legacy/$(boardname)/defconfig)
endif
endif

ifneq ($(defconfig),)
export BOARD_DEFCONFIG := $(defconfig)
AOS_DEFCONFIG := $(BOARD_DEFCONFIG)
endif
# 获取当前的 app 和 board配置信息
export AOS_BOARD_CONFIG = AOS_BOARD_$(shell $(PYTHON) $(TR) $(subst -,_,$(patsubst board_%,%,$(real_boardname))))
export AOS_APP_CONFIG = AOS_APP_$(shell $(PYTHON) $(TR) $(subst -,_,$(patsubst app_%,%,$(real_appname))))

endif # $(BUILD_STRING)
endif # $(NOCONFIG)

# prebuild support
include $(MAKEFILES_PATH)/aos_prebuild.mk

# Support for MBINS build - deprecated! Not maintained any more!
export UNDERLINE
export RADIXPOINT

export MBINSTYPE_UPPER
export MBINSTYPE_LOWER

MBINS ?=
MBINS_APP ?=
ifeq (,$(MBINS))
MBINSTYPE_UPPER :=
MBINSTYPE_LOWER :=
UNDERLINE :=
RADIXPOINT :=
else ifeq (app,$(MBINS))
MBINSTYPE_UPPER :=APP
MBINSTYPE_LOWER :=app
UNDERLINE :=_
RADIXPOINT :=.
else ifeq (kernel,$(MBINS))
MBINSTYPE_UPPER :=KERNEL
MBINSTYPE_LOWER :=kernel
UNDERLINE :=_
RADIXPOINT :=.
else
$(error ***** MBINS Error, Valid MBINS: [MBINS=app MBINS=kernel] ***** ***)
endif

define MBINS_EXIT
$(error ***** This Platform Not Support Multi-Bins! [SUPPORT_MBINS:=$(SUPPORT_MBINS)] Not Use Option:[MBINs=*] ***** ***)
endef

# Define help message
define USAGE_TEXT

Usage: aos make <target> -c <[config|menuconfig]>
aos make menuconfig
aos make [VERBOSE=1] [BUILD_TYPE=debug|inspect|release_log|release]
[clean|distclean|update|export-keil|export-iar] ...

<target>
One each of the following mandatory components separated by '@'
* Application (apps in application/example/, application/profile/ ...)
* Board (boards in platform/board/)

[VERBOSE=1]
Shows the commands as they are being executed

[BUILD_TYPE=debug|inspect|release_log|release]
Build for debug, inspect, release_log or release configurations

Notes
* Component names are case sensitive
* Component names MUST NOT include space or '@' characters
* BUILD_TYPE is set as release_log by default

Example Usage:
Configure and build with default configs:
$> aos make helloworld@mk3060 -c config
$> aos make

Configure and build with customize configs:
$> aos make menuconfig
$> aos make

Customize configs from default and build:
$> aos make helloworld@mk3060 -c menuconfig
$> aos make

Update the metadata for your project:
$> aos make update

Clean output directory (without configs)
$> aos make clean

Clean output directory and configs
$> aos make distclean
endef

############################
# Extra options:
# CHECK_HEADERS=1 : builds header files to test for their completeness
############################

export VERBOSE
export SUB_BUILD

COMPONENT_DEPENDENCY_SCRIPT := $(SCRIPTS_PATH)/component_dependencies.py
COMPONENT_DEPENDENCY = $(PYTHON) $(COMPONENT_DEPENDENCY_SCRIPT)
export COMPONENT_DEPENDENCY

.PHONY: $(BUILD_STRING) main_app clean help export_linkkit_sdk restore_linkkit_sdk

help:
$(info $(USAGE_TEXT))
$(QUIET)$(ECHO)

clean:
$(QUIET)$(ECHO) Cleaning...
$(QUIET)$(CLEAN_COMMAND)
$(QUIET)rm -rf build/scripts/config_mk.py
ifneq (,$(wildcard build/scripts/*.pyc))
$(QUIET)rm -rf build/scripts/*.pyc
endif
$(QUIET)$(ECHO) Done

distclean: clean
ifneq (,$(APPDIR))
$(QUIET)rm -f $(APPDIR)/.config $(APPDIR)/.config.retry $(APPDIR)/.config.old $(APPDIR)/.config.cmd $(APPDIR)/.defconfig $(APPDIR)/..config.tmp $(APPDIR)/aos_config.h
$(QUIET)$(CP) $(APPDIR)/.important.bak/.config $(APPDIR)/.config
else
$(QUIET)rm -f .config .config.retry .config.old .config.cmd .defconfig ..config.tmp aos_config.h
endif

ifneq ($(BUILD_STRING),)
ifeq ($(findstring @,$(BUILD_STRING)),)
$(error Unknown target $(BUILD_STRING) ...)
endif

# Include toolchain
ifeq ($(IDE),iar)
export COMPILER := iar
else ifeq ($(IDE),keil)
export COMPILER := armcc
else ifeq ($(IDE),rvct)
export COMPILER := rvct
endif

ifeq ($(COMPILER),armcc)
export TOOLCHAIN_MAKEFILE := $(MAKEFILES_PATH)/toolchain/aos_toolchain_armcc.mk
else ifeq ($(COMPILER),rvct)
export TOOLCHAIN_MAKEFILE := $(MAKEFILES_PATH)/toolchain/aos_toolchain_rvct.mk
else ifeq ($(COMPILER),iar)
export TOOLCHAIN_MAKEFILE := $(MAKEFILES_PATH)/toolchain/aos_toolchain_iar.mk
else
export TOOLCHAIN_MAKEFILE := $(MAKEFILES_PATH)/toolchain/aos_toolchain_gcc.mk
endif

# Support for test suite - create auto_component and register init functions for test components
AUTO_COMPONENT = $(AUTO_COMPONENT_DIR)/aos.mk
ifneq ($(test), )
TEST_COMPONENT_COLLECTION = $(AUTO_COMPONENT_DIR)/test_collection.$(test)
else
TEST_COMPONENT_COLLECTION = $(AUTO_COMPONENT_DIR)/test_collection.default
endif

$(AUTO_COMPONENT): $(TEST_COMPONENT_COLLECTION)
$(QUIET)$(PYTHON) $(SCRIPTS_PATH)/auto_component.py $(AUTO_COMPONENT_DIR)

$(TEST_COMPONENT_COLLECTION):
$(QUIET)$(PYTHON) $(SCRIPTS_PATH)/gen_test_collection.py $(AUTO_COMPONENT_DIR) $(TEST_COMPONENT_COLLECTION)

-include $(OUTPUT_DIR)/.depends.mk
-include $(OUTPUT_DIR)/.depends_2ndboot.mk
# Target to create config.mk file
# 生成config.mk文件
$(OUTPUT_DIR)/config.mk: $(MAKEFILES_PATH)/aos_target_config.mk $(MAKEFILES_PATH)/aos_host_cmd.mk $(TOOLCHAIN_MAKEFILE) $(AOS_SDK_MAKEFILES) $(AUTO_COMPONENT) $(AOS_PRE_BUILD_TARGETS)
$(QUIET)$(ECHO) $(if $(AOS_SDK_MAKEFILES),Applying changes made to: $?,Making config file for first time)
$(QUIET)$(MAKE) -r $(SILENT) -f $(MAKEFILES_PATH)/aos_target_config.mk $(CLEANED_BUILD_STRING)

ifeq ($(NOCONFIG),)
$(OUTPUT_DIR)/config.mk: $(AOS_CONFIG_DIR)/autoconf.h
endif

endif # ($(BUILD_STRING),)

ifneq ($(MBINS),)
ifneq ($(SUPPORT_MBINS),yes)
MBINS_ERROR := error
endif
endif
# make file 目标依赖于 编译字符串信息
all: $(BUILD_STRING)

$(BUILD_STRING): $(AOS_PRE_BUILD_TARGETS)
# 是否支持2次引导程序 ,AOS_SDK_2NDBOOT_SUPPORT定义在mk3080工程源码目录board/mk3080/aos.mk中,值为yes
ifeq ($(AOS_SDK_2NDBOOT_SUPPORT),yes)
$(BUILD_STRING): main_app 2ndboot
else
$(BUILD_STRING): main_app
endif

ifeq ($(IDE),keil)
main_app: export-keil
else ifeq ($(IDE),iar)
main_app: export-iar
endif

.PHONY: show-build-info
show-build-info:
$(QUIET)$(ECHO)
$(QUIET)$(ECHO) Build Configuration:
$(QUIET)$(ECHO) ====================
$(QUIET)$(ECHO) App: $(appname)
$(QUIET)$(ECHO) Board: $(boardname)
$(QUIET)$(ECHO) ====================
$(QUIET)$(ECHO)

.PHONY: prebuild
ifeq ($(NOCONFIG),)
prebuild: show-build-info
endif

prebuild: $(AOS_PRE_BUILD_TARGETS)
# 初始化编译环境
init-build-env: $(OUTPUT_DIR)/config.mk
# 创建 bin lib include 目录
$(QUIET)$(call MKDIR, $(OUTPUT_DIR)/binary)
$(QUIET)$(call MKDIR, $(OUTPUT_DIR)/libraries)
$(QUIET)$(call MKDIR, $(OUTPUT_DIR)/includes)
# 根据config.mk自动生成代码
$(QUIET)$(PYTHON) $(SCRIPTS_PATH)/gen_auto_code.py $(OUTPUT_DIR)/config.mk $(AUTO_COMPONENT_DIR)
# main_app 依赖于多个文件
# prebuild 检查组件是否完整
# config.mk 基于 aos_target_build 生成的全局变量
# init-build-env 初始化编译环境
main_app: prebuild $(OUTPUT_DIR)/config.mk $(YOS_SDK_PRE_APP_BUILDS) $(MAKEFILES_PATH)/aos_target_build.mk init-build-env
$(if $(MBINS_ERROR), $(call MBINS_EXIT))
# 打印开始编译
$(QUIET)$(ECHO) Build AOS Now
$(QUIET)$(ECHO) TOOLCHAIN_PATH=$(TOOLCHAIN_PATH)
# 执行aos_target_build 进行编译
$(QUIET)$(MAKE) -r $(JOBSNO) $(SILENT) -f $(MAKEFILES_PATH)/aos_target_build.mk $(CLEANED_BUILD_STRING) $(PASSDOWN_TARGETS)
$(QUIET)$(ECHO) Build complete: $(BUILD_STRING)

# 生成2次引导程序目标,根据main_app分析
$(OUTPUT_DIR)/config_2ndboot.mk: $(MAKEFILES_PATH)/aos_target_config.mk $(MAKEFILES_PATH)/aos_host_cmd.mk $(TOOLCHAIN_MK) $(AOS_SDK_MAKEFILES) $(AUTO_COMPONENT) $(AOS_CONFIG_DIR)/autoconf.h
$(QUIET)$(ECHO) $(if $(AOS_SDK_2NDBOOT_MAKEFILES),Applying changes made to: $?,Making config file for first time)
$(QUIET)$(MAKE) -r $(SILENT) -f $(MAKEFILES_PATH)/aos_target_config.mk $(CLEANED_BUILD_STRING) AOS_2NDBOOT_SUPPORT=yes

2ndboot: prebuild $(OUTPUT_DIR)/config_2ndboot.mk $(MAKEFILES_PATH)/aos_target_build.mk
$(if $(MBINS_ERROR), $(call MBINS_EXIT))
$(QUIET)$(ECHO) Build AOS Second Boot Now
$(QUIET)$(ECHO) TOOLCHAIN_PATH=$(TOOLCHAIN_PATH)
$(QUIET)$(call MKDIR, $(OUTPUT_DIR)/binary)
$(QUIET)$(call MKDIR, $(OUTPUT_DIR)/libraries)
$(QUIET)$(PYTHON) $(SCRIPTS_PATH)/gen_auto_code.py $(OUTPUT_DIR)/config_2ndboot.mk $(AUTO_COMPONENT_DIR)
$(QUIET)$(MAKE) -r $(SILENT) $(JOBSNO) -f $(MAKEFILES_PATH)/aos_target_build.mk $(CLEANED_BUILD_STRING) $(PASSDOWN_TARGETS) AOS_2NDBOOT_SUPPORT=yes
$(QUIET)$(PYTHON) $(SCRIPTS_PATH)/gen_output.py $(OUTPUT_DIR)/binary $(AOS_CONFIG)
$(QUIET)$(ECHO) Build 2nd boot complete: $(BUILD_STRING)

ifeq (littlevgl_simulate@linuxhost,$(CLEANED_BUILD_STRING))
./out/littlevgl_simulate@linuxhost/binary/littlevgl_simulate@linuxhost.elf
endif

export_linkkit_sdk:
$(QUIET)$(call MKDIR, $(BUILD_DIR))
$(QUIET)$(PYTHON) $(SCRIPTS_PATH)/gen_linkkit_sdk.py $(SOURCE_ROOT) $(BUILD_DIR)/export

restore_linkkit_sdk:
$(QUIET)$(call MKDIR, $(BUILD_DIR))
$(QUIET)$(PYTHON) $(SCRIPTS_PATH)/restore_linkkit_sdk.py $(SOURCE_ROOT) $(BUILD_DIR)/export

export-project: $(OUTPUT_DIR)/config.mk
$(QUIET)$(MAKE) -r $(SILENT) -f $(MAKEFILES_PATH)/aos_3rd_project.mk $(BUILD_STRING)

export-keil: export-project
$(QUIET)$(ECHO) Build Keil project complete

export-iar: export-project
$(QUIET)$(ECHO) Build IAR Project complete

%.config: $(AOS_CONFIG)
$(QUIET):

%.menuconfig: $(AOS_CONFIG)
$(QUIET)$(MAKE) -r $(SILENT) -f $(MAKEFILES_PATH)/aos_kconfig.mk menuconfig_only