编译子系统通过模块、部件和产品三层配置来实现编译和打包。模块就是编译子系统的一个目标,包括(动态库、静态库、配置文件、预编译模块等)。模块要定义属于哪个部件,一个模块只能归属于一个部件。
以下是常用的模块配置规则:
# C/C++模板
ohos_shared_library #动态库
ohos_static_library #静态库
ohos_executable #可执行文件
ohos_source_set
# 预编译模板:
ohos_prebuilt_executable
ohos_prebuilt_shared_library
ohos_prebuilt_static_library
#hap模板
ohos_hap
ohos_app_scope
ohos_js_assets
ohos_resources
#其他常用模板
#配置文件
ohos_prebuilt_etc
#sa配置
ohos_sa_profile
c/c++模板示例
ohos开头的模板对应的.gni文件路径在:openharmony/build/templates/cxx/cxx.gni
ohos_shared_library示例:
import("//build/ohos.gni")
ohos_shared_library("helloworld") {
sources = ["file"] # 包含的C或C++文件,如:["",""]
include_dirs = [] # 如有重复头文件定义,优先使用前面路径头文件
cflags = [] # 如重复冲突定义,后面的参数优先生效,也就是该配置项中优先生效
cflags_c = []
cflags_cc = []
ldflags = [] # 如重复冲突定义,前面参数优先生效,也就是ohos_template中预制参数优先生效
configs = []
deps = [] # 部件内模块依赖
external_deps = [ # 跨部件模块依赖定义,"part_name:module_name", # 定义格式为 "部件名:模块名称"
] # 这里依赖的模块必须是依赖的部件声明在inner_kits中的模块
output_name = [string] # 模块输出名
output_extension = [] # 模块名后缀
module_install_dir = [] # 缺省在/system/lib64或/system/lib下, 模块安装路径,模块安装路径,从system/,vendor/后开始指定
relative_install_dir = [] # 模块安装相对路径,相对于/system/lib64或/system/lib;如果有module_install_dir配置时,该配置不生效
part_name = [string] # 必选,所属部件名称
output_dir
# Sanitizer配置,每项都是可选的,默认为false/空
sanitize = {
# 各个Sanitizer开关
cfi = [boolean] # 控制流完整性检测
cfi_cross_dso = [boolean] # 开启跨so调用的控制流完整性检测
integer_overflow = [boolean] # 整数溢出检测
boundary_sanitize = [boolean] # 边界检测
ubsan = [boolean] # 部分ubsan选项
all_ubsan = [boolean] # 全量ubsan选项
...
debug = [boolean] # 调测模式
blocklist = [string] # 屏蔽名单路径
}
testonly = [boolean]
license_as_sources = []
license_file = [] # 后缀名是.txt的文件
remove_configs = []
no_default_deps = []
install_images = []
install_enable = [boolean]
symlink_target_name = []
version_script = []
use_exceptions = []
}
ohos_static_library示例
import("//build/ohos.gni")
ohos_static_library("helloworld") {
sources = ["file"] # 后缀名是.c的相关文件
include_dirs = ["dir"] # 包含目录
configs = [] # 配置
deps = [] # 部件内模块依赖
part_name = [string] # 部件名称
subsystem_name = [string] # 子系统名称
cflags = []
external_deps = [ # 跨部件模块依赖定义,"part_name:module_name", # 定义格式为 "部件名:模块名称"
] # 这里依赖的模块必须是依赖的部件声明在inner_kits中的模块
lib_dirs = []
public_configs = []
# Sanitizer配置,每项都是可选的,默认为false/空
sanitize = {
# 各个Sanitizer开关
cfi = [boolean] # 控制流完整性检测
cfi_cross_dso = [boolean] # 开启跨so调用的控制流完整性检测
integer_overflow = [boolean] # 整数溢出检测
boundary_sanitize = [boolean] # 边界检测
ubsan = [boolean] # 部分ubsan选项
all_ubsan = [boolean] # 全量ubsan选项
...
debug = [boolean] # 调测模式
blocklist = [string] # 屏蔽名单路径
}
remove_configs = []
no_default_deps = []
license_file = [] # 后缀名是.txt的文件
license_as_sources = []
use_exceptions = []
}
ohos_executable示例
import("//build/ohos.gni")
ohos_executable("helloworld") {
configs = [] # 配置
part_name = [string] # 部件名称
subsystem_name = [string] # 子系统名称
deps = [] # 部件内模块依赖
external_deps = [ # 跨部件模块依赖定义,
"part_name:module_name", # 定义格式为 "部件名:模块名称"
] # 这里依赖的模块必须是依赖的部件声明在inner_kits中的模块
ohos_test = []
test_output_dir = []
# Sanitizer配置,每项都是可选的,默认为false/空
sanitize = {
# 各个Sanitizer开关
cfi = [boolean] # 控制流完整性检测
cfi_cross_dso = [boolean] # 开启跨so调用的控制流完整性检测
integer_overflow = [boolean] # 整数溢出检测
boundary_sanitize = [boolean] # 边界检测
ubsan = [boolean] # 部分ubsan选项
all_ubsan = [boolean] # 全量ubsan选项
...
debug = [boolean] # 调测模式
blocklist = [string] # 屏蔽名单路径
}
testonly = [boolean]
license_as_sources = []
license_file = [] # 后缀名是.txt的文件
remove_configs = []
static_link = []
install_images = []
module_install_dir = [] # 模块安装路径,从system/,vendor/后开始指定
relative_install_dir = []
symlink_target_name = []
output_dir = [directory] # 存放输出文件的目录
install_enable = [boolean] # 编译后的镜像烧录后,可执行模块默认是不安装在开发板内,如果要安装需要指定install_enable为true.
version_script = []
use_exceptions = []
}
ohos_source_set示例
import("//build/ohos.gni")
ohos_source_set("helloworld") {
sources = ["file"] # 后缀名是.c的相关文件
include_dirs = [] # 包含目录
configs = [] # 配置
public = [] # .h类型头文件
defines = []
public_configs = []
part_name = [string] # 部件名称
subsystem_name = [string] # 子系统名称
deps = [] # 部件内模块依赖
external_deps = [ # 跨部件模块依赖定义,
"part_name:module_name", # 定义格式为 "部件名:模块名称"
] # 这里依赖的模块必须是依赖的部件声明在inner_kits中的模块
# Sanitizer配置,每项都是可选的,默认为false/空
sanitize = {
# 各个Sanitizer开关
cfi = [boolean] # 控制流完整性检测
cfi_cross_dso = [boolean] # 开启跨so调用的控制流完整性检测
integer_overflow = [boolean] # 整数溢出检测
boundary_sanitize = [boolean] # 边界检测
ubsan = [boolean] # 部分ubsan选项
all_ubsan = [boolean] # 全量ubsan选项
...
debug = [boolean] # 调测模式
blocklist = [string] # 屏蔽名单路径
}
testonly = [boolean]
license_as_sources = []
license_file = []
remove_configs = []
no_default_deps = []
license_file = [] # 后缀名是.txt的文件
license_as_sources = []
use_exceptions = []
}
注意:
只有sources和part_name是必选,其他都是可选的;
Sanitizer配置详见:Sanitizer使用说明。
预编译模板示例
预编译模板的.gni相关文件路径在:openharmony/build/templates/cxx/prebuilt.gni。
ohos_prebuilt_executable示例:
import("//build/ohos.gni")
ohos_prebuilt_executable("helloworld") {
sources = ["file"] # 源
output = []
install_enable = [boolean]
deps = [] # 部件内模块依赖
public_configs = []
subsystem_name = [string] # 子系统名
part_name = [string] # 部件名
testonly = [boolean]
visibility = []
install_images = []
module_install_dir = [] # 模块安装路径,从system/,vendor/后开始指定
relative_install_dir = [] # 模块安装相对路径,相对于system/etc;如果有module_install_dir配置时,该配置不生效
symlink_target_name = []
license_file = [] # 后缀名是.txt的文件
license_as_sources = []
}
注意:只有sources和part_name是必选,其他都是可选的。
新增模块并编译
分为三种case:
在原有部件添加一个模块
新建部件并在其中添加模块
新建子系统并在该子系统的部件下添加模块。

