社区编辑申请
注册/登录
openharmony南向研究-编译架构和编译框架之二
系统 OpenHarmony
我认为这部分作为这个系列第二章的原因是必须要了解openharmony的各个子系统的通用构建方式和原理在进行新的子系统开发时会减少很多阻碍更加流畅开发。

??想了解更多关于开源的内容,请访问:??

??51CTO 开源基础软件社区??

??https://ost.51cto.com??

综述

openharmony的编译构架系统基于系统的设计初衷和一些基本特性,包括微内核和可拆分性,针对不同的子系统使用着不同的构建方式和构建单元,目前在代码中可以看到主要分为以前使用的make方式来构建gcc,以及目前正在迭代和加入的gn和ninja编译方案。对于编译这一块我不是非常了解,但是我认为这部分作为这个系列第二章的原因是必须要了解openharmony的各个子系统的通用构建方式和原理在进行新的子系统开发时会减少很多阻碍更加流畅开发。

参考文献

??浅析鸿蒙中的 Gn 与 Ninja(一)-开源基础软件社区-51CTO.COM??唐老师写的这一篇虽然是系列中唯一一篇,但是给了人很大启发

GN与Ninja

GN与Ninja简介

很多人使用过一些常用的构建工具,如我们熟知的c++相关的makefile,cmake,java中相关的,ant,maven,gradle等等他们的作用都是一种将源码生成可执行应用程序的自动化过程工具,构建包括了编译链接和代码打包为可执行文件。

其实openharmony的整套系统也是需要进行构建,而且是被划分为一个一个的子系统进行编译的,而更具体到代码则是通过gn脚本对应模块来实现的。

gn和ninja的历史来源于Google Chrome 项目,为了提高大体量系统级代码的编译构建速度才设计使用的。

ninja是直接接触到工程文件的部分,gn是用来描述并生成ninja文件的方式。

  • 子系统 子系统是一个逻辑概念,它由一个或多个具体的组件组成。OpenHarmony整体遵从分层设计,从下向上依次为:内核层、系统服务层、框架层和应用层。系统功能按照“系统 > 子系统 > 组件”逐级展开,在多设备部署场景下,支持根据实际需求裁剪某些非必要的子系统或组件。
  • 华为给出了命令行工具hb(openharmony Build),这是结合了gn和ninja构建工具的构建系统,但是目前对于ohos.build文件的理解和书写还是停留在注册一个模组的程度,其他的一些配置和参数还没有查到具体的写法。

GN与ninja的关系以及用法和语法深入讲解

ninja是直接接触到工程文件的部分,gn是用来描述并生成ninja文件的方式。在其他的项目工程中如果gcc,cmake用多了厌烦了,直接使用gn和ninja也是个有趣的尝试。

Gn和ninja与openharmony的结合

Gn用于生成ninja且可以在全局目录下递归查找子Gn文件进行联合构建,最终通过ohos的hb编译脚本ohos.build进行总体解释,再将生成的动态链接库或者动态依赖库绑定在全局(通过harmonyos\build\subsystem_config.json添加模组进行绑定)。

真实案例 在openharmony中添加一个子模组的流程

必要参考文献

??docs/标准系统如何添加一个模块.md · OpenHarmony/build - Gitee.com??。

实现流程

通过Hi3516Dv300实现一个napi接口子系统的过程,代码测试正常,跟着流程做即可,解析会在后面几篇文章中给出。

在harmonyos目录下新建demo目录。

  • 建立子目录
  • |-- BUILD.gn
  • |-- demo.cpp
  • |-- ohos.build
  • 填写每个文件,复制粘贴即可

BUILD.gn

 import("//build/ohos.gni")
ohos_shared_library("demo") {
sources = [
"demo",
]
deps = [ "//foundation/ace/napi:ace_napi" ]
relative_install_dir = "module"
subsystem_name = "demo"
part_name = "demo_part"
}

由此编译完成后会产生一个动态链接库,位置在out/system/lib/module/libdemo.z.so。

ohos.build

{
"subsystem": "demo",
"parts": {
"demo_part": {
"module_list": [
"//demo:demo"
],
}
}
}

demo.cpp

