0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

深度解析鸿蒙系统的编译流程

鸿蒙系统HarmonyOS 来源:HarmonyOS社区 作者:liangkz 2021-04-23 17:04 次阅读

1.准备工作

我的本地代码是基于最新发布的OpenHarmony 1.1.0 LTS(2021-04-01)版本抓取的,代码根目录OHOS1_1_0LTS:

$repo init -u https://gitee.com/openharmony/manifest.git -b refs/tags/OpenHarmony_release_v1.1.0 --no-repo-verify

$repo sync

我还有Hi3861_Wifiiot开发板和开发环境,如下:

Linux环境下的DecEco IDE下创建新工程“Test_Wifiiot”,在“HPM”标签下找到“@ohos/wifi_iot”,点击“Install to project”选择“Test_Wifiiot”项目,开始下载并安装组件到项目里。

2.全编译+模块编译

2.1 OHOS1_1_0LTS的全代码编译

在代码根目录下执行:

OHOS1_1_0LTS$hb set

[OHOS INFO] Input code path:.

OHOS Which product do you need?

ipcamera_hispark_pegasus@hisilicon

->ipcamera_hispark_taurus@hisilicon

ipcamera_hispark_aries@hisilicon

这一步完成后,会在代码根目录下生成“ohos_config.json”文件,然后就可以开始编译了:

OHOS1_1_0LTS$hb build

OHOS1_1_0LTS$python build.py

OHOS1_1_0LTS$python build.py -p ipcamera_hispark_taurus@hisilicon

效果都是一样的。

第一次全编译了2491个文件,以后再操作上面的命令就不是全编译了,只编译需要编译的部分。

2.2 Test_Wifiiot项目的全编译

新下载的项目代码根目录下并没有“build.py”文件。

$hb set

会生成“ohos_config.json”,但没有完成配置,hb build 会失败。

可以执行

$ln -s ./build/lite/build.py build.py

创建build.py的软链接,再执行

$python build.py wifiiot

就可以正常编译了。

Test_Wifiiot项目还可以用DevEco IDE进行一键编译,操作步骤见官方的文档:

https://device.harmonyos.com/cn/docs/ide/user-guides/service_introduction-0000001050166905

2.3 OHOS1_1_0LTS的组件/仓库/Target编译

一开始,关于模块编译,我在网上搜到了:

