1.5 鸿蒙编译子系统详解
编译子系统提供了鸿蒙系统的编译构建架构,主要由shel脚本、python脚本、gn脚本、json配置文件等组成。
1.5.1 系统架构
编译子系统官方架构图:
编译子系统位于目录build,主要的目录结构如下:
./build
├── build_scripts //编译入口脚本
├── common //共用配置
├── compile_standard_whitelist.json //白名单配置,4.0新增
├── config //gn配置,语言、编译器、os、检查、安全等
├── core //gn入口及配置
├── docs //文档
├── hb //hb工具源码,编译脚本
├── lite //轻量级编译相关
├── ohos //鸿蒙相关
├── ohos.gni //gn导入总入口
├── ohos_var.gni //gn全局变量定义
├── prebuilts_download_config.json //预编译配置
├── prebuilts_download.py //预编译下载脚本
├── prebuilts_download.sh //预编译下载入口
├── rust //rust配置
├── scripts //主要编译脚本
├── subsystem_config.json //子系统配置
├── templates //gn模板定义
├── test.gni //测试的配置
├── toolchain //gn工具链配置
├── tools //工具,依赖检查、组件检查等
......
1.5.2 预编译下载
在编译开始前,需要下载工具软件,安装必要的依赖库。
执行命令:
build/prebuilts_download.sh
sh脚本的执行流程:
预编译安装完成后,会生成prebuilts目录,其目录结构如下:
./prebuilts/
├── ark_tools
│ └── ark_js_prebuilts
├── build-tools
│ ├── common
│ └── linux-x86
├── clang
│ └── ohos
├── cmake
│ ├── linux-x86
│ └── windows-x86
├── develop_tools
│ ├── bpftool
│ └── pahole
├── gcc
│ └── linux-x86
├── mingw-w64
│ └── ohos
├── ohos-sdk
│ └── linux
├── python
│ └── linux-x86
└── rustc
├── linux-x86_64
├── rust-1.68.0-dev-x86_64-unknown-linux-gnu
├── rust-std-1.68.0-dev-aarch64-linux-ohos
└── rust-std-1.68.0-dev-armv7-linux-ohos
编译中主要使用的工具是prebuilts/build-tools/linux-x86/bin下的gn、ninja,以及llvm工具链prebuilts/clang/ohos/linux-x86_64/llvm/bin。
1.5.3 编译流程
预编译完成后,就可以执行编译命令了,以润和rk3568大禹200开发板编译为例,编译命令:
#方式1
./build.sh --product-name rk3568
#方式2
./build.py -p rk3568
#方式3,hb需要提前安装,请参照之前的教程
hb set
hb build -f
1.5.3.1 build.sh脚本
build.sh处理流程:
build.sh中执行py脚本命令为:
prebuilts/python/linux-x86/current/bin/python3 build/hb/main.py build --product-name rk3568
1.5.3.2 build.py脚本
build.py处理流程:
与build.sh是一样,也是执行build/hb/main.py脚本。
1.5.3.3 hb命令
使用hb命令前,先要进行安装,再进行编译,命令为
#安装hb
pip3 install --user build/hb
#如果安装了旧版本,需要先进行卸载
#pip3 uninstall ohos-build
#选择产品,这里选择standard->hihope->rk3568
hb set
#编译,-f是全部编译
hb build -f
hb被安装在~/.local/bin目录下,其源码如下:
#!/usr/bin/python3
# -*- coding: utf-8 -*-
import re
import sys
from hb.__main__ import main
if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
sys.exit(main())
这里导入main并执行的的hb.__main__,位于脚本~/.local/lib/python3.8/site-packages/hb/__main__.py。
其主要源码如下:
def main():
in_ohos_dir, ohos_root_path = is_in_ohos_dir()
if in_ohos_dir :
entry_path = os.path.join(os.path.abspath(os.path.relpath(
ohos_root_path, os.path.curdir)), 'build', 'hb', 'main.py')
spec = importlib.util.spec_from_file_location('main', entry_path)
api = importlib.util.module_from_spec(spec)
spec.loader.exec_module(api)
main_api = api.Main()
main_api.main()
else:
raise Exception(
"[OHOS_ERROR]: Please call hb utilities inside ohos source directory")
if __name__ == "__main__":
sys.exit(main())
从源码可以看出,main()从build/hb/main.py导入main函数,并执行。
总结一下:
尽管鸿蒙有三种编译方式,但最终执行的脚本都是build/hb/build.py。比较起来,shell脚本执行的内容最全面,hb工具较简洁。
需要注意的是,如果是复杂的编译需求,比如有多个源码目录、多个鸿蒙版本、多个硬件级别的鸿蒙产品编译时,或者在自动编译部署的环境下,建议卸载hb,使用py脚本或是sh脚本。