#include <assert.h>
#include "napi/native_api.h"
#include "napi/native_node_api.h"
static napi_value Method(napi_env env, napi_callback_info info) {
napi_status status;
napi_value str;
status = napi_create_string_utf8(env, "NAPI!", 256, &str);
assert(status == napi_ok);
return world;
}
static napi_value Init(napi_env env, napi_value exports) {
napi_status status;
napi_property_descriptor desc[] = {
DECLARE_NAPI_FUNCTION("demo", Method),
};
status = napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
assert(status == napi_ok);
return exports;
}
NAPI_MODULE(demo, Init)

接下来把子系统进行绑定。

到达openharmony/build/subsystem_config.json。

 "demo": {
"project": "hmf/demo",
"path": "demo",
"name": "demo",
"dir": ""
}

紧接着到达openharmony/productdefine/common/products/Hi3516Dv300添加到产品输出目录中作为子系统。

最终在out/ohos-arm-release/packages/phone/images/ 中可以找到刚刚提到的动态链接库,在通过hdc工具烧录到系统中,或者直接烧录整个镜像,在北向代码中即可进行测试,或者用logconsloe工具可以测试结果

(因为时间比较紧张没时间写新的去测试,这是项目中测过的改了一下显示的东西,后面会更新V2的时候更换新的样例)

gn和ninja的基础语法和命令,参考文档,以及一个小训练

  1. 交叉编译 :参考 cross_compile.md
  2. gn官网:??gn - Git at Google (googlesource.com)??。
  3. 语法:??v60.04 鸿蒙内核源码分析(gn应用) | 如何构建鸿蒙系统 | 百篇博客分析OpenHarmony源码 - 知乎 (zhihu.com)??。
  4. BUILD,gn 的写法直接从第三篇搬运过来的,为了避免有些人懒得点开一个一个去看。
