同步操作将从 OpenHarmony/build 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
OpenHarmony的软件以部件作为基本功能单元,但为了组装出不同形态的产品,部件可能需要提供不同规格的版本。本文主要介绍以下几个方面的编译实践方法:
feature主要用于描述部件在不同产品下的差异化行为。产品在装配部件时,可以通过配置不同的feature来使用部件不同的特性集。
当前系统有两个版本的产品配置文件格式,配置方法分别如下:
productdefine/common/products/xxx.json目录下V2版本产品配置文件中为部件配置不同feature的示例如下:
{
...
"parts": {
"subsytemName:partName": {
"feature": [ "{partName}_feature_A": false ]
}
}
}
vendor/xxx/config.json目录下V3版本产品配置文件中为部件配置不同feature的示例如下:
{
...
"subsystems": [{
"subsystem": "subsystemName",
"components": [{
"component": "partName",
"features":[ "{partName}_feature_A=false" ]
}]
}]
}
下面介绍feature的声明、定义以及使用方法。
feature的声明
在部件的bundle.json文件中通过feature_list来声明部件的feature列表,每个feature都必须以"{部件名}_"开头。示例如下:
{
"name": "@ohos/xxx",
"component": {
"name": "partName",
"subsystem": "subsystemName",
"features": [
"{partName}_feature_A"
]
}
}
features中可以为部件声明多个feature。
feature的定义
在部件内可通过以下方式定义feature的默认值:
declare_args() {
{partName}_feature_A = true
}
该值是此部件的默认值,产品可以在部件列表中重载该feature的值。
feature需给部件内多个模块使用时,建议把feature定义在部件的全局gni文件中,各个模块的BUILD.gn中import该gni文件。
feature的使用
BUILD.gn文件中可通过以下方式进行根据feature决定部分代码或模块参与编译:
if ({partName}_feature_A) {
sources += [ "xxx.c" ]
}
# 某个特性引入的依赖,需要通过该feature进行隔离
if ({partName}_feature_A) {
deps += [ "xxx" ]
external_deps += [ "xxx" ]
}
# bundle.json中不支持if判断,如果bundle.json中包含的sub_component需要被裁减,可以定义group进行裁减判断
group("testGroup") {
deps = []
if ({partName}_feature_A) {
deps += [ "xxx" ]
}
}
也可以通过以下方式为模块定义代码宏进行代码级差异化编译:
if ({partName}_feature_A) {
defines += ["FEATUREA_DEFINE"]
}
可裁剪模块使用独立BUILD.gn文件
实际裁剪部件中的单个模块时,该模块的BUILD.gn不能和其它必选模块混合在同一个BUILD.gn脚本中。
shared_library("requiredA") {
deps = ["dependB"]
}
shared_library("optionalC") {
deps = ["dependD"]
}
如上图所示,由于编译扫描部件时是以BUILD.gn文件为单位的,只要requiredA模块被引用,编译时可选的optionalC以及dependD模块都会被引入并被依赖。因此,建议可选模块使用单独的BUILD.gn脚本编写。
如果部件A/B/C/D等都依赖部件O,而部件O可被裁减;则部件A/B/C/D等都需要定义裁减部件O时的隔离feature。在这种情况下,产品配置人员裁减部件O时,还需要手动关闭部件A/B/C/D为支持裁减部件O所定义的feature开关,装配时比较麻烦。
为了解决该问题,编译框架将当前产品支持的所有部件都加载到了global_parts_info全局变量中,每个部件的编译脚本中可以通过部件名称判断该部件是否被裁减,然后自动修改部件的feature默认值,实现部件feature默认值可自动跟随裁减部件而同步更新。
declare_args() {
"{partName}_feature_A" = true
if (!defined(global_parts_info.{subsystem_O}_{partName_O})) {
{partName}_feature_A = false
}
}
如上图所示,部件A的{partName}_feature_A特性默认为true,如果部件O被裁减,则该feature自动配置为false。
注意:访问global_parts_info中的部件名称中如果包含有"-"或".",需转化为"_"。global_parts_info的具体内容可查看out/preloader/productName/parts_info.json文件。
inner_kits是部件之间依赖的接口集合,部件内的模块及特性裁剪不能影响inner_kits接口:
所属部件没被裁剪,但内部有部分模块被裁剪:
此场景要求inner_kits接口不能有任何缺失,确保依赖该inner_kits的外部模块可正常编译,运行时可以内部实现上有差异。
所属部件被裁剪:
依赖该inner_kits的模块需要一起被裁剪。
部分IoT无屏产品不支持应用安装,不需要编译system_kits提供JS API。因此,每个子系统的napi模块需保证可独立裁剪。其裁剪方式通过全局的support_jsapi开关进行隔离。
support_jsapi的默认值为true,产品配置中可通过以下方法来修改:
productdefine/common/products/xxx.json目录下的V2版本产品配置文件配置示例如下:
{
"product_name": "productName",
"version": "2.0",
"product_company": "xxx",
"support_jsapi": false,
...
}
vendor/xxx/config.json目录下的V3版本产品配置文件配置示例如下:
{
"product_name": "productName",
"version": "3.0",
"device_company": "xxx",
"support_jsapi": false,
...
}
support_jsapi是一个全局的feature,每个部件都可以参考1.2章的方式使用进行代码隔离。
group("jsapi_group") {
deps = []
if (support_jsapi) {
deps += [ "real_jsapi_module" ]
}
}
系统能力即SystemCapability,又称syscap,是部件向开发者提供的接口的集合。
部件配置系统能力是为了方便某个特定部件是否要打开或关闭特定的系统能力。
部件配置系统能力的位置在部件目录下的bundle.json,配置示例如下所示:
"component": {
"name": "wifi",
"subsystem": "communication",
"syscap": [
"SystemCapability.Communication.WiFi.STA = true",
"SystemCapability.Communication.WiFi.AP = true",
"SystemCapability.Communication.WiFi.P2P = false",
"SystemCapability.Communication.WiFi.Core = false",
"SystemCapability.Communication.WiFi.HotspotExt"
]
],
...
}
在component下加入syscap这一关键字,内部配置相应的系统能力,系统能力若无赋值,则默认为true,若有赋值,则按实际值为准。若值为true,则表示该部件默认开启此系统能力,若值为false,则表明该部件默认关闭此系统能力
以上配置表明,WIFI的STA、AP、和HotspotExt三个系统能力是打开的,而P2P和Core是关闭的。
产品配置系统能力是为了方便某个特定产品是否要打开或关闭特定的系统能力,若无配置,则以部件侧的配置为准,产品配置系统能力的位置在vender/{company}/{product}/config.json。
如果要对产品的系统能力进行精细化配置,可在产品配置中加入syscap关键字,并对要配置的系统能力赋值。产品侧的配置优先级大于部件系统能力默认配置,若某一个系统能力在部件侧默认配置为false,在产品侧配置为true,则这个系统能力的最终配置为true。示例如下:
{
"subsystem": "communication",
"components": [
...
{
"component": "wifi",
"features": [],
"syscap": [
"SystemCapability.Communication.WiFi.AP = false",
"SystemCapability.Communication.WiFi.P2P = true",
"SystemCapability.Communication.WiFi.HotspotExt = false"
]
},
...
以上配置表明,WiFi的AP和HotspotExt系统能力是关闭的,而P2P是打开的。综合部件侧的配置,最终STA、P2P为打开系统能力,而AP、Core和HotspotExt为关闭的系统能力。
一般来说,当产品没有特性化差异的时候,我们仅需在部件侧配置系统能力,部件侧配置的系统能力是我们的基础,只有当产品存在特性化差异,需要关闭某个默认打开的系统能力或打开某个系统默认关闭的系统能力时,我们才会需要在产品侧配置。
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。