Openharmony 编译框架概述

这篇具有很好参考价值的文章主要介绍了Openharmony 编译框架概述。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

简介

编译构建子系统提供了一个基于Gn和ninja的编译构建框架。根据产品配置,编译生成对应的镜像包。其中编译构建流程为

preloader->loader->gn->ninja

  1. build文件夹下的subsystem_config.json文件,主要包含子系统名称与路径信息,在preloader阶段被加载,根据子系统名称和路径信息查找该路径下的bundle.json和ohos.build文件。

    加载vendor厂商设备下的config.json,配置文件主要包含产品名称,产品厂商,产品设备名,产品类型,产品对应子系统路径,产品所包含的部件等信息。

  2. 使用Gn配置构建目标。

  3. Gn运行后会生成ninja文件。

  4. 通过运行ninja来执行编译任务。

 

约束与限制

- 编译环境需要Ubuntu18.04及以上版本。

- 安装编译所需的程序包。

安装命令:

sudo apt-get install bison ccache default-jdk flex gcc-arm-linux-gnueabi gcc-arm-none-eabi genext2fs liblz4-tool libssl-dev libtinfo5 mtd-utils mtools openssl ruby scons unzip u-boot-tools zip

 

编译方式和命令选项

编译方式分为源码根目录的build.sh执行脚本和hb命令方式,最终编译逻辑都会走build下的hb模块。

命令选项:

  -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个工作失败
  --jobs=JOBS                           # 指定编译线程数
  --export-para=EXPORT_PARA
  --build-only-gn                       # 只做gn解析,不运行ninja
  --ccache                              # 可选  编译使用ccache,需要本地安装ccache,未变化的部件则不会执行编译
  --fast-rebuild                        # 快速重建,default=False,直接使用ninja编译,跳过产品和gn解析
  --log-level=LOG_LEVEL               # 指定编译期间的日志级别','三个级别可选:debug, info and error,default='info'
  --device-type=DEVICE_TYPE             # 指定设备类型,default='default',用于固件适配
  --build-variant=BUILD_VARIANT           # 指定设备操作模式,default='user'

 

gn常用配置模版

# C/C++模板
ohos_shared_library #动态库
ohos_static_library #静态库
ohos_executable     #可执行文件
ohos_source_set     #资源集合
ohos_unittest   
​
# 预编译模板,使用已生成的二进制文件:
ohos_prebuilt_executable
ohos_prebuilt_shared_library
ohos_prebuilt_static_library
​
#hap模板
ohos_hap
ohos_app_scope  #下面几项都服务于ohos_hap
ohos_js_assets
ohos_resources
​
#其他常用模板
ohos_prebuilt_etc   #配置文件
ohos_copy
​
#sa配置
ohos_sa_profile
​
#其他常用模版
group           #模块组合,可将一个组合作为一个组件
config          #配置项,可用于其他模版的configs配置项
action          #行为执行,可用于执行脚本
​
print           #调试用打印
foreach
...

 

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 = []                  # 配置项,应用于当前目标
  public_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                    #文件输出路径
​
​

 

子系统配置

oh子系统配置在build/subsystem_config.json中,子系统目录下需要存在 bundle.json文件或者ohos.build文件,是该目录组件作为子系统编译的先决条件。

*bundle.json*

    {
       "name": "@ohos/<component_name>",                 # HPM部件英文名称,格式"@组织/部件名称"
       "description": "xxxxxxxxxxxxxxxxxxx",             # 部件功能一句话描述
       "version": "3.1",                                 # 版本号,版本号与OpenHarmony版本号一致
       "license": "Apache License 2.0",                  # 部件License
       "publishAs": "code-segment",                      # HPM包的发布方式,当前默认都为code_segment
       "segment": {
           "destPath": ""
       },                                                # 发布类型为code_segment时为必填项,定义发布类型code_segment的代码还原路径(源码路径)
       "dirs": {},                                       # HPM包的目录结构,字段必填内容可以留空
       "scripts": {},                                    # HPM包定义需要执行的脚本,字段必填,值非必填
       "component": {                                    # 部件属性
           "name": "<component_name>",                   # 部件名称
           "subsystem": "",                              # 部件所属子系统
           "syscap": ["SystemCapability.Ai.AiEngine"],   # 部件为应用提供的系统能力
           "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": []                                # 部件测试用例编译入口
           }
       }
    }

 

 

新建部件并在其中添加模块

  1. 在模块目录下配置BUILD.gn,根据类型选择对应的模板。

这一步与在原有部件中添加一个模块的方法基本一致,只需注意该模块对应BUILD.gn文件中的part_name为新建部件的名称即可。

 

  1. 修改或者新建ohos.build配置文件,参考vendor/hihope/rk3568/ohos.build

  {
     "subsystem": "子系统名",
     "parts": {
       "新建部件名": {
         "module_list": [
           "部件包含模块的gn目标"
         ],
         "inner_kits": [
         ],
         "test_list": [
           "测试用例",
         ]
       }
     }
   }
​
​

当前oh部件配置文件已基本使用bundle.json,ohos.build配置文件已基本被替代。

 