#目的是要得到项目各个模块的编译入口
group("ohos") {
deps = []
if (ohos_build_target == "") {
# Step 1: Read product configuration profile.
# 第一步:读取配置文件product_path的值来源于根目录的ohos_config.json,如下,内容由 hb set 命令生成
# {
# "root_path": "/home/openharmony",
# "board": "hispark_aries",
# "kernel": "liteos_a",
# "product": "ipcamera_hispark_aries",
# "product_path": "/home/openharmony/vendor/hisilicon/hispark_aries",
# "device_path": "/home/openharmony/device/hisilicon/hispark_aries/sdk_liteos",
# "patch_cache": null
#}
product_cfg = read_file("${product_path}/config.json", "json")

# Step 2: Loop subsystems configured by product.
# 第二步:循环处理各自子系统,config.json中子系统部分格式如下hb
#"subsystems": [
# {
# "subsystem": "aafwk",
# "components": [
# { "component": "ability", "features":[ "enable_ohos_appexecfwk_feature_ability = false" ] }
# ]
# },
# ...
# {
# "subsystem": "distributed_schedule",
# "components": [
# { "component": "system_ability_manager", "features":[] },
# { "component": "foundation", "features":[] },
# { "component": "distributed_schedule", "features":[] }
# ]
# },
# {
# "subsystem": "kernel",
# "components": [
# { "component": "liteos_a", "features":[] }
# ]
# },
#]
foreach(product_configed_subsystem, product_cfg.subsystems) {#对子系统数组遍历操作
subsystem_name = product_configed_subsystem.subsystem #读取一个子系统 aafwk,hiviewdfx,security ==
subsystem_info = {
}
# Step 3: Read OS subsystems profile.
# 第三步: 读取各个子系统的配置文件
subsystem_info =
read_file("//build/lite/components/${subsystem_name}.json", "json")

# Step 4: Loop components configured by product.
# 第四步: 循环读取子系统内各控件的配置信息
# 此处以内核为例://build/lite/components/kernel.json"
# "components": [
# {
# "component": "liteos_a", # 组件名称
# "description": "liteos-a kernel", # 组件一句话功能描述
# "optional": "false", # 组件是否为最小系统必选
# "dirs": [ # 组件源码路径
# "kernel/liteos_a"
# ],
# "targets": [ # 组件编译入口
# "//kernel/liteos_a:kernel"
# ],
# "rom": "1.98MB", # 组件ROM值
# "ram": "", # 组件RAM估值
# "output": [ # 组件编译输出
# "liteos.bin"
# ],
# "adapted_board": [ # 组件已适配的主板
# "hispark_aries",
# "hispark_taurus",
# "hi3518ev300",
# "hi3516dv300",
# ],
# "adapted_kernel": [ "liteos_a" ], # 组件已适配的内核
# "features": [], # 组件可配置的特性
# "deps": {
# "components": [], # 组件依赖的其他组件
# "third_party": [ # 组件依赖的三方开源软件
# "FreeBSD",
# "musl",
# "zlib",
# "FatFs",
# "Linux_Kernel",
# "lwip",
# "NuttX",
# "mtd-utils"
# ]
# }
# },
# ]
foreach(product_configed_component,
product_configed_subsystem.components) { #遍历项目控件数组
# Step 5: Check whether the component configured by product is exist.
# 第五步: 检查控件配置信息是否存在
component_found = false #初始为不存在
foreach(system_component, subsystem_info.components) {#项目控件和子系统中的控件遍历对比
if (product_configed_component.component ==
system_component.component) { #找到了liteos_a
component_found = true
}
}
#如果没找到的信息,则打印项目控件查找失败日志
assert(
component_found,
"Component \"${product_configed_component.component}\" not found" +
", please check your product configuration.")

# Step 6: Loop OS components and check validity of product configuration.
# 第六步: 检查子系统控件的有效性并遍历控件组,处理各个控件
foreach(component, subsystem_info.components) {
kernel_valid = false #检查内核
board_valid = false #检查开发板
# Step 6.1: Skip component which not configured by product.
if (component.component == product_configed_component.component) {
# Step 6.1.1: Loop OS components adapted kernel type.
foreach(component_adapted_kernel, component.adapted_kernel) {
if (component_adapted_kernel == product_cfg.kernel_type &&
kernel_valid == false) { #内核检测是否已适配
kernel_valid = true
}
}
# 如果内核未适配,则打印未适配日志
assert(
kernel_valid,
"Invalid component configed, ${subsystem_name}:${product_configed_component.component} " + "not available for kernel: ${product_cfg.kernel_type}!")
# Step 6.1.2: Add valid component for compiling.
# 添加有效组件进行编译
foreach(component_target, component.targets) {//遍历组件的编译入口
deps += [ component_target ] #添加到编译列表中
}
}
}
}
}
# Step 7: Add device and product target by default.
# 第七步: 添加设备和项目的编译单元
# "product_path": "/home/openharmony/vendor/hisilicon/hispark_aries",
# "device_path": "/home/openharmony/device/hisilicon/hispark_aries/sdk_liteos",
deps += [
"${device_path}/../", #添加 //device/hisilicon/hispark_aries 进入编译项
"${product_path}" #添加 //vendor/hisilicon/hispark_aries 进入编译项
]
} else {#编译指定的组件,例如 hb build -T targetA&&targetB
deps += string_split(ohos_build_target, "&&")
}
}

5.必须要提及的点和要指出的问题。

在总体的设计中注册一个子模块的步骤讲的挺清楚了,那么我们对于刚刚的一些最常用的gn语法分析和讲解一下。

mport("//drivers/adapter/uhdf2/uhdf.gni")
import("//build/ohos.gni")

ohos_shared_library("demo") {
# 指定编译源文件
include_dirs = [ # 模块依赖头文件目录
"include/"
]
sources = [
"demo.cpp",
]
# 指定编译依赖,如果依赖第三方库,需要在此添加
deps = [ "//foundation/ace/napi:ace_napi" ]
# 指定库生成的路径
relative_install_dir = "module"
# 子系统及其组件,后面会引用
subsystem_name = "demo"
part_name = "demo_part"
}