HarmonyOS单模块编译与源码导读》(Link: https://harmonyos.51cto.com/posts/3094 )

这篇文章(下文简称《导读》),仔细阅读,并对比本地代码OHOS1_1_0LTS查看了build\lite目录下,并没有上文所提到的compile.py文件和product目录,这个可能是鸿蒙系统迭代更新版本给拿掉了。

查看OHOS1_1_0LTS\build\lite目录下的README_zh.md,虽然看到增加了-T的说明:

-T[TARGET [TARGET ...]], --target [TARGET [TARGET ...]]

Compile single target

但没做进一步使用说明,因为对鸿蒙的编译系统还没多少了解,我还是不大清楚如何使用操作。

官方文档“轻量和小型系统编译构建指导”:

https://device.harmonyos.com/cn/docs/develop/subsystems/oem_subsys_build_des-0000001060646620

可能没有更新,甚至没有对“-T”参数的描述。

不过官方文档中“组件描述位于build/lite/components下”这句话倒提醒了我,去里面看了一下,

原来这就是鸿蒙系统所有组件描述文件的存放位置,每个组件文件内又有多个【组件和target】的描述。

打开“applications.json”看一下,这里就有上面《导读》提到的东西:

"component": "camera_sample_app",

"description": "Camera related samples.",

"optional": "true",

"dirs": [

"applications/sample/camera/launcher",

"applications/sample/camera/cameraApp",

"applications/sample/camera/setting",

"applications/sample/camera/gallery",

"applications/sample/camera/media"

],

"targets": [

"//applications/sample/camera/launcher:launcher_hap",

"//applications/sample/camera/cameraApp:cameraApp_hap",

"//applications/sample/camera/setting:setting_hap",

"//applications/sample/camera/gallery:gallery_hap",

"//applications/sample/camera/media:media_sample"

],

赶紧操作一下:

OHOS1_1_0LTS$hb build -T //applications/sample/camera/launcher:launcher_hap

编译OK,不过时间还是有点长

官方文档说“组件即为gn中的编译单元,可以为静态库、动态库或可执行文件。”

编译构建流程图上也是写 hb build [component]

OHOS1_1_0LTS$hb build camera_sample_app

编译OK,但感觉与target编译以及最上面hb build是一样的效果~~

我还在OHOS1_1_0LTS\applications\sample\camera\README_zh.md 文档中看到对媒体子系统组件的使用说明:

单仓的编译构建,在根目录下进行单仓的构建和编译

# 开发板选择

hb set

# 单仓构建和编译

hb build camera_lite

再查看一下build\lite\components\multimedia.json,原来单仓编译就是组件编译,而Target编译,实际上看起来又与组件编译差别不大,有些组件本身就是一个target,有些组件分多个target。

"component": "camera_lite",

"description": "Camera service.",

"optional": "true",

"dirs": [

"foundation/multimedia/camera_lite",

"foundation/multimedia/utils/lite/hals"

],

"targets": [

"//foundation/multimedia/camera_lite/frameworks:camera_lite"

],

小结:

鸿蒙系统所有组件描述文件的存放在build/lite/components/目录下,每个组件文件内又有多个组件和target的描述。

组件/仓库编译指令:

$hb build component_name

Target编译指令(可一次编译多个target,用&&连接):

$hb build -T target_name

$hb build -T target1_name&&target2_name

3.编译系统build目录结构

首先必须要仔细研读 build\lite\README_zh.md 文档,文档上没有的地方,我这里补充一下我的理解,做成表格更容易管理。这个表格会在以后学习过程中根据新的理解做更新。

o4YBAGCCi4mAUxJbAARWz09jTsk784.png

4.编译结果out目录结构

o4YBAGCCi6yAecNCAAQme0sj10k469.png

pIYBAGCCi7yAB7RvAAKgLJSoqfU618.png

打开“os-release”文件查看:

VERSION="OpenHarmony 1.0"

RELEASE_TIME="2021-04-18 07:38:53"

分别是鸿蒙系统的版本号,和当次编译(内核?系统?)的时间

5.构建系统Gn+Ninja
在学习鸿蒙之前,我对Gn/Ninja并不了解,只是知道有这么个东西,因为用不到所以也没有去学习的动力。

这几天因为想深入了解一下鸿蒙的编译系统,就通过网络资源简单学习了一下,也只是知道了个大概,我看到的资料里觉得比较好的,有如下链接:

首先最重要的“gn help ”和官方文档“The Ninja build system”,随用随查。

【下文中对gn定义的关键字不再解释,请自行随时 gn help。】

《浅析鸿蒙中的Gn和Ninjia(一)》

Link: https://harmonyos.51cto.com/posts/2972

《HarmonyOS 2.0研究(1) -环境搭建及编译过程分析》【强烈推荐】【本文内简称为《过程分析》】

Link:https://my.oschina.net/u/2502829/blog/4613535

《#2020征文-开发板#鸿蒙liteos-a如何启动第一个用户进程init_lite》【本文内简称为《如何启动init_lite》】

Link:https://harmonyos.51cto.com/posts/1998#bkwz

《GN语法和操作》

Link:https://blog.csdn.net/yujiawang/article/details/72627138

为了快速理解Gn+Ninja是如何工作的,我自己做了一个 GnHelloWorld工程来做测试和验证,源代码放在gitee上:

https://gitee.com/liangkzgitee/GnProjs.git

压缩包也添加在本文附件里,请大家按readme.txt文档操作,逐步进行跟踪和分析。

readme.txt 文档内容如下:

这是一个最简单的Gn+Ninja构建系统的例子工程,通过这个简单的工程和下面的操作,

学习Gn+Ninja构建系统是如何构建编译我们的源代码的。

原始工程目录如下:

GnHelloWorld/ #工程根目录

├──build/ #编译构建主目录

│ └──config/ #编译相关的配置项

│ ├──toolchans/ #编译工具链相关

│ │ └──BUILD.gn #编译选项、链接选项等等

│ └──BUILDCONFIG.gn #指定默认编译工具链

├──src/ #源代码目录

│ ├──BUILD.gn #(*)

│ └──hello.c #(*)源代码

├──.gn #Gn构建系统入口

├──BUILD.gn #

└──Readme.txt #(*)本文

Step1:

在"GnHelloWorld"目录下执行:"gn gen out"命令后,会生成一个"out"目录,

GnHelloWorld/

├──......[略]

├──out/

│ ├──obj/

│ │ └──src/

│ │ └──hello.ninja #编译hello.c的ninja脚本

│ ├──args.gn #构建参数

│ ├──build.ninja

│ ├──build.ninja.d

│ └──toolchain.ninja

├──......[略]

Step2: [建议操作这步之前,先备份out目录,如: "cp -r out out_bak"]

在"GnHelloWorld"目录下执行: "ninja -C out",会在out目录下生成

GnHelloWorld/

├──......[略]

├──out_bak/ #Step1 的 out 目录的副本

│ ├──obj/

│ │ └──src/

│ │ └──hello.ninja

│ ├──args.gn

│ ├──build.ninja

│ ├──build.ninja.d

│ └──toolchain.ninja

├──out/ #out目录有更新,见#

│ ├──obj/

│ │ ├──src

│ │ │ ├──hello.ninja

│ │ │ └──hello.o #编译链工具根据规则生成的 .o

│ │ └──all.stamp #

│ ├──.ninja_deps #

│ ├──.ninja_log #

│ ├──args.gn

│ ├──build.ninja

│ ├──build.ninja.d

│ ├──hello #编译后生成的可执行文件

│ └──toolchain.ninja

├──......[略]

Step3:

在"GnHelloWorld"目录下执行: 执行"./out/hello",输出"Hello Gn World!"

Step1做了如下工作:

1.执行gn gen 时带的参数被记录下来,生成out/args.gn【本例不带args参数】

2.找到 “.gn”文件并将其所在的目录设为“souce root”,解析该文件以获取buildconfig。

3.执行buildconfig所指向的文件BUILDCONFIG.gn,设置一个默认的编译工具链,

生成out/toolchain.ninja。

4.加载“souce root”目录下的“BUILD.gn”文件,根据其内容加载它依赖的其它

目录下的BUILD.gn文件,生成out/build.ninja.d。

5.根据out/build.ninja.d中各个BUILD.gn的内容,递归解决各自的依赖关系,

解决掉依赖关系之后,就在out/obj/对应目录下,生成“.ninja”,

如例子中的“out/obj/src/hello.ninja”。

6.解决掉所有的依赖关系后,在out/目录下生成一个“build.ninja”。

Step2做了如下工作:

根据上面的.ninja文件所定义的规则和依赖关系,依次编译出各自的中间文件,

最终生成可执行文件“out/hello”。

理解了上面的东西之后,你就可以开始进一步学习更复杂的东西了,可以参考Gn的官方文档,

或者网络上的其它资源,自己动手做验证。

6.编译流程分析

我们repo/sync完整个鸿蒙代码后,要编译系统,一般做以下三步:

1. 首次编译,需要首先 hb set

2. 首次编译,hb build 会启动全编译

3. 修改某个文件,比如 init_lite 的main 文件main函数加行log,再次编译 hb build或者hb build init_lite。

这三步操作,鸿蒙的编译系统都做了哪些具体工作?

带着这个疑问,我希望能够抽丝剥茧,一步一步来确认,可能中间会有暂不理解的,先跳过,未来再做进一步完善。

可惜目前我对python的了解也不多,无法对相关脚本做非常详细的分析,对Gn构建系统的理解也还不够深入,无法给出理想的分析结果,所以只能先把我现在知道的写下来,以后学习过程中逐步补充完善。

6.1设置环境hb set

【查看/build/lite/README_zh.md】

设置OpenHarmony源码目录和要编译的产品,在代码根目录生成“ohos_config.json”文件。

具体 hb set命令怎么调用/build/lite/hb/目录下的相关脚本,再结合系统环境变量$PATH等相关必要信息来生成这个.json文件的,懂python的可以进去看一下。

打开“ohos_config.json”文件查看:

{

"root_path": "/home/lkz/Work/OHOS1_1_0LTS",

"board": "hispark_taurus",

"kernel": "liteos_a",

"product": "ipcamera_hispark_taurus",

"product_path": "/home/lkz/Work/OHOS1_1_0LTS/vendor/hisilicon/hispark_taurus",

"device_path": "/home/lkz/Work/OHOS1_1_0LTS/device/hisilicon/hispark_taurus/sdk_liteos"

}

这些将作为非常重要的参数交给下一步编译使用。

6.2全编译hb build
【查看/build/lite/README_zh.md】

编译产品、开发板或者组件。解决方案编译实现如下:

A. 读取开发板配置:主要包括开发板使用的编译工具链、编译链接命令和选项等。

B. 调用gn: 调用gn gen命令,读取产品配置(主要包括开发板、内核、选择的组件等)生成解决方案out目录和ninja文件。

C. 调用ninja:调用ninja -C out/company/product启动编译。

D. 系统镜像打包:将组件编译产物打包,制作文件系统镜像。

说的很“框架”,下面我们一步一步来看一下。

A. 检测/读取/配置所有的必要参数
包括但不限于以下列出来的几个文件:

ohos_config.json

Build\lite\ohos_var.gni 定义使用于所有组件的全局变量

device\hisilicon\hispark_pegasus\sdk_liteos\config.gni 这是编译LiteOS_A内核所需要用到的配置

vendor\hisilicon\hispark_taurus\config.json 这是hisilicon提供的产品全量配置表:子系统、组件列表等等

通过hb build传进去的参数,比如 -n 表示编译NDK,则会将ohos_build_ndk变量由默认的FALSE改为TRUE。

B. 调用gn gen命令生成out目录和ninja文件
很复杂,也很简单。

复杂是中间涉及到太多的Python和Gn语法,我暂时无法完整理解。

简单是因为我做过了上面的GnHelloWorld工程来做测试和分析,知道了框架。

更详细的分析过程,请看《过程分析》这篇文章。

下面是我对//build/lite/BUILD.gn这个文件中的 group("ohos") 的分解,最终得到"ohos"的完整的依赖关系:

o4YBAGCCi9eAYQr2AARXSLvEiCU897.png

pIYBAGCCi-WAKilMAASfWDFQ02I745.png

pIYBAGCCjGiASWF3AAM5uzkhKh8639.png

pIYBAGCCjIaAL_pBAAR7AS-AvRM556.png

C. 调用ninja启动编译

这里就开始根据上一步生成的 .ninja 文件里的规则调用编译工具链来编译各目录下的源文件了,生成 .o/.a/.so/可执行文件 等等,其中.so文件会先在out\hispark_taurus\ipcamera_hispark_taurus\目录下生成,等编译完之后会转移到out\hispark_taurus\ipcamera_hispark_taurus\libs\usr\目录下,还生成了.ninja_log和.ninja_deps文件。

编辑:hfy

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • Linux
    +关注

    关注

    87

    文章

    11136

    浏览量

    208095
  • 编译系统
    +关注

    关注

    0

    文章

    10

    浏览量

    8855
  • 鸿蒙系统
    +关注

    关注

    183

    文章

    2629

    浏览量

    65882
收藏 人收藏

    评论

    相关推荐

    鸿蒙系统编译完成

    1、按官方文档,(ubuntun16.04)鸿蒙系统已经编译完成
    发表于 09-14 16:06

    鸿蒙系统驱动程序的实现流程

    放入内核中9、具体驱动放入内容内核的实现流程10、修改hcs文件11、修改mk文件12、编写app13、获取服务14、分配HddBuf15、调用Dispatch函数16、取出数据17、把APP源码放入系统18、编译、烧写、测试1
    发表于 09-24 14:48

    鸿蒙系统是在什么系统编译?用的是什么编译器?

    想了解下鸿蒙系统是在什么系统编译?用的是什么编译器?
    发表于 09-27 09:04

    【HarmonyOS】鸿蒙系统介绍 和 编译环境搭建

    ://device.harmonyos.com/cn/docs/start/introduce/oem_quickstart_3861_build-0000001054781998 。目前鸿蒙系统的开发方式是在Linux系统上面
    发表于 10-20 11:19

    使用语音控制的鸿蒙小车开发流程

    之前我们已经有一篇文章讲了如何驱动鸿蒙小车,通过网络控制小车的运行。基于鸿蒙系统 + Hi3861 的wifi小车,可以通过电脑、手机控制:这一篇我们来试点不一样的:使用语音控制鸿蒙
    发表于 11-24 14:38

    使用语音控制的鸿蒙小车开发流程

    之前我们已经有一篇文章讲了如何驱动鸿蒙小车,通过网络控制小车的运行。基于鸿蒙系统 + Hi3861 的wifi小车,可以通过电脑、手机控制:这一篇我们来试点不一样的:使用语音控制鸿蒙
    发表于 12-02 16:58

    鸿蒙芯片Hi3861启动流程介绍

    1 系统总体启动如下所示: 2 在鸿蒙系统启动之前,主要由boot程序来引导的,boot程序类似电脑主板的bios,Hi3861的boot程序比较多,如下:3 Boot启动流程如下:4
    发表于 09-22 15:11

    5分钟深度解析鸿蒙基础架构,附原文档!

    材料可进一步了解:1)微内核和宏内核的差异,为什么鸿蒙选择微内核;2)方舟编译器的原理和作用,已经它所解决的核心技术问题。HarmonyOS鸿蒙操作系统的研发历程:微内核、方舟
    发表于 11-12 10:29

    简单看一下鸿蒙系统中u-boot代码的编译步骤流程

    u-boot在鸿蒙系统中的作用就不说了,这里只简单看一下鸿蒙系统中u-boot代码的编译步骤流程
    发表于 03-29 14:15

    鸿蒙系统编译流程及分析v1.0

    之后,你就可以开始进一步学习更复杂的东西了,可以参考Gn的官方文档,或者网络上的其它资源,自己动手做验证。 6.编译流程分析我们repo/sync完整个鸿蒙代码后,要编译
    发表于 04-07 10:40

    鸿蒙系统编译相关资料下载

      因为新接触鸿蒙系统的开发,我对鸿蒙编译系统基本上没什么理解,都是凭着经验和百度一边学习一边总结的,本文是我在学习网上关于
    发表于 04-07 15:09

    C语言深度解析

    C语言深度解析,本资料来源于网络,对C语言的学习有很大的帮助,有着较为深刻的解析,可能会对读者有一定的帮助。
    发表于 09-28 07:00

    鸿蒙系统黄金搭档方舟编译器2.0:实现多语言多设备编译

    在今天的华为HDC 2020开发者大会上,除了鸿蒙2.0系统之外,华为还推出了方舟编译器2.0,这是去年首发方舟编译器之后的升级版。
    的头像 发表于 09-10 16:54 3278次阅读

    鸿蒙系统用什么语言 华为方舟编译器原理图分析

    的硬件设备,开发者在上面开发应用相对来说也会更简单一些。 鸿蒙系统用什么语言 根据华为公布的方舟编译器资料 可以推测鸿蒙系统是用C、C++语
    的头像 发表于 04-16 10:42 6206次阅读
    <b class='flag-5'>鸿蒙</b><b class='flag-5'>系统</b>用什么语言 华为方舟<b class='flag-5'>编译</b>器原理图分析

    一文解析鸿蒙系统诞生背景、技术细节生态圈

    操作系统上垄断地位的尝试必将成为中国科技史上的里程碑事件。 我们推荐兴业证券的报告《华为鸿蒙深度研究》, 从鸿蒙系统的产生背景、开源技术细节
    的头像 发表于 06-11 16:14 5884次阅读