新建子系统并在该子系统的部件下添加模块

  1. 在模块目录下配置BUILD.gn,根据类型选择对应的模板。

  2. 在新建的子系统目录下每个部件对应的文件夹下创建bundle.json文件,定义部件信息。这一步与新建部件并在其中添加模块中对应的步骤并无区别。

  3. 修改build目录下的subsystem_config.json文件

{
    "子系统名": {
        "path": "子系统目录",
        "name": "子系统名",
        ...
    }
}

该文件定义了有哪些子系统以及这些子系统所在文件夹路径,添加子系统时需要说明子系统path与name,分别表示子系统路径和子系统名。

  1. 在vendor/hihope/rk3568/config.json中添加对应的部件,可实现特性化定制。

      "subsystems": [
        {
          "subsystem": 子系统名,
          "components": [
            {
              "component": 部件名,
              "features": []    //特性化定制
            }
          ]
        }

 

成功添加验证:

+ 在输出文件夹的对应子系统文件夹下的部件文件夹下的BUILD.gn文件中module_list包含了新建模块的BUILD.gn中定义的目标。

+ 编译完成后打包到image中去,生成对应的so文件或者二进制文件

 

部件化编译实践

1. 使用feature配置进行部件差异化配置

feature主要用于描述部件在不同产品下的差异化行为。产品在装配部件时,可以通过配置不同的feature来使用部件不同的特性集。

1.1 产品如何配置部件的feature

当前系统两个版本的产品配置文件格式,配置方法分别如下:

- V3产品配置文件

vendor/xxx/config.json目录下V3版本产品配置文件中为部件配置不同feature的示例如下:

{
 ...
 "subsystems": [
  "subsystem": "subsystemName",
   "components": [{
    "component": "partName",
    "features":[ "{partName}_feature_A=false" ]
   }]
 }]
}

 

1.2 部件开发人员如何使用feature进行部件的特性隔离

下面介绍feature的声明、定义以及使用方法。

在部件的bundle.json文件中通过feature_list来声明部件的feature列表,每个feature都必须以"*{部件名}_*"开头。示例如下:

{
 "name": "@ohos/xxx",
 "component": {
  "name": "partName",
  "subsystem": "subsystemName",
  "features": [
   "{partName}_feature_A"	// features中可以为部件声明多个feature。
  ]
 }
}

在部件内可通过以下方式定义feature的默认值,一般是在gni头文件中:

 declare_args() {
  {partName}_feature_A = true
 }

 

该值是此部件的默认值,产品可以在部件列表中重载该feature的值。

feature需给部件内多个模块使用时,建议把feature定义在部件的全局gni文件中,各个模块的BUILD.gn中import该gni文件。

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脚本中。

 

2. 如何判断当前产品中是否包含某个依赖的部件

如果部件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。

 

3. inner_kits模块裁剪处理策略

inner_kits是部件之间依赖的接口集合,部件内的模块及特性裁剪不能影响inner_kits接口:

- 所属部件没被裁剪,但内部有部分模块被裁剪:

此场景要求inner_kits接口不能有任何缺失,确保依赖该inner_kits的外部模块可正常编译,运行时可以内部实现上有差异。

- 所属部件被裁剪:

依赖该inner_kits的模块需要一起被裁剪。

 

4. napi模块需支持统一裁剪方式

部分IoT无屏产品不支持应用安装,不需要编译system_kits提供JS API。因此,每个子系统的napi模块需保证可独立裁剪。其裁剪方式通过全局的support_jsapi开关进行隔离。

4.1 产品如何配置关闭所有的jsapi模块编译

support_jsapi的默认值为true,产品配置中可通过以下方法来修改:

vendor/xxx/config.json目录下的V3版本产品配置文件配置示例如下:

{
  "product_name": "productName",
  "version": "3.0",
  "device_company": "xxx",
  "support_jsapi": false,
  ...
}

 

4.2 部件开发人员如何使用support_jsapi进行部件的特性隔离

support_jsapi是一个全局的feature,每个部件都可以参考1.2章的方式使用进行代码隔离。

group("jsapi_group") {
 deps = []
 if (support_jsapi) {
  deps += [ "real_jsapi_module" ]
 }
}

 

5.1 部件配置系统能力

部件配置系统能力是为了方便某个特定部件是否要打开或关闭特定的系统能力。

部件配置系统能力的位置在部件目录下的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,则表明该部件默认关闭此系统能力。

SystemCapability是面向北向应用开发的能力呈现。

 

5.2 产品配置系统能力

产品配置系统能力是为了方便某个特定产品是否要打开或关闭特定的系统能力,若无配置,则以部件侧的配置为准,产品配置系统能力的位置在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"
     ]
    },
    ...

 

生成镜像

通用镜像配置在build/ohos/images/mkimage下的镜像名_image.conf.txt,每个系统镜像文件都是由一个image_conf.txt描述文件来描述的,包含挂载路径,镜像大小,文件系统类型等。厂商定制配置在vendor产品下的image_conf目录下。

build/ohos/images/mkimage/system_image_conf.txt文章来源地址https://www.toymoban.com/news/detail-754603.html