ohos_executable("hello") {
include_dirs = [ # 模块依赖头文件目录
"//base/compileruntime/js_util_module/util",
"//ark/js_runtime",
"//foundation/ace/napi",
"//foundation/ace/napi/interfaces/kits",
"//foundation/ace/napi/native_engine",
"//foundation/ace/napi/native_engine/impl/ark",
"//third_party/icu/icu4c/source/common",
"//third_party/googletest/include",
"//third_party/node/src",
"//utils/native/base/include",
"include/"
]
sources = [
"hello.c"
]
deps = [ "//foundation/ace/napi:ace_napi",
"//ark/js_runtime:libark_jsruntime",
"//base/compileruntime/js_util_module/util:util_packages",
"//foundation/ace/napi/:ace_napi",
"//foundation/ace/napi/:ace_napi_ark",
"//third_party/icu/icu4c:static_icuuc",
"//third_party/libuv:uv_static",
"//utils/native/base:utils",
"//utils/native/base:utilsecurec", ]
# 子系统及其组件,后面会引用


subsystem_name = "applications"
part_name = "prebuilt_hap"
}

这部分是我在项目中使用,在一个子系统(subsystem)中注册两个模组,一个是ohos_executable–hello,另外一个是ohos_shared_librarydemo。

分别有一些子选项需要填写:

  • include_dirs --存放头文件。
  • sources — 存放源文件。
  • deps—指定依赖。

其他的部分都有注释,有人可能会问这些的详细参数表在哪里去找,答案是目前只能在各个子系统的gn里去翻,我这边还没找到更有效的参考文献。

??想了解更多关于开源的内容,请访问:??

??51CTO 开源基础软件社区??

??https://ost.51cto.com??。

责任编辑:jianghua 来源: 鸿蒙社区
相关推荐

2022-04-02 20:45:04

Hi3516开发板操作系统鸿蒙

2022-04-15 14:31:02

鸿蒙操作系统

2022-04-20 20:28:40

HDF 驱动框架鸿蒙操作系统

2022-04-07 15:28:16

HarmonyOS鸿蒙操作系统

2022-04-01 15:18:04

HarmonyHDF 驱动鸿蒙

2022-04-14 10:10:59

Nginx开源Linux

2022-04-11 13:57:38

HarmonyRelease操作系统

2022-04-21 10:01:48

VMware

2022-04-18 10:37:01

鸿蒙操作系统开发工具

2022-04-07 14:33:31

操作系统鸿蒙HarmonyOS

2022-04-21 11:26:31

鸿蒙操作系统

2022-04-12 11:35:43

IDE工具OHOS应用鸿蒙

2022-04-25 09:10:50

RK3568鸿蒙

2022-04-08 11:08:17

分布式数据接口同步机制

2022-03-02 16:08:31

Harmony应用开发鸿蒙

2022-04-19 11:23:26

release3.1子系统鸿蒙

2022-04-06 11:27:05

harmonyeTS 开发NAPI开发

2022-04-21 14:05:21

开发者论坛

2022-04-12 12:06:49

智能小车Wi-Fi IoT鸿蒙

2022-04-01 15:26:06

Harmony操作系统鸿蒙

同话题下的热门内容

OpenHarmony啃论文俱乐部—大数据框架性能优化系统OpenEuler-22.03-LTS+UKUI如何快速在AARCH64架构运行与体验OpenHarmony—分区切换之Reboot源码解析HarmonyOS Connect设备开发--抛除束缚,自定义设备UIOpenHarmony驱动框架HDF中设备管理服务构建过程详解之一如何在DAYU200上安装浏览器-基于OpenHarmony 3.1 Release版本HarmonyOS - Java与Js的混合使用与交互OpenHarmony啃论文俱乐部——物联网摇摆门趋势算法

编辑推荐

HarmonyOS 2.0鸿蒙第二期开发者Beta公测申请指南HarmonyOS LYEVK-3861开发板播放《蜜雪冰城》鸿蒙HarmonyOS分布式软总线:构建低时延、高带宽的多设备虚拟网络华为HarmonyOS的强势突围: 直面物联网迷宫的蓄力进击鸿蒙HarmonyOS2.0发布会现场回忆录
我收藏的内容
点赞
收藏

51CTO技术栈公众号

网站地图 申博娱乐开户 菲律宾申博开户 澳门新葡京赌场 太阳城娱乐登入
菲律宾太阳娱乐网址登入 www.msc66.com www.sbc66.com 菲律宾申博游戏怎么登入
申博游戏注册 申博现金百家乐 菲律宾太阳城申博 申博现金百家乐
申博官网登录 网上百家乐 菲律宾申博娱乐 百家乐
百家乐真人游戏 申博游戏网址 澳门新葡京赌场 申博娱乐手机登入