[AliOS-Things编译系统] 由一个宏开关出发

在阅读 AliOS CLI 组件代码时,发现有一个 CONFIG_AOS_CLI 的宏开关,用于控制是否开启 CLI 组件的功能,但是找了半天也没看到其定义。事实上,类似 CONFIG_AOS_CLI 这样的控制组件开/关的宏定义在 AliOS 核心代码中非常多,进一步搜索工程,发现与 AliOS 的编译系统有关,因此花一些心思学习一下 AliOS 的编译系统。

AliOS 的整个编译系统很复杂,为了不至于陷入进入,因此我只捋一捋自己的思路。

关于 AliOS 的系列博客,请参考 AliOS-Things系列学习笔记-目录

怎么下手

搜遍了 AliOS-Things 的整个工程的代码,都没有在源文件(.c .h)中找到 CONFIG_AOS_CLI 的定义,只在 toos/cli/cli.mk 中看到这样一行代码:

1
GLOBAL_DEFINES  += HAVE_NOT_ADVANCED_FORMATE CONFIG_AOS_CLI

由于这是一个 .mk(即makefile)文件,因此可以断定,这个宏开关是在编译时由编译命令传递给源文件的。那么产生了更进一步的问题,即这个 .mk 文件在什么时候会被调用的?

以关键字 cli.mk 搜索整个工程的所有文件,但是没有搜到任何结果,猜测这应该是编译系统根据某些条件自动调用到这个 .mk 文件的。

如何证明?

从命令下手

想想我们是怎么编译程序的,我们执行命令 aos make helloworld@mk3060,所以我们可以试试拿 aos 这个命令开刀。

执行命令 aos --help 看看提示我们啥。

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
work@ubuntu:~/me/AliOS-Things$ aos --help
usage: aos [-h] [--version] ...

Code management tool for aos - https://code.aliyun.com/aos/aos
version 0.0.6

Use 'aos <command> -h|--help' for detailed help.
Online manual and guide available at https://code.aliyun.com/aos/aos-cube

optional arguments:
-h, --help show this help message and exit
--version print version number and exit

Commands:

new Create new aos program or component
import Import program from URL
add Add component from URL
remove Remove component
deploy Find and add missing components and source codes
codes Import the optional component from the remote repository
publish Publish program or component
update Update to branch, tag, revision or latest
sync Synchronize aos component references
ls View dependency tree
status Show version control status

make Make aos program/component
makelib Compile static library

config Tool configuration

help This help screen

看了看,aos 主要就是用于管理整个工程,只是发现其中有一个命令(Commands)是 make - Make aos program/comonent,即 aos make 用于编译 aos 的程序,并没有其它太多对我们有价值的东西。

继续执行命令 aos make --help 试试呢?事实证明,这个命令显示的不是 aos make 的帮助信息!这算不算一个小 BUG 呢?

后来偶然发现,执行命令 aos make (不加其它参数)会打印 aos make 的帮助信息。

分析 aos make

aos make 显示的打印信息如下:

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
work@ubuntu:~/me/AliOS-Things$ aos make
build/Makefile:119: *** Aborting due to invalid targets

Usage: make <target> [download] [run | debug] [JTAG=xxx] [total] [VERBOSE=1] [BINS=app/framework/kernel]
make run

<target>
One each of the following mandatory [and optional] components separated by '@'
* Application (apps in example)
* Board (mk3060 linuxhost b_l475e)
* [debug | release] Building for debug or release configurations

[download]
Download firmware image to target platform

[run]
Reset and run an application on the target hardware

[total]
Build all targets related to this application and board

[JTAG=xxx]
JTAG interface configuration file from the tools/OpenOCD dirctory
Default option is jlink_swd

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

[BINS=app/framework/kernel]
Build bins: app or framework or kernel

Notes
* Component names are case sensitive
* 'rhino' and 'debug' are reserved component names
* Component names MUST NOT include space or '@' characters
* Building for debug is assumed unless '@release' is appended to the target