在原有部件中添加一个模块。
在模块目录下配置BUILD.gn,根据模板类型选择对应的gn模板。
修改bundle.json
{
"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": [] # 部件测试用例编译入口
}
}
}
注意:无论哪种方式该bundle.json文件均在对应子系统所在文件夹下。
新建部件并在其中添加一个模块
1.在模块目录下配置BUILD.gn,根据模板类型选择对应的gn模板。与在原有部件添加一个模板的方法基本一致,只需要注意该模板对应的BUILD.gn文件中的part_name为新建部件的名称即可。
2.新建一个bundle.json文件
3.在vendor/{product_company}/{product-name}/config.json中添加对应的部件,直接添加到原有部件后即可. 比如~/vendor/hihope/rk3568/config.json。
"subsystems": [
{
"subsystem": "部件所属子系统名",
"components": [
{ "component": "部件名1", "features":[] }, # 子系统下的原有部件1
{ "component": "部件名2", "features":[] }, # 子系统下的原有部件2
{ "component": "部件名new", "features":[] } # 子系统下的新增部件new
]
},
.
]
新建子系统并在该子系统的部件下添加模块
1.在模块目录下配置BUILD.gn.
2.在该子系统的每个部件对应文件夹下创建bundle.json。
3.修改build/目录下的subsystem_config.json。
{
"子系统名1": { # 原有子系统1
"path": "子系统目录1",
"name": "子系统名1"
},
"子系统名2": { # 原有子系统2
"path": "子系统目录2",
"name": "子系统名2"
},
"子系统名new": { # 新增子系统new
"path": "子系统目录new",
"name": "子系统名new"
},
}
4.在vendor/{product_company}/{product-name}/config.json中比如,~/vendor/hihope/rk3568/config.json添加新增的对应部件。
"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": []
}
]
},
]
模块编译
1.模块可以使用“--build-target 模块名"单独编译,编译命令如下:
./build.sh --build-target 模块名 或者 ./build.sh -T 模块名
2.也可以编译相应产品,以编译hispark_taurus_standard为例,编译命令如下:
./build.sh --product-name hispark_taurus_standard --build-target 模块名 --ccache
3.还可以编译模块所在的部件:
./build.sh --product-name hispark_taurus_standard --build-target musl --build-target 模块名 --ccache