同步操作将从 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" ]
}
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。