Example Usage
Build for Debug
make helloworld@mk108

Build, Download and Run using the default USB-JTAG programming interface
make helloworld@mk108 download run

Build for Release
make helloworld@mk108@release

Reset and run an application on the target hardware
make run

Clean output directory
make clean. Stop.

分析几个自己感兴趣的参数。

VERBOSE

作为老司机的我,发现最感兴趣的参数是 [VERBOSE=1],因为在编译的时候加上这个参数后会打印更多的信息,尤其是会打印都执行了哪些命令。

现在试试执行命令 aos make helloworld@linuxhost VERBOSE=1,是不是发现打印多了很多东西呢?更多细节慢慢去发觉吧。

在实际的运用过程中,我发现 [VERBOSE=1] 给我最大的用处是当我通过 J-Link 下载程序 MK3060 失败时发现失败的原因。在执行命令 aos make helloworld@mk3060 JTAG=jlink download 时,会发现打印这句话。

echo Downloading application to partition: 2 size: 304332 bytes…
Downloading application to partition: 2 size: 304332 bytes…
“/home/work/me/AliOS-Things/build/OpenOCD/Linux64/openocd” -s ./ -f .//build/OpenOCD/interface/jlink.cfg -f .//build/OpenOCD/beken/beken.cfg -c init -c soft_reset_halt -c flash_init -c “flash_erase 0x13000 0x8E000” -c “load_image out/helloworld@mk3060/binary/helloworld@mk3060.bin 0x12000” -c shutdown >> out/openocd.log 2>&1 && echo Download complete && “/home/work/me/AliOS-Things/build/cmd/linux64/echo” || echo Download failed

注意到上面命令中的这句话 “>> out/openocd.log 2>&1”,它表示将 OpenOCD 输出的信息重定向到 out/openocd.log 这个文件中。所以,如果你通过 JTag 下载程序失败(提示 Download failed),则查看这个文件吧,你可以很快定位问题。

TARGET

这个参数表示你想要编译哪个应用程序,想将其运行在哪个平台,想让其作为 Debug 版本编译(程序会多打印很多调试信息)还是作为 Release 版本编译。

如果你想编译 helloworld这个程序,且希望其运行在 Linux 上,则执行 “aos make helloworld@linuxhost”;如果将其运行在 MK3060 平台上,则运行 “aos make hellworld@mk3060”;如果今后程序测试稳定了,则可以 Release,则运行 “aos make hellworld@mk3060#release”。

注意最后一个是可选的。

download

没啥多说的,程序编译后自动烧写到目标平台,例如 “aos make helloworld@mk3060 JTAG=jlink download”。

JTAG

如果要将程序烧写到 MK3060,则需要加上 JTAG=jlink 这个选项。例如 “aos make helloworld@mk3060 JTAG=jlink download”。

run

编译后,不仅将程序烧写到板子上,还让其自动复位并运行,例如 “aos make hellworld@mk3060 JTAG=jlink download run”。

total

MK3060 里面的程序包括 Bootloader+APP 这两部分,只是 Bootloader 在模组出厂时就已经烧写好了,我们不需要重新烧写。我们只需要烧写 APP。当然如果想对 Bootloader 进行升级的话,强制把 Bootloader 也烧写进入。

所以,total = bootloader + app 。

MK3060 的 bootloader 的二进制镜像文件的路径是 board/mk3060/boot.bin。

编译时入口

执行命令 “aos make helloworld@linuxhost VERBOSE=1”,可以看到打印的消息的最前面有这样一句话

“/home/work/me/AliOS-Things/build/cmd/linux64/make” -r -f .//build/aos_target_config.mk helloworld@linuxhost

这句话的意思是执行 make 命令,-f 选项表面所使用的 makefile 文件是 ./build/aos_target_config.mk,因此我们需要看这个文件。

我们后续博客再简单分析下这个 makefile 文件。

学习资料