首先我们先来熟悉几个概念:
- 子系统
子系统是一个逻辑概念,它由一个或多个具体的组件组成。OpenHarmony整体遵从分层设计,从下向上依次为:内核层、系统服务层、框架层和应用层。系统功能按照“系统 > 子系统 > 组件”逐级展开,在多设备部署场景下,支持根据实际需求裁剪某些非必要的子系统或组件。
- 组件
系统最小的可复用、可配置、可裁剪的功能单元。组件具备目录独立可并行开发、可独立编译、可独立测试的特征。
- gn
Generate ninja的缩写,用于产生ninja文件。
- ninja
ninja是一个专注于速度的小型构建系统。
- hb
OpenHarmony的命令行工具,用来执行编译命令。
hb 命令
hb 的源代码在build/lite/hb路径下,其入口函数为__main__.py中的main()。
hb 支持以下命令:
set 构建配置
env 显示构建配置变量
build 编译
clean 清空编译输出
build/lite/hb_internal中有各个命令的具体实现
set和build比较重要,首先来看一下set命令:
hb set
hb set的作用是生成产品配置文件,执行后会在根目录下生成ohos_config.json文件
文件内容如下:
代码路径为build/lite/hb/set/set.py,设备类型不改变的情况下,不需要反复执行该命令。
hb build
hb build的作用是根据配置信息生成编译指导文件build.ninja。
脚本执行过程如下:
调用 gn_build 使用 gn gen生成 *.ninja 文件
调用 ninja_build 使用 ninja -w dupbuild=warn -C 生成 *.o *.so *.bin 等最后的文件
代码路径为:build/lite/hb/build/build.py
通过对上述一些概念的理解,我们接下来说一下OpenHarmony编译所用的工具和编译实现思想:
- 工具
1.编译链接的最上层是Python脚本,使用python脚本进行组织,可以很好的实现跨平台编译
2.除了Python外还需要GN、Ninja、GCC来构建系统。
GN作为编译逻辑部分,将各级子系统和组件组织起来。
Ninja作为构建中间部分,他用最简单最快速的方式将编译文件编译参数传递给编译系统。
GCC作为编译部分,通常随编译系统而变化。
- 思路
1.执行hb 命令的Python脚本,读取开发板配置:主要包括开发板使用的编译工具链、编译链接命令和选项等。
读取的主要配置文件有
Build\lite\ohos_var.gni:定义使用于所有组件的全局变量。
device{company}{board}\config.gni:这是编译 LiteOS_A 内核所需要用到的配置。
vendor{company}{board}\config.json:这是开发板提供的产品全量配置表:子系统、组件列表等等。
通过 hb build 传进去的参数,比如 -n 表示编译 NDK,则会将 ohos_build_ndk 变量由默认的 FALSE 改为 TRUE。
2.调用 gn:调用 gn gen 命令,读取产品配置(主要包括开发板、内核、选择的组件等)生成解决方案 out 目录和 ninja 文件。
3.调用 ninja:调用 ninja -C out/company/product 启动编译。
4.系统镜像打包:将组件编译产物打包,制作文件系统镜像。
build/lite/BUILD.gn 这个文件中的 group(“ohos”) 的分解,最终得到"ohos"的完整的依赖关系
C.调用 ninja 启动编译
这里就开始根据上一步生成的 .ninja 文件里的规则调用编译工具链来编译各目录下的源文件了,生成 .o/.a/.so/ 可执行文件 等等。
其中 .so 文件会先在 out{company}{board}\ 目录下生成,等编译完之后会转移到 out{company}{board}\libs\usr\ 目录下,还生成了 .ninja_log 和 .ninja_deps 文件。
D. 打包制作系统镜像