/
1610612224
--fs_type=ext4
#可选配置
--dac_config ../../build/ohos/images/mkimage/dac.txt	// path uid gid cap
--file_context obj/base/security/selinux/file_contexts.bin	//base selinux 文件安全策略

到了这里,关于Openharmony 编译框架概述的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • OpenHarmony—Docker编译环境

    OpenHarmony为开发者提供了两种Docker环境,以帮助开发者快速完成复杂的开发环境准备工作。两种Docker环境及适用场景如下: 独立Docker环境:适用于直接基于Ubuntu、Windows操作系统平台进行版本编译的场景。 基于HPM的Docker环境:适用于使用HPM工具进行发行版编译的场景。 表1 D

    2024年03月11日
    浏览(61)
  • 如何编译OpenHarmony自带APP

    作者:王石 概述 OpenHarmony 的主干代码是开源社区的重要学习资源,对于想进行应用开发和熟悉 OpenHarmony 能力的同学主干代码是非常重要的资源,在主干代码的 applications 目录里聚集了很多原生的应用实现,那么如何编译这些代码就是我们这篇文章的主要议题。 使用 DevEco 导

    2024年04月12日
    浏览(37)
  • OpenHarmony源码学习之编译构建

    云将东游,过扶摇之枝,而适遭鸿蒙。—《庄子·在宥》 OpenHarmony是由开放原子开源基金会(OpenAtom Foundation)孵化及运营的开源项目,目标是面向全场景、全连接、全智能时代、基于开源的方式,搭建一个智能终端设备操作系统的框架和平台,促进万物互联产业的繁荣发展。

    2024年02月04日
    浏览(47)
  • 【鸿蒙系统】 ---OpenHarmony加快本地编译(二)

    💌 所属专栏:【鸿蒙系统】 😀 作  者:我是夜阑的狗🐶 🚀 个人简介:一个正在努力学技术的CV工程师,专注基础和实战分享 ,欢迎咨询! 💖 欢迎大家:这里是CSDN,我总结知识的地方,喜欢的话请三连,有问题请私信 😘 😘 😘   大家好,又见面了,我是夜阑的

    2024年04月26日
    浏览(46)
  • OpenHarmony 4.0 Release 编译异常处理

    编译环境:Ubuntu 20.04 OpenHarmony 软件版本:4.0 Release 设备平台:rk3568 参考官网步骤: OpenHarmony 4.0 Release 源码获取 参考官网构建步骤: v4.0 Release 编译构建 如果上述步骤一切顺利,编译通过,build log如下: 下拉代码执行报错 unable to resolve “fork_flow”\\\" 表明repo工具无法解析名为

    2024年02月05日
    浏览(51)
  • Docker 编译OpenHarmony 4.0 release

    编译环境:Ubuntu 20.04 OpenHarmony版本:4.0 release 平台设备:RK3568 OpenHarmony 3.2更新至OpenHarmony 4.0后,公司服务器无法编译通过,总是在最后几十个文件时报错,错误码4000: 经分析尝试: 1、相同的步骤和命令,wsl2 编译OpenHarmony 4.0 r正常。 2、服务器使用sudo编译正常,但由于sudo使

    2024年02月03日
    浏览(49)
  • OpenHarmony-4.0-Release 源码编译记录

    本文基于 Ubuntu 20.04.4 LTS 这个没啥好说的,都是搞机的,用之前编译 aosp 的 linux 环境就行,有小伙伴担心会把之前的环境搞崩, 也有用 docker 编译的,我这里就直接在 aosp 环境下搞了,还省事。 安装下面这三东西,是为了下载 Harmony 源码 sudo apt install curl sudo apt install python3

    2024年02月05日
    浏览(54)
  • OpenHarmony下musl编译工具链普法

    欠的债总是要还的,这不前面欠的关于OpenHarmony下musl相关的还是要还的。这里我对其中的相关知识点,梳理,归纳重新消化下! 说实话,这块我现在都木有搞清楚,GCC/Clang/LLVM之间的区别与联系!这里只能硬着头皮,捡一捡网上各路大神的总结,先理解一波有个基本概念! 先

    2024年04月14日
    浏览(32)
  • OpenHarmony 4.0 源码编译hb 问题排查记录

    OS:Ubuntu 22.04 x86_64 下载好Openharmony 4.0Beta2 的源码 从错信息看是找到某个目录,hb 是python写的,所以打算看看源码是找个目录出错了,根据出错信息直接看源码文件。 查看python 代码可知报错原因是没找到 build/lite/hb_internal ,在OpenHamony 源码下确实没有发现有 build/lite/hb_internal

    2024年02月09日
    浏览(45)
  • OpenHarmony鸿蒙源码下载编译和开发环境搭建

    目录 一、开发环境搭建和源码下载 二、编译 三、总结  一、开发环境搭建 最好是在如Ubuntu18.04以上的系统中搭建,不然有些软件依赖需要解决,加大搭建时间 如gitee中开源OpenHarmony中的文档所示,搭建开发环境,搭建文档网站如下: zh-cn/device-dev/get-code/sourcecode-acquire.md ·

    2024年01月21日
    浏览(63)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包