提交 e32a6912 编写于 作者: Z zwx1138075

Doc仓下编译构建开发文档更新

Signed-off-by: Nzwx1138075 <zhuyunping@huawei.com>
上级 e8e444d0
# 编译形态整体说明
**编译构建支持的产品列表**
| 编译形态 | 开发板 | 主芯片 | 内核 | 系统类型 |
| ----------------------------- | --------------- | ----------- | ----------- | ----------- |
| neptune100 | neptune100 | winnermicro | liteos_m | mini |
| rk3568 | rk3568 | rockchip | linux | standard |
| rk3568_mini_system | rk3568 | rockchip | linux | standard |
| bearpi_hm_micro | bearpi_hm_micro | stm32mp1xx | liteos_a | small |
| bearpi_hm_nano | bearpi_hm_nano | hi3861v100 | liteos_m | mini |
| wifiiot_hispark_pegasus | hispark_pegasus | hi3861v100 | liteos_m | mini |
| ipcamera_hispark_aries | hispark_aries | hi3518ev300 | liteos_a | small |
| ipcamera_hispark_taurus | hispark_taurus | hi3516dv300 | liteos_a | small |
| ipcamera_hispark_taurus_linux | hispark_taurus | hi3516dv300 | linux | small |
| hispark_taurus_standard | hispark_taurus | hi3516dv300 | linux | standard |
| watchos | hispark_taurus | hi3516dv300 | linux | standard |
| hispark_phoenix | hispark_phoenix | hi3751v350 | linux | standard |
| hispark_taurus_mini_system | hispark_taurus | hi3516dv300 | liteos_a | mini |
| hispark_pegasus_mini_system | hispark_pegasus | hi3861v100 | liteos_m | mini |
| gr5515_sk_iotlink_demo | gr5515_sk | gr551x | liteos_m | mini |
| gr5515_sk_xts_demo | gr5515_sk | gr551x | liteos_m | mini |
| wifi_demo | dev_wifi_a | asr582x | liteos_m | mini |
| xts_demo | dev_wifi_a | asr582x | liteos_m | mini |
| display_demo | v200zr | bes2600 | liteos_m | mini |
| xts_demo | v200zr | bes2600 | liteos_m | mini |
| iotlink_demo | v200zr | bes2600 | liteos_m | mini |
| mini_distributed_music_player | v200zr | bes2600 | liteos_m | mini |
| niobe407 | niobe407 | stm32f4xx | liteos_m | mini |
| qemu_mini_system_demo | arm_mps2_an386 | qemu | liteos_m | mini |
| qemu_cksy_mini_system_demo | SmartL_E802 | qemu | liteos_m | mini |
| qemu_cm55_mini_system_demo | arm_mps3_an547 | qemu | liteos_m | mini |
| qemu_xtensa_mini_system_demo | esp32 | qemu | liteos_m | mini |
| qemu_riscv_mini_system_demo | ricsv32_virt | qemu | liteos_m | mini |
| qemu_ca7_mini_system_demo | arm_virt | qemu | liteos_a | small |
| qemu_small_system_demo | arm_virt | qemu | liteos_a | small |
| qemu-arm-linux-min | qemu-arm-linux | qemu | linux | standard |
| qemu-arm-linux-headless | qemu-arm-linux | qemu | linux | standard |
| iotlink_demo | cst85_wblink | chipsea | liteos_m | mini |
| dsoftbus_demo | cst85_wblink | chipsea | liteos_m | mini |
| xts_demo | cst85_wblink | chipsea | liteos_m | mini |
......@@ -18,4 +18,5 @@
- [运行](quickstart-ide-standard-running-rk3568-running.md)
- 附录
- [Hi3516开发板介绍](quickstart-ide-standard-board-introduction-hi3516.md)
- [RK3568开发板介绍](quickstart-ide-standard-board-introduction-rk3568.md)
\ No newline at end of file
- [RK3568开发板介绍](quickstart-ide-standard-board-introduction-rk3568.md)
- [编译形态整体说明](quickstart-build.md)
\ No newline at end of file
......@@ -21,5 +21,6 @@
- 开发板介绍
- [Hi3516开发板介绍](quickstart-standard-board-introduction-hi3516.md)
- [RK3568开发板介绍](quickstart-standard-board-introduction-rk3568.md)
- [编译形态整体说明](quickstart-build.md)
- [参考信息](quickstart-standard-reference.md)
- [使用HiTool烧录代码](quickstart-standard-hitool.md)
\ No newline at end of file
......@@ -39,9 +39,9 @@ action("some_action") {
outputs = [ _output ]
args = [
...
"--output",
rebase_path(_output, root_build_dir),
...
"--output",
rebase_path(_output, root_build_dir),
...
]
...
}
......@@ -70,7 +70,7 @@ declare_args() {
- 加入"${target_name}"可以防止子目标重名。
- 加入双下划线可以很方便地区分出子目标属于哪一个模块,方便在出现问题时快速定位。
```
# 例3
template("ohos_shared_library") {
......@@ -137,17 +137,17 @@ import("//a.gni")
编译脚本实质上完成了两件工作:
1. **描述模块之间依赖关系(deps)**
实践过程中,最常出现的问题是**依赖关系缺失**
2. **描述模块编译的规则(rule)**
实践过程中,容易出现的问题是**输入和输出不明确**
依赖缺失会导致两个问题:
- **概率性编译错误**
```
# 例6
# 依赖关系缺失,导致概率性编译出错
......@@ -164,13 +164,13 @@ import("//a.gni")
deps = [ ":b" ]
}
```
上面的例子中,libb.so在链接的时候会链接liba.so,实质上构成b依赖a,但是b的依赖列表(deps)却没有声明对a的依赖。由于编译是并发执行的,如果libb.so在链接的时候liba.so还没有编译出来,就会出现编译错误。
由于liba.so也有可能在libb.so之前编译出来,所以依赖缺失导致的编译错误是概率性的。
- **依赖关系缺失导致模块没有参与编译**
还是上面的例子,如果我们指定ninja编译目标为images,由于images仅仅依赖b,所以a不会参与编译。由于b实质上依赖a, 这时b在链接时会出现必现错误。
有一种不太常见的问题是**过多的依赖****过多的依赖会降低并发,导致编译变慢**。见下面的例子:
......@@ -186,13 +186,13 @@ template("too_much_deps") {
action(_gen_resource_target) {
...
}
_compile_resource_target = "${target_name}__compile_res"
action(_compile_resource_target) {
deps = [":$_gen_resource_target"]
...
}
_compile_js_target = "${target_name}__js"
action(_compile_js_target) {
# 这个deps不需要
......@@ -261,20 +261,17 @@ write_file("a.out")
- **原生模板是最小功能模板**,无法提供external_deps的解析,notice收集,安装信息生成等的额外功能,这些额外功能最好是随着模块编译时同时生成,所以必须对原生模板做额外的扩展才能满足实际的需求。
- 当输入文件依赖的文件发生变化时,gn原生的action模板不能自动感知不到这种编译,无法重新编译。见例8
原生模板和编译系统提供的模板之间的对应关系:
| 编译系统提供的模板 | 原生模板 |
| :------------------ | -------------- |
| ohos_shared_library | shared_library |
| ohos_source_set | source_set |
| ohos_executable | executable |
| ohos_static_library | static_library |
| action_with_pydeps | action |
| ohos_group | group |
| 编译系统提供的模板 | 原生模板 |
|:------------------- | -------------- |
| ohos_shared_library | shared_library |
| ohos_source_set | source_set |
| ohos_executable | executable |
| ohos_static_library | static_library |
| action_with_pydeps | action |
| ohos_group | group |
### 使用python脚本
......@@ -288,7 +285,7 @@ action中的script推荐使用python脚本,不推荐使用shell脚本。相比
### rebase_path
- 仅在向action的参数列表中(args)调用rebase_path。
```
# 例10
template("foo") {
......@@ -310,7 +307,7 @@ action中的script推荐使用python脚本,不推荐使用shell脚本。相比
```
- 同一变量做两次rebase_path会出现意想不到的结果。
```
# 例11
template("foo") {
......@@ -337,11 +334,11 @@ action中的script推荐使用python脚本,不推荐使用shell脚本。相比
模块间数据分享是很常见的事情,比如A模块想要知道B模块的输出和deps。
- 同一BUILD.gn之间数据分享
同一BUILD.gn之间数据可以通过定义全局变量的方式来共享。
下面的例子中,模块a的输出是模块b的输入,可以通过定义全局变量的方式来共享给b
```
# 例12
_output_a = get_label_info(":a", "out_dir") + "/a.out"
......@@ -356,13 +353,13 @@ action中的script推荐使用python脚本,不推荐使用shell脚本。相比
```
- 不同BUILD.gn之间数据分享
不同BUILD.gn之间传递数据,最好的办法是将需要共享的数据保存成文件,然后不同模块之间通过文件来传递和共享数据。这种场景比较复杂,读者可以参照OpenHarmony的hap编译过程的write_meta_data。
### forward_variable_from
- 自定义模板需要首先将testonly传递(forward)进来。因为该模板的target有可能被testonly的目标依赖。
```
# 例13
# 自定义模板首先要传递testonly
......@@ -373,7 +370,7 @@ action中的script推荐使用python脚本,不推荐使用shell脚本。相比
```
- 不推荐使用*来forward变量,需要的变量应该**显式地,一个一个地**被forward进来。
```
# 例14
# Bad,使用*forward变量
......@@ -386,10 +383,10 @@ action中的script推荐使用python脚本,不推荐使用shell脚本。相比
template("bar") {
#
forward_variable_from(invoker, [
"testonly",
"deps",
...
])
"testonly",
"deps",
...
])
...
}
```
......@@ -495,15 +492,17 @@ set_source_assignment_filter([])
### 部件内依赖采用deps,跨部件依赖采用external_deps
- 部件在OpenHarmony上指能提供某个能力的一组模块。
- 在模块定义的时候可以声明part_name,用来表明当前模块属于哪个部件。
- 每个部件会声明其inner-kit,供其他部件调用。部件innerkit的声明见源码中的ohos.build。
- 每个部件会声明其inner-kit,供其他部件调用。部件innerkit的声明见源码中的bundle.json。
- 部件间依赖只能依赖innerkit,不能依赖非innerkit的模块。
- 如果a模块和b模块的part_name相同,那么a、b模块属于同一个部件,a,b模块之间的依赖关系可以用deps来声明。
- 如果a、b模块的part_name不同,那么a、b模块不属于同一个部件,a、b模块之间的依赖关系需要通过external_deps来声明,依赖方式为"部件名:模块名"的方式。见例19。
```
# 例19
shared_library("a") {
......@@ -512,14 +511,3 @@ set_source_assignment_filter([])
...
}
```
......@@ -7,7 +7,7 @@
基于Kconfig实现的可视化配置功能具有以下优点:
- 能直观且全面地展示软件的件选项。
- 能直观且全面地展示软件的件选项。
- 可靠性强,如Linux-kernel、buildroot等知名软件都采用Kconfig进行可视化配置。
### 基本概念
......
# 轻量和小型系统编译构建指导
## 概述
一个基于gn和ninja的构建系统,以支持OpenHarmony组件化开发为目标,提供以下基本功能:
- 支持按组件拼装产品并编译。
一个基于gn和ninja的构建系统,以支持OpenHarmony部件化开发为目标,提供以下基本功能:
- 独立构建芯片解决方案厂商源码
- 支持按部件拼装产品并编译
- 独立构建单个组件
- 独立构建芯片解决方案厂商源码
- 独立构建单个部件。
### 基本概念
在使用编译构建子系统前,应了解如下基本概念:
- 子系统
子系统是一个逻辑概念,它由一个或多个具体的组件组成。OpenHarmony整体遵从分层设计,从下向上依次为:内核层、系统服务层、框架层和应用层。系统功能按照“系统 &gt; 子系统 &gt; 组件”逐级展开,在多设备部署场景下,支持根据实际需求裁剪某些非必要的子系统或组件。
子系统是一个逻辑概念,它由一个或多个具体的部件组成。OpenHarmony整体遵从分层设计,从下向上依次为:内核层、系统服务层、框架层和应用层。系统功能按照“系统 &gt; 子系统 &gt; 部件”逐级展开,在多设备部署场景下,支持根据实际需求裁剪某些非必要的子系统或部件。
-
系统最小的可复用、可配置、可裁剪的功能单元。件具备目录独立可并行开发、可独立编译、可独立测试的特征。
-
系统最小的可复用、可配置、可裁剪的功能单元。件具备目录独立可并行开发、可独立编译、可独立测试的特征。
- gn
Generate ninja的缩写,用于产生ninja文件。
......@@ -30,18 +29,16 @@
- hb
OpenHarmony的命令行工具,用来执行编译命令。
### 目录结构
```
build/lite
├── components # 件描述文件
├── components # 件描述文件
├── figures # readme中的图片
├── hb # hb pip安装包源码
├── make_rootfs # 文件系统镜像制作脚本
├── config # 编译配置项
│ ├── component # 件相关的模板定义
│ ├── component # 件相关的模板定义
│ ├── kernel # 内核相关的编译配置
│ └── subsystem # 子系统编译配置
├── platform # ld脚本
......@@ -49,152 +46,162 @@ build/lite
└── toolchain # 编译工具链配置,包括:编译器路径、编译选项、链接选项等
```
### 构建流程
编译构建流程如下图所示,主要分设置和编译两步:
**图1** 编译构建流程
![zh-cn_image_0000001171796557](figures/zh-cn_image_0000001171796557.jpg)
1. hb set: 设置OpenHarmony源码目录和要编译的产品。
2. hb build: 编译产品、开发板或者组件。编译主要过程如下:
2. hb build: 编译产品、开发板或者部件。编译主要过程如下:
1. 读取编译配置:根据产品选择的开发板,读取开发板config.gni文件内容,主要包括编译工具链、编译链接命令和选项等。
2. 调用gn:调用gn gen命令,读取产品配置生成产品解决方案out目录和ninja文件。
3. 调用ninja:调用ninja -C out/board/product启动编译。
4. 系统镜像打包:将组件编译产物打包,设置文件属性和权限,制作文件系统镜像。
4. 系统镜像打包:将部件编译产物打包,设置文件属性和权限,制作文件系统镜像。
## 配置规则
为了实现芯片解决方案、产品解决方案与OpenHarmony是解耦的、可插拔的,件、芯片解决方案和产品解决方案的路径、目录树和配置需遵循一定的规则,具体如下:
为了实现芯片解决方案、产品解决方案与OpenHarmony是解耦的、可插拔的,件、芯片解决方案和产品解决方案的路径、目录树和配置需遵循一定的规则,具体如下:
### 部件
### 组件
部件源码路径命名规则为:**{领域}/{子系统}/{部件}**,部件目录树规则如下:
组件源码路径命名规则为:**{领域}/{子系统}/{组件}**,组件目录树规则如下:
> ![icon-caution.gif](public_sys-resources/icon-caution.gif) **注意:**
> 组件的名称、源码路径、功能简介、是否必选、编译目标、RAM、ROM、编译输出、已适配的内核、可配置的特性和依赖等属性定义在build/lite/components目录下对应子系统的json文件中,新增组件时需要在对应子系统json文件中添加相应的组件定义。产品所配置的组件必须在某个子系统中被定义过,否则会校验失败。
> 部件的名称、源码路径、功能简介、是否必选、编译目标、RAM、ROM、编译输出、已适配的内核、可配置的特性和依赖等属性定义在build/lite/components目录下对应子系统的json文件中,新增部件时需要在对应子系统json文件中添加相应的部件定义。产品所配置的部件必须在某个子系统中被定义过,否则会校验失败。
```
component
├── interfaces
│ ├── innerkits # 系统内接口,件间使用
│ ├── innerkits # 系统内接口,件间使用
│ └── kits # 应用接口,应用开发者使用
├── frameworks # framework实现
├── services # service实现
└── BUILD.gn # 件编译脚本
└── BUILD.gn # 件编译脚本
```
以泛sensor子系统的sensor服务组件为例,组件属性定义描述文件字段说明如下:
以泛sensor子系统的sensor服务部件为例,部件属性定义描述文件字段说明如下:
```
{
"name": "@ohos/sensor_lite", # HPM部件英文名称,格式"@组织/部件名称"
"description": "Sensor services", # 部件功能一句话描述
"version": "3.1", # 版本号,版本号与OpenHarmony版本号一致
"license": "MIT", # 部件License
"publishAs": "code-segment", # HPM包的发布方式,当前默认都为code_segment
"segment": {
"destPath": ""
}, # 发布类型为code_segment时为必填项,定义发布类型code_segment的代码还原路径(源码路径)
"dirs": {"base/sensors/sensor_lite"}, # HPM包的目录结构,字段必填内容可以留空
"scripts": {}, # HPM包定义需要执行的脚本,字段必填,值非必填
"licensePath": "COPYING",
"readmePath": {
"en": "README.rst"
},
"component": { # 部件属性
"name": "sensor_lite", # 部件名称
"subsystem": "", # 部件所属子系统
"syscap": [], # 部件为应用提供的系统能力
"features": [], # 部件对外的可配置特性列表,一般与build中的sub_component对应,可供产品配置
"adapted_system_type": [], # 轻量(mini)小型(small)和标准(standard),可以是多个
"rom": "92KB", # 部件ROM值
"ram": "~200KB", # 部件RAM估值
"deps": {
"components": [ # 部件依赖的其他部件
"samgr_lite",
"ipc_lite"
],
"third_party": [ # 部件依赖的三方开源软件
"bounds_checking_function"
]
}
"build": { # 编译相关配置
"sub_component": [
""//base/sensors/sensor_lite/services:sensor_service"", # 部件编译入口
], # 部件编译入口,模块在此处配置
"inner_kits": [], # 部件间接口
"test": [] # 部件测试用例编译入口
}
}
}
```
```
{
"components": [
{
"component": "sensor_lite", # 组件名称
"description": "Sensor services", # 组件一句话功能描述
"optional": "true", # 组件是否为最小系统必选
"dirs": [ # 组件源码路径
"base/sensors/sensor_lite"
],
"targets": [ # 组件编译入口
"//base/sensors/sensor_lite/services:sensor_service"
],
"rom": "92KB", # 组件ROM值
"ram": "~200KB", # 组件RAM估值
"output": [ "libsensor_frameworks.so" ], # 组件编译输出
"adapted_kernel": [ "liteos_a" ], # 组件已适配的内核
"features": [], # 组件可配置的特性
"deps": {
"components": [ # 组件依赖的其他组件
"samgr_lite",
"ipc_lite"
],
"third_party": [ # 组件依赖的三方开源软件
"bounds_checking_function"
]
}
}
]
}
```
部件BUILD.gn的编写建议如下:
组件BUILD.gn的编写建议如下:
- 编译目标名称与组件一致。
- 编译目标名称与部件一致。
- 组件对外可配置的特性变量需声明在该组件BUILD.gn中,特性变量命名规则:ohos_{subsystem}_{component}_{feature}。特性在组件描述中也需要同步定义,在产品配置文件config.json中按需配置。
- 部件对外可配置的特性变量需声明在该部件BUILD.gn中,特性变量命名规则:ohos_{subsystem}_{component}_{feature}。特性在部件描述中也需要同步定义,在产品配置文件config.json中按需配置。
- 宏定义规则:OHOS_{SUBSYSTEM}_{COMPONENT}_{FEATURE}
> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:**
> 组件的编译脚本语言为gn,gn的基本用法请见[gn快速入门](https://gn.googlesource.com/gn/+/master/docs/quick_start.md)。组件即为gn定义的编译目标,可以为静态库、动态库、可执行文件或group。
以图形的UI组件为例,foundation/graphic/ui/BUILD.gn文件如下:
> 部件的编译脚本语言为gn,gn的基本用法请见[gn快速入门](https://gn.googlesource.com/gn/+/master/docs/quick_start.md)。部件即为gn定义的编译目标,可以为静态库、动态库、可执行文件或group。
```
# 声明组件可配置的特性
declare_args() {
enable_ohos_graphic_ui_animator = false # 动效特性开关
ohos_ohos_graphic_ui_font = "vector" # 可配置的字体类型,vector或者bitmap
}
# 组件基础功能
shared_library("base") {
sources = [
......
]
include_dirs = [
......
]
}
# 仅在animator开启时编译
if(enable_ohos_graphic_ui_animator ) {
shared_library("animator") {
sources = [
......
]
include_dirs = [
以图形的UI部件为例,foundation/graphic/ui/BUILD.gn文件如下:
```
# 声明部件可配置的特性
declare_args() {
enable_ohos_graphic_ui_animator = false # 动效特性开关
ohos_ohos_graphic_ui_font = "vector" # 可配置的字体类型,vector或者bitmap
}
# 部件基础功能
shared_library("base") {
sources = [
......
]
include_dirs = [
......
]
}
# 仅在animator开启时编译
if(enable_ohos_graphic_ui_animator ) {
shared_library("animator") {
sources = [
......
]
include_dirs = [
......
]
deps = [ :base ]
}
}
......
# target名称建议与组件名称一致, 组件target类型可以是executable(bin文件),shared_library(动态库.so),static_library(静态库.a),group等等
executable("ui") {
deps = [
":base"
]
# animator特性由产品配置
if(enable_ohos_graphic_ui_animator ) {
deps += [
"animator"
]
}
}
```
]
deps = [ :base ]
}
}
......
# target名称建议与部件名称一致, 部件target类型可以是executable(bin文件),shared_library(动态库.so),static_library(静态库.a),group等等
executable("ui") {
deps = [
":base"
]
# animator特性由产品配置
if(enable_ohos_graphic_ui_animator ) {
deps += [
"animator"
]
}
}
```
### 芯片解决方案
- 芯片解决方案是指基于某款开发板的完整解决方案,包含驱动、设备侧接口适配、开发板sdk等。
- 芯片解决方案是一个特殊的组件,源码路径规则为:**device/{芯片解决方案厂商}/{开发板}**
- 芯片解决方案组件会随产品选择的开发板默认编译。
- 芯片解决方案是一个特殊的部件,源码路径规则为:**device/{开发板}/{芯片解决方案厂商}**
- 芯片解决方案部件会随产品选择的开发板默认编译。
芯片解决方案目录树规则如下:
```
device
└── company # 芯片解决方案厂商
└── board # 开发板名称
└── board # 芯片解决方案厂商
└── company # 开发板名称
├── BUILD.gn # 编译脚本
├── hals # OS南向接口适配
├── linux # 可选,linux内核版本
......@@ -203,10 +210,8 @@ device
└── config.gni # liteos_a版本编译配置
```
> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:**
> config.gni为开发板编译相关的配置,编译时会采用该配置文件中的参数编译所有OS组件,编译阶段系统全局可见。
> config.gni为开发板编译相关的配置,编译时会采用该配置文件中的参数编译所有OS部件,编译阶段系统全局可见。
config.gni的关键字段介绍如下:
......@@ -223,14 +228,12 @@ board_cxx_flags: 开发板配置的cpp文件编译选项。
board_ld_flags: 开发板配置的链接选项。
```
### 产品解决方案
产品解决方案为基于开发板的完整产品,主要包含产品对OS的适配、组件拼装配置、启动配置和文件系统配置等。产品解决方案的源码路径规则为:**vendor/{产品解决方案厂商}/{产品名称}**_。_产品解决方案也是一个特殊的组件。
产品解决方案为基于开发板的完整产品,主要包含产品对OS的适配、部件拼装配置、启动配置和文件系统配置等。产品解决方案的源码路径规则为:**vendor/{产品解决方案厂商}/{产品名称}**_。_产品解决方案也是一个特殊的部件。
产品解决方案的目录树规则如下:
```
vendor
└── company # 产品解决方案厂商
......@@ -245,28 +248,29 @@ vendor
└── ......
```
> ![icon-caution.gif](public_sys-resources/icon-caution.gif) **注意:**
> **新增产品须按如上的规则创建目录和文件,编译构建系统将按该规则扫描已配置的产品。**
关键的目录和文件详细介绍如下:
1. **vendor/company/product/init_configs/etc**
该文件夹中包含rcS脚本,Sxxx脚本和fstab脚本。init进程在启动系统服务之前执行这些脚本。执行的流程为“rcS-&gt;fstab-&gt;S00-xxx“。Sxxx脚本中的内容与开发板和产品需要有关,主要包括设备节点的创建、创建目录、扫描设备节点、修改文件权限等等。这些文件在产品编译的BUILD.gn中按需拷贝到产品out目录中,最终打包到rootfs镜像中。
2. **vendor/company/product/init_configs/init.cfg**
init进程启动服务的配置文件,当前支持解析的命令有:
- start: 启动某个服务
- mkdir: 创建文件夹
- chmod: 修改指定路径/文件的权限
- chown: 修改指定路径/文件的属组
- mount: 挂载命令
该文件中的各个字段的解释如下:
该文件中的各个字段的解释如下:
```
{
"jobs" : [{ # job数组,一个job对应一个命令集合。job的执行顺序:pre-init -> init -> post-init。
......@@ -308,44 +312,42 @@ vendor
```
3. **vendor/company/product/init_configs/hals**
解决方案厂商对OS的适配,需要实现的接口请见各个件的readme说明文档。
解决方案厂商对OS的适配,需要实现的接口请见各个件的readme说明文档。
4. **vendor/company/product/config.json**
config.json为编译构建的主入口,包含了开发板、OS件和内核等配置信息。
config.json为编译构建的主入口,包含了开发板、OS件和内核等配置信息。
以基于hispark_taurus开发板的ipcamera产品为例,配置文件如下:
```
{
"product_name": "ipcamera", # 产品名称
"version": "3.0", # config.json的版本号, 固定"3.0"
"type": "small", # 系统类型, 可选[mini, small, standard]
"ohos_version": "OpenHarmony 1.0", # 选择的OS版本
"device_company": "hisilicon", # 芯片厂商
"board": "hispark_taurus", # 开发板名称
"kernel_type": "liteos_a", # 选择的内核类型
"kernel_version": "3.0.0", # 选择的内核版本
"subsystems": [
{
"subsystem": "aafwk", # 选择的子系统
"components": [
{ "component": "ability", "features":[ "enable_ohos_appexecfwk_feature_ability = true" ] } # 选择的组件和组件特性配置
]
},
{
......
}
......
更多子系统和组
}
}
```
"product_name": "ipcamera", # 产品名称
"version": "3.0", # config.json的版本号, 固定"3.0"
"type": "small", # 系统类型, 可选[mini, small, standard]
"ohos_version": "OpenHarmony 1.0", # 选择的OS版本
"device_company": "hisilicon", # 芯片厂商
"board": "hispark_taurus", # 开发板名称
"kernel_type": "liteos_a", # 选择的内核类型
"kernel_version": "3.0.0", # 选择的内核版本
"subsystems": [
{
"subsystem": "aafwk", # 选择的子系统
"components": [
{ "component": "ability", "features":[ "enable_ohos_appexecfwk_feature_ability = true" ] } # 选择的部件和部件特性配置
]
},
{
......
}
......
更多子系统和部
}
}
```
5. **vendor/company/product/fs.yml**
该文件用于配置文件系统镜像制作过程,将编译产物打包成文件系统镜像,比如用户态根文件系统rootfs.img和可读写的userfs.img。它由多个列表组成,每个列表对应一个文件系统。字段说明如下:
```
fs_dir_name: 必填,声明文件系统文件名, 如rootfs、userfs
fs_dirs: 选填,配置out下文件目录与文件系统文件目录的映射关系,每个文件目录对应一个列表
......@@ -358,30 +360,29 @@ vendor
file_dir: 必填,文件系统下具体文件路径
file_mode: 必填,文件权限声明
fs_symlink: 选填,配置文件系统软连接
fs_make_cmd: 必填,配置需要制作文件系统脚本,OS提供的脚本在build/lite/make_rootfs下, 支持linux,liteos内核和ext4、jffs2、vfat格式。也支持芯片解决方案厂商自定义。
fs_make_cmd: 必填,配置需要制作文件系统脚本,OS提供的脚本在build/lite/make_rootfs下, 支持linux,liteos内核和ext4、jffs2、vfat格式。也支持芯片解决方案厂商自定义。
fs_attr: 选填,根据配置项动态调整文件系统
```
其中fs_symlink、fs_make_cmd字段支持以下变量:
其中fs_symlink、fs_make_cmd字段支持以下变量:
- ${root_path}
代码根目录,对应gn的${ohos_root_path}
代码根目录,对应gn的${ohos_root_path}
- ${out_path}
产品out目录,对应gn的${root_out_dir}
- ${fs_dir}
文件系统目录,由以下变量拼接而成
- ${root_path}
- ${fs_dir_name}
> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:**
> fs.yml是可选的,对于没有文件系统的设备可不配置。
产品out目录,对应gn的${root_out_dir}
- ${fs_dir}
文件系统目录,由以下变量拼接而成
- ${root_path}
- ${fs_dir_name}
> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:**
> fs.yml是可选的,对于没有文件系统的设备可不配置。
6. **vendor/company/product/BUILD.gn**
产品编译的入口,主要用于编译解决方案厂商源码和拷贝启动配置文件。如果某个产品被选择为要编译的产品,那么对应产品目录下的BUILD.gn会默认编译。一个典型的产品编译BUILD.gn应该如下:
```
group("product") { # target名称需与product名称即三级目录名称一致
deps = []
......@@ -392,13 +393,11 @@ vendor
}
```
## 使用指导
### 前提条件
开发环境需安装gn、ninja构建工具、python 3.7.4及以上和hb。安装方法请见[搭建基础环境](../quick-start/quickstart-lite-env-setup.md)
开发环境需安装gn、ninja构建工具、python 3.9.2及以上和hb。安装方法请见[搭建基础环境](../quick-start/quickstart-lite-env-setup.md)。
### hb工具使用说明
......@@ -427,7 +426,6 @@ optional arguments:
查看当前设置信息
```
hb env
[OHOS INFO] root path: xxx
......@@ -442,58 +440,63 @@ hb env
```
hb build -h
usage: hb build [-h] [-b BUILD_TYPE] [-c COMPILER] [-t [TEST [TEST ...]]]
[--dmverity] [--tee] [-p PRODUCT] [-f] [-n]
[-T [TARGET [TARGET ...]]] [-v] [-shs] [--patch]
usage: hb build [-h] [-b BUILD_TYPE] [-c COMPILER] [-t [TEST [TEST ...]]] [-cpu TARGET_CPU] [--dmverity] [--tee]
[-p PRODUCT] [-f] [-n] [-T [TARGET [TARGET ...]]] [-v] [-shs] [--patch] [--compact-mode]
[--gn-args GN_ARGS] [--keep-ninja-going] [--build-only-gn] [--log-level LOG_LEVEL] [--fast-rebuild]
[--device-type DEVICE_TYPE] [--build-variant BUILD_VARIANT]
[component [component ...]]
positional arguments:
component name of the component
component name of the component, mini/small only
optional arguments:
-h, --help show this help message and exit
-b BUILD_TYPE, --build_type BUILD_TYPE
release or debug version
release or debug version, mini/small only
-c COMPILER, --compiler COMPILER
specify compiler
specify compiler, mini/small only
-t [TEST [TEST ...]], --test [TEST [TEST ...]]
compile test suit
--dmverity Enable dmverity
-cpu TARGET_CPU, --target-cpu TARGET_CPU
select cpu
--dmverity enable dmverity
--tee Enable tee
-p PRODUCT, --product PRODUCT
build a specified product with
{product_name}@{company}, eg: camera@example
build a specified product with {product_name}@{company}
-f, --full full code compilation
-n, --ndk compile ndk
-T [TARGET [TARGET ...]], --target [TARGET [TARGET ...]]
Compile single target
compile single target
-v, --verbose show all command lines while building
-shs, --sign_haps_by_server
sign haps by server
--patch apply product patch before compiling
--dmverity Enable dmverity
-p PRODUCT, --product PRODUCT
build a specified product with
{product_name}@{company}, eg: ipcamera@hisilcon
-f, --full full code compilation
-T [TARGET [TARGET ...]], --target [TARGET [TARGET ...]]
Compile single target
--compact-mode compatible with standard build system set to false if we use build.sh as build entrance
--gn-args GN_ARGS specifies gn build arguments, eg: --gn-args="foo="bar" enable=true blah=7"
--keep-ninja-going keeps ninja going until 1000000 jobs fail
--build-only-gn only do gn parse, donot run ninja
--log-level LOG_LEVEL
specifies the log level during compilationyou can select three levels: debug, info and error
--fast-rebuild it will skip prepare, preloader, gn_gen steps so we can enable it only when there is no change
for gn related script
--device-type DEVICE_TYPE
specifies device type
--build-variant BUILD_VARIANT
specifies device operating mode
```
- hb build后无参数,会按照设置好的代码路径、产品进行编译,编译选项使用与之前保持一致。-f 选项将删除当前产品所有编译产品,等同于hb clean + hb build.
- hb build {component_name}:基于设置好的产品对应的单板、内核,单独编译件(e.g.:hb build kv_store)。
- hb build {component_name}:基于设置好的产品对应的单板、内核,单独编译件(e.g.:hb build kv_store)。
- hb build -p ipcamera\@hisilicon:免set编译产品,该命令可以跳过set步骤,直接编译产品。
- 在device/device_company/board下单独执行hb build会进入内核选择界面,选择完成后会根据当前路径的单板、选择的内核编译出仅包含内核、驱动的镜像。
- 在device/board/device_company下单独执行hb build会进入内核选择界面,选择完成后会根据当前路径的单板、选择的内核编译出仅包含内核、驱动的镜像。
**hb clean**
清除out目录对应产品的编译产物,仅保留args.gn、build.log。清除指定路径可输入路径参数:hb clean out/board/product,默认将清除当前hb set的产品对应out路径。
```
hb clean
usage: hb clean [-h] [out_path]
......@@ -505,16 +508,14 @@ optional arguments:
-h, --help show this help message and exit
```
### 新增部件
### 新增组件
本小节介绍如何新增一个组件,首先确定组件归属的子系统和组件名称,然后按如下步骤新增:
1. 源码开发完成后,添加组件编译脚本。
以编译组件hello_world可执行文件为例,applications/sample/hello_world/BUILD.gn可以写为:
本小节介绍如何新增一个部件,首先确定部件归属的子系统和部件名称,然后按如下步骤新增:
1. 源码开发完成后,添加部件编译脚本。
以编译部件hello_world可执行文件为例,applications/sample/hello_world/BUILD.gn可以写为:
```
executable("hello_world") {
include_dirs = [
......@@ -528,28 +529,26 @@ optional arguments:
如上编译脚本,可编译出一个可在OpenHarmony上运行的名为hello_world的可执行文件。
单独编译该组件,hb set任意选择一款产品,然后使用-T选项单独编译组件:
单独编译该部件,hb set任意选择一款产品,然后使用-T选项单独编译部件:
```
hb build -f -T //applications/sample/hello_world
```
组件在开发板上功能验证完成后,可按步骤2-4将组件配置到产品中。
2. 添加组件描述。
组件描述位于build/lite/components下,新增的组件需加入对应子系统的json文件中。一个组件描述必选的字段有:
- component:组件名称。
- description:组件的一句话功能描述。
- optional:组件是否为系统可选。
- dirs:组件源码路径。
- targets:组件编译入口。
以将hello_world组件加入应用子系统为例,在applications.json中添加hello_world对象:
部件在开发板上功能验证完成后,可按步骤2-4将部件配置到产品中。
2. 添加部件描述。
部件描述位于build/lite/components下,新增的部件需加入对应子系统的json文件中。一个部件描述必选的字段有:
- component:部件名称。
- description:部件的一句话功能描述。
- optional:部件是否为系统可选。
- dirs:部件源码路径。
- targets:部件编译入口。
以将hello_world部件加入应用子系统为例,在applications.json中添加hello_world对象:
```
{
"components": [
......@@ -569,11 +568,10 @@ optional arguments:
}
```
3. 将组件配置到产品。
产品的配置文件config.json位于vendor/company/product/下,产品配置文件需包含产品名称、OpenHarmony版本号、device厂商、开发板、内核类型、内核版本号,以及配置的子系统和组件。以将hello_world组件加入产品配置文件my_product.json中为例,加入hello_world对象:
3. 将部件配置到产品。
产品的配置文件config.json位于vendor/company/product/下,产品配置文件需包含产品名称、OpenHarmony版本号、device厂商、开发板、内核类型、内核版本号,以及配置的子系统和部件。以将hello_world部件加入产品配置文件my_product.json中为例,加入hello_world对象:
```
{
"product_name": "hello_world_test",
......@@ -595,11 +593,11 @@ optional arguments:
```
4. 编译产品。
1. 代码根目录输入hb set选择对应产品。
2. 执行hb build。
### 新增芯片解决方案
编译构建支持添加新的芯片解决方案厂商,具体步骤如下:
......@@ -607,14 +605,13 @@ optional arguments:
1. 创建芯片解决方案目录。
按照[芯片解决方案配置规则](#配置规则)创建目录,以芯片厂商realtek的“rtl8720“开发板为例, 在代码根目录执行:
```
mkdir -p device/realtek/rtl8720
mkdir -p device/board/realtek/rtl8720
```
2. 创建内核适配目录,并编写开发板编译配置config.gni文件。
以realtek的“rtl8720“开发板的liteos_a适配为例,device/realtek/rtl8720/liteo_a/config.gni的内容如下:
以realtek的“rtl8720“开发板的liteos_a适配为例,device/board/realtek/rtl8720/liteo_a/config.gni的内容如下:
```
# Kernel type, e.g. "linux", "liteos_a", "liteos_m".
kernel_type = "liteos_a"
......@@ -651,8 +648,8 @@ optional arguments:
```
3. 编写编译脚本。
在开发板目录下创建BUILD.gn,target名称应与开发板名称一致。以realtek的rtl8720开发板为例,device/realtek/rtl8720/BUILD.gn内容可以是:
在开发板目录下创建BUILD.gn,target名称应与开发板名称一致。以realtek的rtl8720开发板为例,device/board/realtek/rtl8720/BUILD.gn内容可以是:
```
group("rtl8720") { # target类型也可以shared_library, static_library, executable
# 具体内容
......@@ -663,22 +660,20 @@ optional arguments:
4. 编译芯片解决方案。
在开发板目录下执行hb build,即可启动芯片解决方案的编译。
### 新增产品解决方案
编译构建支持芯片解决方案和件的灵活拼装,形成定制化的产品解决方案。具体步骤如下:
编译构建支持芯片解决方案和件的灵活拼装,形成定制化的产品解决方案。具体步骤如下:
1. 创建产品目录
按照[产品解决方案配置规则](#配置规则)创建产品目录,以基于“rtl8720“开发板的wifiiot模组为例,在代码根目录执行:
```
mkdir -p vendor/my_company/wifiiot
```
2. 拼装产品
在新建的产品目录下新建config.json文件,以步骤1中的wifiiot为例,vendor/my_company/wifiiot/config.json可以是:
```
{
"product_name": "wifiiot", # 产品名称
......@@ -693,18 +688,18 @@ optional arguments:
{
"subsystem": "kernel", # 选择的子系统
"components": [
{ "component": "liteos_m", "features":[] } # 选择的组件和组件特性
{ "component": "liteos_m", "features":[] } # 选择的部件和部件特性
]
},
...
{
更多子系统和
更多子系统和
}
]
}
```
注意:编译构建系统编译前会对device_company,board,kernel_type,kernel_version、subsystem、component字段进行有效性检查,其中device_company,board,kernel_type,kernel_version应与已知的芯片解决方案匹配,subsystem、component应与build/lite/components下的件描述匹配。
注意:编译构建系统编译前会对device_company,board,kernel_type,kernel_version、subsystem、component字段进行有效性检查,其中device_company,board,kernel_type,kernel_version应与已知的芯片解决方案匹配,subsystem、component应与build/lite/components下的件描述匹配。
3. 适配OS接口
在产品目录下创建hals目录,并将产品解决方案对OS适配的源码和编译脚本放入该目录下。
......@@ -717,7 +712,7 @@ optional arguments:
6. 配置文件系统镜像(可选,仅支持文件系统的开发板需要)
在产品目录下创建fs.yml文件。fs.yml需按产品实际情况配置,一个典型的fs.yml文件如下:
```
-
fs_dir_name: rootfs # 镜像的名称
......@@ -819,9 +814,9 @@ optional arguments:
```
7. 配置产品Patch(可选,视产品涉及件是否需要打补丁而定)
7. 配置产品Patch(可选,视产品涉及件是否需要打补丁而定)
在产品目录下创建patch.yml文件。patch.yml需按产品实际情况配置,一个典型的patch.yml文件如下:
```
# 需要打patch的路径
foundation/communication/dsoftbus:
......@@ -834,16 +829,16 @@ optional arguments:
- third_party/wpa_supplicant/3.patch
...
```
配置完成后,编译时增加--patch参数,即可在产品编译前将配置的Patch文件打到对应目录中,再进行编译:
```
hb build -f --patch
```
8. 编写编译脚本
在产品目录下创建BUILD.gn文件,按产品实际情况编写脚本。以步骤1中的wifiiot为例,BUILD.gn示例如下:
```
group("wifiiot") { # target名称与产品名一致
deps = []
......@@ -859,10 +854,8 @@ optional arguments:
9. 编译产品。
在代码根目录执行hb set按提示选择新增的产品,然后执行hb build即可启动编译。
## 常见问题
### 编译构建过程中,提示“usr/sbin/ninja: invalid option -- w”
- **现象描述:**
......@@ -874,7 +867,6 @@ optional arguments:
- **解决办法:**
卸载环境中ninja和gn,按照[获取工具](../get-code/gettools-ide.md)。
### 编译构建过程中,提示“/usr/bin/ld: cannot find -lncurses”
- **现象描述:**
......@@ -889,7 +881,6 @@ optional arguments:
sudo apt-get install lib32ncurses5-dev
```
### 编译构建过程中,提示“line 77: mcopy: command not found”
- **现象描述:**
......@@ -904,7 +895,6 @@ optional arguments:
​sudo apt-get install dosfstools mtools
```
### 编译构建过程中,提示“riscv32-unknown-elf-gcc: error trying to exec 'cc1': execvp: No such file or directory”
- **现象描述:**
......@@ -915,14 +905,13 @@ optional arguments:
- ​**解决办法:**
查询gcc_riscv32所在目录。
```
which riscv32-unknown-elf-gcc
```
使用chmod命令修改目录权限为755。
### 编译构建过程中,提示“No module named 'Crypto'”
- **现象描述:**
......@@ -932,17 +921,18 @@ optional arguments:
python3未安装Crypto。
- **解决办法:**
1. 查询Python版本号。
```
python3 --version
```
2. 需使用python3.7以上版本,然后安装pycryptodome。
```
sudo pip3 install pycryptodome
```
```
python3 --version
```
2. 需使用python3.9.2以上版本,然后安装pycryptodome。
```
sudo pip3 install pycryptodome
```
### 编译构建过程中,提示“xx.sh : xx unexpected operator”
......@@ -957,4 +947,4 @@ optional arguments:
```
sudo rm -rf /bin/sh
sudo ln -s /bin/bash /bin/sh
```
```
\ No newline at end of file
# 标准系统编译构建指导
## 概述
编译构建子系统提供了一个基于gn和ninja的编译构建框架。主要提供以下功能:
- 构建不同芯片平台的产品。如:hispark_taurus_standard平台。
- 根据产品配置,按照组件组装并打包产品特性的能力。
- 根据产品配置,按照部件组装并打包产品特性的能力。
### 基本概念
在了解编译构建子系统的能力前,应了解如下基本概念:
- 平台
开发板和内核的组合,不同平台支持的子系统和件不同。
开发板和内核的组合,不同平台支持的子系统和件不同。
- 子系统
OpenHarmony整体遵从分层设计,从下向上依次为:内核层、系统服务层、框架层和应用层。系统功能按照“系统 &gt; 子系统 &gt; 组件”逐级展开,在多设备部署场景下,支持根据实际需求裁剪某些非必要的子系统或组件。子系统是一个逻辑概念,它具体由对应的组件构成。
OpenHarmony整体遵从分层设计,从下向上依次为:内核层、系统服务层、框架层和应用层。系统功能按照“系统 &gt; 子系统 &gt; 部件”逐级展开,在多设备部署场景下,支持根据实际需求裁剪某些非必要的子系统或部件。子系统是一个逻辑概念,它具体由对应的部件构成。
-
-
对子系统的进一步拆分,可复用的软件单元,它包含源码、配置文件、资源文件和编译脚本;能独立构建,以二进制方式集成,具备独立验证能力的二进制单元。
- gn
......@@ -29,10 +27,9 @@
- ninja
ninja是一个专注于速度的小型构建系统。
### 运作机制
OpenHarmony的编译构建流程主要包括编译命令行解析,调用gn,执行ninja:
OpenHarmony的编译构建流程主要包括编译命令行解析,调用gn,执行ninja:
- 命令行解析:解析待编译的产品名称,加载相关配置。
......@@ -40,7 +37,6 @@ OpenHarmony的编译构建流程主要包括编译命令行解析,调用gn,
- 执行ninja:启动编译并生成对应的产品版本。
### 约束与限制
- 需按照[源码获取](../get-code/sourcecode-acquire.md)指导下载全量源码(采用方式三获取)。
......@@ -49,72 +45,131 @@ OpenHarmony的编译构建流程主要包括编译命令行解析,调用gn,
- 安装编译所需的程序包。
安装命令:
```
sudo apt-get install binutils git-core gnupg flex bison gperf build-essential zip curl zlib1g-dev gcc-multilib g++-multilib libc6-dev-i386 lib32ncurses5-dev x11proto-core-dev libx11-dev lib32z-dev ccache libgl1-mesa-dev libxml2-utils xsltproc unzip m4
# 推荐使用脚本,在家目录执行
# ./build/build_scripts/env_setup.sh
# 不要用root执行,会将环境变量加到root。如果你的sheel不是bash或者zsh,执行完还需要你手动配置以下内容到你的环境变量中,cd ~到你用户家目录查看隐藏文件能显示你的用户环境变量文件。
# export PATH=/home/tools/llvm/bin:$PATH
# export PATH=/home/tools/hc-gen:$PATH
# export PATH=/home/tools/gcc_riscv32/bin:$PATH
# export PATH=/home/tools/ninja:$PATH
# export PATH=/home/tools/node-v12.20.0-linux-x64/bin:$PATH
# export PATH=/home/tools/gn:$PATH
# export PATH=/root/.local/bin:$PATH
# 如果不用脚本执行,则需要安装以下内容
apt-get update -y
apt-get install -y apt-utils binutils bison flex bc build-essential make mtd-utils gcc-arm-linux-gnueabi u-boot-tools python3.9.2 python3-pip git zip unzip curl wget gcc g++ ruby dosfstools mtools default-jre default-jdk scons python3-distutils perl openssl libssl-dev cpio git-lfs m4 ccache zlib1g-dev tar rsync liblz4-tool genext2fs binutils-dev device-tree-compiler e2fsprogs git-core gnupg gnutls-bin gperf lib32ncurses5-dev libffi-dev zlib* libelf-dev libx11-dev libgl1-mesa-dev lib32z1-dev xsltproc x11proto-core-dev libc6-dev-i386 libxml2-dev lib32z-dev libdwarf-dev
apt-get install -y grsync xxd libglib2.0-dev libpixman-1-dev kmod jfsutils reiserfsprogs xfsprogs squashfs-tools pcmciautils quota ppp libtinfo-dev libtinfo5 libncurses5 libncurses5-dev libncursesw5 libstdc++6 python2.7 gcc-arm-none-eabi vim ssh locales doxygen
# python需要安装以下模块
chmod +x /usr/bin/repo
pip3 install --trusted-host https://repo.huaweicloud.com -i https://repo.huaweicloud.com/repository/pypi/simple requests setuptools pymongo kconfiglib pycryptodome ecdsa ohos-build pyyaml prompt_toolkit==1.0.14 redis json2html yagmail python-jenkins
pip3 install esdk-obs-python --trusted-host pypi.org
pip3 install six --upgrade --ignore-installed six
#还需要安装llvm,hc-gen,gcc_riscv32,ninja,node-v14.15.4-linux-x64,gn并将上述shell环境非bash或者zsh的配置内容导入到你用户的环境变量中
```
## 编译构建使用指导
## 编译构建使用指导
### 目录结构
```
/build # 编译构建主目录
├── config # 编译相关的配置项
├── __pycache__ # ----------------------
├── build_scripts/ # 编译相关的python脚本
├── common/ # ----------------------
├── config/ # 编译相关的配置项
├── core
│ └── gn # 编译入口BUILD.gn配置
├── loader # 各个组件配置加载、模板生成
├── ohos # OpenHarmony编译打包流程配置
│ ├── kits # kits编译打包模板和处理流程
│ ├── ndk # ndk模板和处理流程
│ ├── notice # notice模板和处理流程
│ ├── packages # 版本打包模板和处理流程
│ ├── sa_profile # sa模板和处理流程
│ ├── sdk # sdk模板和处理流程,包括sdk中包含的模块配置
│ └── testfwk # 测试相关的处理
├── scripts # 编译相关的python脚本
├── templates # c/c++编译模板定义
└── toolchain # 编译工具链配置
```
│ ├── gn/ # 编译入口BUILD.gn配置
└── build_scripts/ # ----------------------
├── docs # ----------------------
gn_helpers.py* # ----------------------
lite/ # hb和preloader入口
misc/
├── ohos # OpenHarmony编译打包流程配置
│ ├── kits # kits编译打包模板和处理流程
│ ├── ndk # ndk模板和处理流程
│ ├── notice # notice模板和处理流程
│ ├── packages # 版本打包模板和处理流程
│ ├── sa_profile # sa模板和处理流程
│ ├── sdk # sdk模板和处理流程,包括sdk中包含的模块配置
│ └── testfwk # 测试相关的处理
├── ohos.gni* # 汇总了常用的gni文件,方便各个模块一次性import
├── ohos_system.prop # ----------------------
├── ohos_var.gni* # ----------------------
├── prebuilts_download.sh* # ----------------------
├── print_python_deps.py* # ----------------------
├── scripts/ # ----------------------
├── subsystem_config.json # ----------------------
├── subsystem_config_example.json # ----------------------
├── templates/ # c/c++编译模板定义
├── test.gni* # ----------------------
├── toolchain # 编译工具链配置
├── tools # 常用工具
├── version.gni # ----------------------
├── zip.py* # ----------------------
```
### 编译命令
- 代码根目录下执行全量版本的编译命令:
```
./build.sh --product-name {product_name}
```
{product_name}为当前版本支持的平台。比如:hispark_taurus_standard等。
编译完成后,结果镜像保存在 out/{device_name}/packages/phone/images/ 目录下。
- 编译命令支持选项:
```
--product-name # 必须 编译的产品名称,如:hispark_taurus_standard
--build-target # 可选 指定编译目标,可以指定多个
--gn-args # 可选 gn参数,支持指定多个
--ccache # 可选 编译使用ccache,需要本地安装ccache
- 编译命令支持选项:./build.sh -h
```
-h, --help # 显示帮助信息并退出
--source-root-dir=SOURCE_ROOT_DIR # 指定路径
--product-name=PRODUCT_NAME # 指定产品名
--device-name=DEVICE_NAME # 指定装置名称
--target-cpu=TARGET_CPU # 指定cpu
--target-os=TARGET_OS # 指定操作系统
-T BUILD_TARGET, --build-target=BUILD_TARGET # 指定编译目标,可以指定多个
--gn-args=GN_ARGS # gn参数,支持指定多个
--ninja-args=NINJA_ARGS # ninja参数,支持指定多个
-v, --verbose # 生成时显示所有命令行
--keep-ninja-going # 让ninja持续到1000000个工作失败
--sparse-image
--jobs=JOBS
--export-para=EXPORT_PARA
--build-only-gn # 只做gn解析,不运行ninja
--ccache # 可选 编译使用ccache,需要本地安装ccache
--fast-rebuild # 快速重建,default=False
--log-level=LOG_LEVEL # 指定编译期间的日志级别','三个级别可选:debug, info and error,default='info'
--device-type=DEVICE_TYPE # 指定设备类型,default='default'
--build-variant=BUILD_VARIANT # 指定设备操作模式,default='user'
```
### 开发步骤
1. 添加组件。
本节以添加一个自定义的组件为例,描述如何编译组件,编译库、编译可执行文件等。
示例组件partA由feature1、feature2和feature3组成,feature1的编译目标为一个动态库,feature2的目标为一个可执行程序,feature3的目标为一个etc配置文件。
示例组件partA的配置需要添加到一个子系统中,本次示例将添加到subsystem_examples子系统中(subsystem_examples子系统定义在test/examples/目录)。
1. 添加部件。
本节以添加一个自定义的部件为例,描述如何编译部件,编译库、编译可执行文件等。
示例部件partA由feature1、feature2和feature3组成,feature1的编译目标为一个动态库,feature2的目标为一个可执行程序,feature3的目标为一个etc配置文件。
示例部件partA的配置需要添加到一个子系统中,本次示例将添加到subsystem_examples子系统中(subsystem_examples子系统定义在test/examples/目录)。
示例部件partA的完整目录结构如下:
示例组件partA的完整目录结构如下:
```
test/examples/partA
├── feature1
│ ├── BUILD.gn
......@@ -132,15 +187,17 @@ OpenHarmony的编译构建流程主要包括编译命令行解析,调用gn,
├── BUILD.gn
└── src
└── config.conf
```
示例1:编写动态库gn脚本test/examples/partA/feature1/BUILD.gn,示例如下:
示例1:编写动态库gn脚本test/examples/partA/feature1/BUILD.gn,示例如下:
```
config("helloworld_lib_config") {
include_dirs = [ "include" ]
}
ohos_shared_library("helloworld_lib") {
sources = [
"include/helloworld1.h",
......@@ -149,188 +206,220 @@ OpenHarmony的编译构建流程主要包括编译命令行解析,调用gn,
public_configs = [ ":helloworld_lib_config" ]
part_name = "partA"
}
```
示例2:编写可执行文件gn脚本test/examples/partA/feature2/BUILD.gn,示例如下:
```
ohos_executable("helloworld_bin") {
sources = [
"src/helloworld2.cpp"
]
include_dirs = [ "include" ]
deps = [ # 依赖件内模块
deps = [ # 依赖件内模块
"../feature1:helloworld_lib"
]
external_deps = [ "partB:module1" ] # (可选)如果有跨组件的依赖,格式为“组件名:模块名”
external_deps = [ "partB:module1" ] # (可选)如果有跨部件的依赖,格式为“部件名:模块名”
install_enable = true # 可执行程序缺省不安装,需要安装时需要指定
part_name = "partA"
}
```
示例3:编写etc模块gn脚本test/examples/partA/feature3/BUILD.gn,示例如下:
示例3:编写etc模块gn脚本test/examples/partA/feature3/BUILD.gn,示例如下:
```
ohos_prebuilt_etc("feature3_etc") {
source = "src/config.conf"
relative_install_dir = "init" #可选,模块安装相对路径,相对于默认安装路径;默认在/system/etc目录
part_name = "partA"
}
```
示例4:在子系统的ohos.build中添加组件配置:test/examples/ohos.build。每个子系统有一个ohos.build配置文件,在子系统的根目录下。示例如下:
```
"partA": {
"module_list": [
"//test/examples/partA/feature1:helloworld_lib",
"//test/examples/partA/feature2:helloworld_bin",
"//test/examples/partA/feature3:feature3_etc",
],
"inner_kits": [
],
"system_kits": [
],
"test_list": [
示例4:在部件的bundle.json中添加模块配置:test/examples/bundle.json。每个部件都有一个bundle.json配置文件,在部件的根目录下。示例如下:
]
}
```
{
"name": "@ohos/<component_name>", # HPM部件英文名称,格式"@组织/部件名称"
"description": "xxxxxxxxxxxxxxxxxxx", # 部件功能一句话描述
"version": "3.1", # 版本号,版本号与OpenHarmony版本号一致
"license": "MIT", # 部件License
"publishAs": "code-segment", # HPM包的发布方式,当前默认都为code_segment
"segment": {
"destPath": ""
}, # 发布类型为code_segment时为必填项,定义发布类型code_segment的代码还原路径(源码路径)
"dirs": {}, # HPM包的目录结构,字段必填内容可以留空
"scripts": {}, # HPM包定义需要执行的脚本,字段必填,值非必填
"licensePath": "COPYING", # 指定该模块的版权申明路径
"readmePath": {
"en": "README.rst"
}, # 该模块的reademe.opensource的路径
"component": { # 部件属性
"name": "<component_name>", # 部件名称
"subsystem": "", # 部件所属子系统
"syscap": [], # 部件为应用提供的系统能力
"features": [], # 部件对外的可配置特性列表,一般与build中的sub_component对应,可供产品配置
"adapted_system_type": [], # 轻量(mini)小型(small)和标准(standard),可以是多个
"rom": "xxxKB", # ROM基线,没有基线写当前值
"ram": "xxxKB", # RAM基线,没有基线写当前值
"deps": {
"components": [], # 部件依赖的其他部件
"third_party": [] # 部件依赖的三方开源软件
},
"build": { # 编译相关配置
"sub_component": [], # 部件编译入口,模块在此处配置
"inner_kits": [], # 部件间接口
"test": [] # 部件测试用例编译入口
}
}
}
```
一个组件包含module_list、inner_kits、system_kits、test_list四个部分的声明,其中:
- module_list:组件所包含的模块列表;
- inner_kits:组件提供给其它组件调用的接口,其他组件的模块可以在external_deps中添加依赖的模块;
2. 将部件添加到产品配置中。
在产品的配置中添加部件,产品对应的配置文件://vendor/{product_company}/{product-name}/config.json。
- system_kits:组件提供给开发者开发应用的接口;
- test_list:组件中对应模块的测试用例;
2. 将组件添加到产品配置中。
在产品的配置中添加组件,产品对应的配置文件://vendor/{product_company}/{product-name}/config.json。
在产品配置文件中添加 "subsystem_examples:partA",表示该产品中会编译并打包partA到版本中。
3. 编译。
以编译hispark_taurus_standard为例,编译命令如下:
以编译hispark_taurus_standard为例,编译命令如下:
```
./build.sh --product-name hispark_taurus_standard --ccache
```
4. 编译输出。
编译所生成的文件都归档在out/hispark_taurus/目录下,结果镜像输出在 out/hispark_taurus/packages/phone/images/ 目录下。
## 常见问题
### 如何将一个模块编译并打包到版本中?
- 模块要指定part_name,指定它归属的部件,一个模块只能属于一个部件;
- 部件的模块,要在部件配置的module_list中,或者可以被module_list中的模块依赖到;
- 部件的模块,要在部件配置的component.build.sub_component中,或者可以被component.build.sub_component中的模块依赖到;
- 部件要加到对应产品的部件列表中。
### 关于deps、external_deps的使用
在添加一个模块的时候,需要在BUILD.gn中声明它的依赖,为了便于后续处理部件间依赖关系,我们将依赖分为两种——部件内依赖deps和部件间依赖external_deps。
**依赖分类:**
部件内依赖: 现有模块module1属于部件part1,要添加一个属于部件part1的模块module2,module2依赖于module1,这种情况就属于部件内依赖。
部件间依赖: 现有模块module1属于部件part1,要添加一个模块module2,module2依赖于module1,module2属于部件part2。模块module2与模块module1分属于两个不同的部件,这种情况就属于部件间依赖。
### 依赖分类:
部件内依赖使用deps,部件间依赖使用external_deps
- 1.部件内依赖: 现有模块module1属于部件part1,要添加一个属于部件part1的模块module2,module2依赖于module1,这种情况就属于部件内依赖
**示例:**
- 2.部件间依赖: 现有模块module1属于部件part1,要添加一个模块module2,module2依赖于module1,module2属于部件part2。模块module2与模块module1分属于两个不同的部件,这种情况就属于部件间依赖。
部件内依赖示例:
- ##### 部件内依赖示例:
```
import("//build/ohos.gni")
ohos_shared_library("module1") {
……
part_name = "part1" # 必选,所属部件名称
}
```
```
import("//build/ohos.gni")
ohos_shared_library("module1") {
……
part_name = "part1" # 必选,所属部件名称
……
}
```
```
import("//build/ohos.gni")
ohos_shared_library("module2") {
……
deps = [
"module1的gn target",
……
] # 部件内模块依赖
part_name = "part1" # 必选,所属部件名称
}
```
```
import("//build/ohos.gni")
ohos_shared_library("module2") {
……
deps = [
"module1的gn target",
……
] # 部件内模块依赖
part_name = "part1" # 必选,所属部件名称
}
```
部件内依赖和一般的依赖一样
- ##### 部件间依赖示例:
部件间依赖示例:
```
import("//build/ohos.gni")
ohos_shared_library("module1") {
……
part_name = "part1" # 必选,所属部件名称
……
}
```
```
import("//build/ohos.gni")
ohos_shared_library("module1") {
……
part_name = "part1" # 必选,所属部件名称
}
```
- 模块1所属部件的bundle.json文件
模块1所属部件的ohos.build文件
```
{
"name": "@ohos/<component_name>", # HPM部件英文名称,格式"@组织/部件名称"
"description": "xxxxxxxxxxxxxxxx", # 部件功能一句话描述
"version": "3.1", # 版本号,版本号与OpenHarmony版本号一致
"license": "MIT", # 部件License
"publishAs": "code-segment", # HPM包的发布方式,当前默认都为code_segment
"segment": {
"destPath": ""
}, # 发布类型为code_segment时为必填项,定义发布类型code_segment的代码还原路径(源码路径)
"dirs": {}, # HPM包的目录结构,字段必填内容可以留空
"scripts": {}, # HPM包定义需要执行的脚本,字段必填,值非必填
"licensePath "licensePath": "COPYING",
": "COPYING",
"readmePath": {
"en": "README.rst"
},
"component": { # 部件属性
"name": "<component_name>", # 部件名称
"subsystem": "", # 部件所属子系统
"syscap": [], # 部件为应用提供的系统能力
"features": [], # 部件对外的可配置特性列表,一般与build中的sub_component对应,可供产品配置
"adapted_system_type": [], # 轻量(mini)小型(small)和标准(standard),可以是多个
"rom": "xxxKB" # ROM基线,没有基线写当前值
"ram": "xxxKB", # RAM基线,没有基线写当前值
"deps": {
"components": [], # 部件依赖的其他部件
"third_party": [] # 部件依赖的三方开源软件
},
"build": { # 编译相关配置
"sub_component": ["part1"], # 部件编译入口,部件所有模块在此列表
"inner_kits": [ # 部件间接口
{
"header": {
"header_base": "头文件所属目录", # 头文件所属目录
"header_files": [
"头文件名"
] # 头文件名列表
},
"name": "module1的gn target"
},
],
"test": [] # 部件测试用例编译入口
}
}
}
```
```
{
"subsystem":"子系统名称",
"parts": {
"part1": {
"inner_kits": [
{
"header": {
"header_base": "头文件所属目录", # 头文件所属目录
"header_files": [
"头文件名"
] # 头文件名列表
},
"name": "module1的gn target"
},
],
……
}
}
}
```
```
import("//build/ohos.gni")
ohos_shared_library("module2") {
……
external_deps = [
"part1:module1",
……
] # 部件间模块依赖,这里依赖的模块必须是依赖的部件声明在inner_kits中的模块
part_name = "part2" # 必选,所属部件名称
}
```
import("//build/ohos.gni")
ohos_shared_library("module2") {
……
external_deps = [
"part1:module1",
……
] # 部件间模块依赖,这里依赖的模块必须是依赖的部件声明在inner_kits中的模块
part_name = "part2" # 必选,所属部件名称
}
```
```
> ![icon-caution.gif](public_sys-resources/icon-caution.gif) **注意:**
> 部件间依赖要写在external_deps里面,格式为”部件名:模块名"的形式,并且依赖的模块必须是依赖的部件声明在inner_kits中的模块。
### 标准系统如何添加一个模块
要添加的模块可以分为以下三种情况,对原有的配置文件进行不同程度的修改。
......@@ -346,82 +435,145 @@ ohos_shared_library("module2") {
1. 在模块目录下配置BUILD.gn,根据类型选择对应的模板。
这一步与在原有部件中添加一个模块的方法基本一致,只需注意该模块对应BUILD.gn文件中的part_name为新建部件的名称即可。
2. 修改或者新建ohos.build配置文件。
```
2. 修改bundle.json配置文件。"部件包含模块的gn目标"
```
{
"subsystem": "子系统名",
"parts": {
"新建部件名": {
"module_list": [
"部件包含模块的gn目标"
],
"inner_kits": [
],
"test_list": [
"测试用例",
]
"name": "@ohos/<component_name>", # HPM部件英文名称,格式"@组织/部件名称"
"description": "xxxxxxxxxxxxxxxxxxx", # 部件功能一句话描述
"version": "3.1", # 版本号,版本号与OpenHarmony版本号一致
"license": "MIT", # 部件License
"publishAs": "code-segment", # HPM包的发布方式,当前默认都为code_segment
"segment": {
"destPath": "third_party/nghttp2"
}, # 发布类型为code_segment时为必填项,定义发布类型code_segment的代码还原路径(源码路径)
"dirs": {}, # HPM包的目录结构,字段必填内容可以留空
"scripts": {}, # HPM包定义需要执行的脚本,字段必填,值非必填
"licensePath": "COPYING",
"readmePath": {
"en": "README.rst"
},
"component": { # 部件属性
"name": "<component_name>", # 部件名称
"subsystem": "", # 部件所属子系统
"syscap": [], # 部件为应用提供的系统能力
"features": [], # 部件对外的可配置特性列表,一般与build中的sub_component对应,可供产品配置
"adapted_system_type": [], # 轻量(mini)小型(small)和标准(standard),可以是多个
"rom": "xxxKB" # ROM基线,没有基线写当前值
"ram": "xxxKB", # RAM基线,没有基线写当前值
"deps": {
"components": [], # 部件依赖的其他部件
"third_party": [] # 部件依赖的三方开源软件
},
"build": { # 编译相关配置
"sub_component": [
"//foundation/arkui/napi:napi_packages", # 原有模块1
"//foundation/arkui/napi:napi_packages_ndk" # 原有模块2
"//foundation/arkui/napi:new" # 新增模块new
], # 部件编译入口,模块在此处配置
"inner_kits": [], # 部件间接口
"test": [] # 部件测试用例编译入口
}
}
}
}
```
在原有子系统中添加一个新的部件,有两种方法,一种是在该子系统原有的ohos.build文件中添加该部件,另一种是新建一个ohos.build文件,注意无论哪种方式该ohos.build文件均在对应子系统所在文件夹下。
注意无论哪种方式该bundle.json文件均在对应子系统所在文件夹下。
**新建部件并在其中添加一个模块**
ohos.build文件包含两个部分,第一部分subsystem说明了子系统的名称,parts定义了该子系统包含的部件,要添加一个部件,需要把该部件对应的内容添加进parts中去。添加的时候需要指明该部件包含的模块module_list,假如有提供给其它部件的接口,需要在inner_kits中说明,假如有测试用例,需要在test_list中说明,inner_kits与test_list没有也可以不添加。
1. 在模块目录下配置BUILD.gn,根据类型选择对应的模板。这一步与新建部件并在其中添加模块中对应的步骤并无区别。
2. 新建一个bundle.json文件,bundle.json文件均在对应子系统所在文件夹下。bundle.json文件包含两个部分,第一部分subsystem说明了子系统的名称,parts定义了该子系统包含的部件,要添加一个部件,需要把该部件对应的内容添加进parts中去。添加的时候需要指明该部件包含的模块sub_component,假如有提供给其它部件的接口,需要在inner_kits中说明,假如有测试用例,需要在test中说明,inner_kits与test没有也可以不添加。
2. 在//vendor/{product_company}/{product-name}/config.json中添加对应的部件,直接添加到原有部件后即可。
3. 在//vendor/{product_company}/{product-name}/config.json中添加对应的部件,直接添加到原有部件后即可。
```
{
"parts":{
"部件所属子系统名:部件名":{}
}
}
"subsystems": [
{
"subsystem": "部件所属子系统名",
"components": [
{ "component": "部件名1", "features":[] }, # 子系统下的原有部件1
{ "component": "部件名2", "features":[] }, # 子系统下的原有部件2
{ "component": "部件名new", "features":[] } # 子系统下的新增部件new
]
},
.......
]
```
**新建子系统并在该子系统的部件下添加模块**
1. 在模块目录下配置BUILD.gn,根据类型选择对应的模板。这一步与新建部件并在其中添加模块中对应的步骤并无区别。
2. 在新建的子系统目录下每个部件对应的文件夹下创建ohos.build文件,定义部件信息。这一步与新建部件并在其中添加模块中对应的步骤并无区别。
2. 在新建的子系统目录下每个部件对应的文件夹下创建bundle.json文件,定义部件信息。这一步与新建部件并在其中添加模块中对应的步骤并无区别。
3. 修改build目录下的subsystem_config.json文件。
```
{
"子系统名": {
"path": "子系统目录",
"name": "子系统名",
...
}
"子系统名1": { # 原有子系统1
"path": "子系统目录1",
"name": "子系统名1"
},
"子系统名2": { # 原有子系统2
"path": "子系统目录2",
"name": "子系统名2"
},
"子系统名new": { # 新增子系统new
"path": "子系统目录new",
"name": "子系统名new"
},
...
}
```
该文件定义了有哪些子系统以及这些子系统所在文件夹路径,添加子系统时需要说明子系统path与name,分别表示子系统路径和子系统名。
4. 在//vendor/{product_company}/{product-name}目录下的产品配置如product-name是hispark_taurus_standard时,在config.json中添加对应的部件,直接添加到原有部件后即可。
```
{
...
"parts":{
"部件所属子系统名:部件名":{}
}
}
"subsystems": [
{
"subsystem": "arkui", # 原有的子系统名
"components": [ # 单个子系统下的所有部件集合
{
"component": "ace_engine_standard", # 原有的部件名
"features": []
},
{
"component": "napi", # 原有的部件名
"features": []
}
{
"component": "component_new1", # 原有子系统新增的的部件名component_new1
"features": []
}
]
},
{
"subsystem": "subsystem_new", # 新增的子系统名
"components": [
{
"component": "component_new2", # 新增子系统新增的的部件名component_new2
"features": []
}
]
},
...
]
```
成功添加验证:
- 在输出文件夹的对应子系统文件夹下的部件文件夹下的BUILD.gn文件中module_list包含了新建模块的BUILD.gn中定义的目标。
- 编译完成后打包到image中去,生成对应的so文件或者二进制文件。
成功添加验证:
- 在输出文件夹的对应子系统文件夹下的部件文件夹下的BUILD.gn文件中module_list包含了新建模块的BUILD.gn中定义的目标。
- 编译完成后打包到image中去,生成对应的so文件或者二进制文件。
**配置文件说明**
OpenHarmony的配置文件主要有四个。
1. vendor\产品厂商\产品名\config.json
```
{
"product_name": "MyProduct",
......@@ -444,55 +596,71 @@ OpenHarmony的配置文件主要有四个。
}
```
指明了产品名,产品厂商,产品设备,版本,要编译的系统类型,以及产品包含的子系统。
2. build目录下的subsystem_config.json文件。
```
{
"ace": {
"project": "hmf/ace",
"path": "foundation/ace",
"name": "ace",
"dir": "foundation"
}
}
"arkui": {
"path": "foundation/arkui",
"name": "arkui"
},
"ai": {
"path": "foundation/ai",
"name": "ai"
},
......
}
```
该文件对子系统进行了说明,我们需要该子系统定义中的name与path,分别表示子系统的名称和所在文件夹路径。
3. 子系统中ohos.build文件。
3. 子系统中bundle.json文件。
```
{
"subsystem": "ace",
"parts": {
"napi": {
"module_list": [
"//foundation/arkui/napi:napi_packages"
],
"inner_kits": [
],
"test_list": [
"//foundation/arkui/napi:napi_packages_test",
"//foundation/arkui/napi/test/unittest:unittest"
]
"name": "@ohos/<component_name>", # HPM部件英文名称,格式"@组织/部件名称"
"description": "xxxxxxxxxxxxxxxxxxx", # 部件功能一句话描述
"version": "3.1", # 版本号,版本号与OpenHarmony版本号一致
"license": "MIT", # 部件License
"publishAs": "code-segment", # HPM包的发布方式,当前默认都为code_segment
"segment": {
"destPath": ""
}, # 发布类型为code_segment时为必填项,定义发布类型code_segment的代码还原路径(源码路径)
"dirs": {}, # HPM包的目录结构,字段必填内容可以留空
"scripts": {}, # HPM包定义需要执行的脚本,字段必填,值非必填
"licensePath": "COPYING",
"readmePath": {
"en": "README.rst"
},
"component": { # 部件属性
"name": "<component_name>", # 部件名称
"subsystem": "", # 部件所属子系统
"syscap": [], # 部件为应用提供的系统能力
"features": [], # 部件对外的可配置特性列表,一般与build中的sub_component对应,可供产品配置
"adapted_system_type": [], # 轻量(mini)小型(small)和标准(standard),可以是多个
"rom": "xxxKB" # ROM基线,没有基线写当前值
"ram": "xxxKB", # RAM基线,没有基线写当前值
"deps": {
"components": [], # 部件依赖的其他部件
"third_party": [] # 部件依赖的三方开源软件
},
"build": { # 编译相关配置
"sub_component": ["部件包含模块的gn目标"], # 部件编译入口
"inner_kits": [], # 部件间接口
"test": [] # 部件测试用例编译入口
}
}
}
}
```
ohos.build文件定义了子系统包含的部件。
每个部件定义它所包含的模块目标module_list,以及部件间交互的接口inner_kits,测试用例test_list。部件包含的模块目标module_list是必须要说明的。
bundle.json文件定义了子系统包含的部件。
每个部件定义它所包含的模块目标component.build.sub_component,以及部件间交互的接口component.build.inner_kits,测试用例component.build.test_list。部件包含的
模块目标component.build.sub_component是必须要说明的。
4. 每个模块对应的BUILD.gn文件。
可以使用提供的模板,也可以使用gn语法规则自定义编写。
### hap的编译
**hap包的构成**
......@@ -514,6 +682,7 @@ ohos_resources
- 资源目标的目标名必须以"resources"或"resource"或"res"结尾,否则编译检查时会报错
- 支持的变量:
1. sources: 资源的路径,变量类型是list,可以写多个路径
2. hap_profile: 编译资源时需要提供对应hap包的config.json
3. deps: 当前目标的依赖,可选
......@@ -527,6 +696,7 @@ ohos_assets
- assets目标的目标名必须以"assets"或"asset"结尾
- 支持的变量:
1. sources:raw assets所在路径,变量类型是list,可以写多个路径
2. deps: 当前目标的依赖,可选
......@@ -537,6 +707,7 @@ ohos_js_assets
- JS assets目标的目标名必须以"assets"或"asset"结尾
- 支持的变量:
1. source_dir: JS 资源的路径,变量类型是string,只能写一个
2. deps: 当前目标的依赖,可选
......@@ -545,15 +716,16 @@ ohos_hap
- 声明一个hap目标,该目标会生成一个hap包,最终将会打包到system镜像中
- 支持的变量:
1. hap_profile: hap包的config.json
2. deps: 当前目标的依赖
3. shared_libraries: 当前目标依赖的native库
4. hap_name: hap包的名字,可选,默认为目标名
5. final_hap_path: 用户可以制定生成的hap的位置,可选,final_hap_path中会覆盖hap_name
6. subsystem_name: hap包从属的子系统名,需要和ohos.build中的名字对应,否则将导致无法安装到system镜像中
6. subsystem_name: hap包从属的子系统名,需要和bundle.json中的名字对应,否则将导致无法安装到system镜像中
7. part_name: hap包从属的部件名,同subsystem_name
8. js2abc: 是否需要将该hap包转换为ARK的字节码
签名篇见:[配置应用签名]( https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ohos-debugging-and-running-0000001263040487#section17660437768)
签名篇见:[配置应用签名]( https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ohos-debugging-and-running-0000001263040487#section17660437768)
9. certificate_profile: hap对应的授权文件,用于签名
10. certificate_file: 证书文件,证书文件和授权文件,应用开发者需要去openharmony官网申请
11. keystore_path: keystore文件,用于签名
......@@ -561,35 +733,33 @@ ohos_hap
13. key_alias: key的别名
14. module_install_name:安装时的hap包名称
15. module_install_dir: 安装到system中的位置,默认安装在system/app目录下
**开发示例**
```
import("//build/ohos.gni") # 引用ohos.gni
ohos_hap("clock") {
hap_profile = "./src/main/config.json" # config.json
deps = [
":clock_js_assets", # JS assets
":clock_resources", # 资源
]
shared_libraries = [
"//third_party/libpng:libpng", # native库
]
certificate_profile = "../signature/systemui.p7b" # Cer文件
hap_name = "SystemUI-NavigationBar" # 名字
part_name = "prebuilt_hap"
subsystem_name = "applications"
}
ohos_js_assets("clock_js_assets") {
source_dir = "./src/main/js/default"
}
ohos_resources("clock_resources") {
sources = [ "./src/main/resources" ]
hap_profile = "./src/main/config.json"
}
```
**hap开发示例**
```
import("//build/ohos.gni") # 引用ohos.gni
ohos_hap("clock") {
hap_profile = "./src/main/config.json" # config.json
deps = [
":clock_js_assets", # JS assets
":clock_resources", # 资源
]
shared_libraries = [
"//third_party/libpng:libpng", # native库
]
certificate_profile = "../signature/systemui.p7b" # Cer文件
hap_name = "SystemUI-NavigationBar" # 名字
part_name = "prebuilt_hap"
subsystem_name = "applications"
}
ohos_js_assets("clock_js_assets") {
source_dir = "./src/main/js/default"
}
ohos_resources("clock_resources") {
sources = [ "./src/main/resources" ]
hap_profile = "./src/main/config.json"
}
```
### 开源软件Notice收集策略说明
......@@ -599,22 +769,22 @@ ohos_hap
静态库本身是不会被打包的,一般是作为动态库或者可执行程序的一部分被打包到系统中的,为了确保完备,静态库的都会收集。
最终合并的Notice.txt要体现出镜像中每个文件都是用了哪些License,模块和License要有对应关系。
最终合并的NOTICE.txt要体现出镜像中每个文件都是用了哪些License,模块和License要有对应关系。
最终合并的Notice.txt文件在/system/etc/ 目录下。
最终合并的NOTICE.txt文件在/system/etc/ 目录下。
**收集规则**
按照优先级收集License
1. 模块在BUILD.gn中直接声明自己使用的License文件,优先级最高。如下图示例:
```
ohos_shared_library("example") {
...
license_file = "path-to-license-file"
...
}
ohos_shared_library("example") {
...
license_file = "path-to-license-file"
...
}
```
2. 如果模块没有显式声明,那么编译脚本会在BUILD.gn所在的当前目录中查找Readme.OpenSource文件,解析该文件,找出该文件中声明的license,将其作为模块的License。
......@@ -630,4 +800,4 @@ ohos_hap
2. 代码目录下,如果代码使用的不是Apache2.0 License,需要在目录下提供对应的License文件,或者直接在模块中指定license_file。
3. 如果BUILD.gn中添加的源码文件不是当前目录的,需要检查下源码文件所在仓下的license是否和BUILD.gn文件所在仓的一致,不一致的需要处理。
3. 如果BUILD.gn中添加的源码文件不是当前目录的,需要检查下源码文件所在仓下的license是否和BUILD.gn文件所在仓的一致,不一致的需要处理。
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册