构建的必要性

  • 前端开发有构建工具:GruntGulpWebpack
  • 后台开发有构建工具: MavenAntGradle

构建工具重要性不言而喻,它描述了整个工程的如何编译、连接,打包等规则,其中包括:工程中的哪些源文件需要编译以及如何编译、需要创建那些库文件以及如何创建这些库文件、如何最后输出我们想要的文件。

鸿蒙轻内核(L1/liteos)的编译构建工具是hb,hbohos-build的简称, 而ohos又是openharmony os的简称.

hb | ohos-build

hb通过以下命令安装,是用 python写的一个构建工具.

python3 -m pip install --user ohos-build

其源码在 ./build/lite 目录下,含义如下:

build/lite
├── components                  # 组件描述文件
├── figures                     # readme中的图片
├── hb                          # hb pip安装包源码
│   ├── build                   # hb build 命令实现
│   ├── clean                   # hb clean 命令实现
│   ├── common                  # 通用类, 提供 Device,Config,Product,utils 类
│   ├── cts                     # hb cts 命令实现
│   ├── deps                    # hb deps 命令实现
│   ├── env                     # hb env 命令实现
│   ├── set                     # hb set 命令实现
├── make_rootfs                 # 文件系统镜像制作脚本
├── config                      # 编译配置项
│   ├── component               # 组件相关的模板定义
│   ├── kernel                  # 内核相关的编译配置
│   └── subsystem               # 子系统编译配置
├── platform                    # ld脚本
├── testfwk                     # 测试编译框架
└── toolchain                   # 编译工具链配置,包括:编译器路径、编译选项、链接选项等

构建组成

鸿蒙构建系统由 python, gn, ninja, makefile几个部分组成,每个部分都有自己的使命,干自己最擅长的活.

  • python : 胶水语言,最擅长的是对参数,环境变量,文件操作,它任务是做好编译前的准备工作和为gn收集命令参数.不用python直接用gn行不行? 也行,但很麻烦.比如:直接使用下面的命令行也可以生成 .ninja文件,最后的效果是一样的.但相比只使用 hb build 哪个更香, hb build也会生成下面这一坨坨, 但怎么来是python的强项.
    /home/tools/gn gen /home/openharmony/code-v1.1.1-LTS/out/hispark_aries/ipcamera_hispark_aries \
    --root=/home/openharmony/code-v1.1.1-LTS \
    --dotfile=/home/openharmony/code-v1.1.1-LTS/build/lite/.gn \
    --script-executable=python3 \
    '--args=ohos_build_type="debug" ohos_build_compiler_specified="clang" ohos_build_compiler_dir="/home/tools/llvm" product_path="/home/openharmony/code-v1.1.1-LTS/vendor/hisilicon/hispark_aries" device_path="/home/openharmony/code-v1.1.1-LTS/device/hisilicon/hispark_aries/sdk_liteos" ohos_kernel_type="liteos_a" enable_ohos_appexecfwk_feature_ability = false ohos_full_compile=true'

图为绕过hb python部分直接执行gn gen 的结果:

  • gn : 类似构建界的高级语言,gn和ninja的关系有点像C和汇编语言的关系,与它对标的是cmake,它的作用是生成.ninja文件,不用gn直接用ninja行不行? 也行,但更麻烦.就跟全用汇编写鸿蒙系统一样,理论上可行,可谁会这么去干呢.
  • ninja:类似构建界的汇编语言,与它对标的是make,由它完成对编译器clang,链接器ld的使用.
  • makefile:鸿蒙有些模块用的还是make编译, 听说后面会统一使用ninja,是不是以后就看不到make文件了,目前是还有大量的make存在.

如何调试 hb

推荐使用vscode来调试,在调试面板点击 create a launch.json file创建调试文件,复制以下内容就可以调试hb了.

{
    "version": "0.2.0",
    "configurations": [
        {// hb set 
            "name": "hb set",
            "type": "python",
            "request": "launch",
            "program": "./build/lite/hb/__main__.py",
            "console": "integratedTerminal",
            "args": ["set"],
            "stopOnEntry": true
        },
        {//hb build
            "name": "hb build debug",
            "type": "python",
            "request": "launch",
            "program": "./build/lite/hb/__main__.py",
            "console": "integratedTerminal",
            "args": ["build"],
            "stopOnEntry": true
        },
        {//hb clean
            "name": "hb clean",
            "type": "python",
            "request": "launch",
            "program": "./build/lite/hb/__main__.py",
            "console": "integratedTerminal",
            "args": ["clean"],
            "stopOnEntry": true
        },
    ]
}

构建流程

编译构建流程图所示,主要分设置和编译两步:

本篇调试图中的 hb set | hb build 两个命令

hb set | 选择项目

源码见于: ./build/lite/hb/set/set.py
hb set执行的大致流程是这样的:

  • 你可以在任何目录下执行hb set, 它尝试读取当前目录下的 ohos_config.json配置文件,如果没有会让你输入代码的路径
    [OHOS INFO] Input code path: 

也就是源码根目录, 生成ohos_config.json配置文件,配置内容项是固定的,由Config类管理.

  • 可以在以下位置打上断点调试 set命令,跟踪整个过程.
    def exec_command(args):
        if args.root_path is not None:  
            return set_root_path(root_path=args.root_path)

        if args.product:
            return set_product()

        return set_root_path() == 0 and set_product() == 0

图为断点调试现场

  • 最后生成的配置文件如下:
      {
      "root_path": "/home/openharmony/code-v1.1.1-LTS",
      "board": "hispark_aries",
      "kernel": "liteos_a",
      "product": "ipcamera_hispark_aries",
      "product_path": "/home/openharmony/code-v1.1.1-LTS/vendor/hisilicon/hispark_aries",
      "device_path": "/home/openharmony/code-v1.1.1-LTS/device/hisilicon/hispark_aries/sdk_liteos",
      "patch_cache": null
      }

有了这些路径就为后续 hb build 铺好了路.

hb build | 编译项目

源码见于: ./build/lite/hb/build/*.py
建议大家去调试下源码,非常有意思,能看清楚所有的细节.本篇将编译工具中重要代码都加上了注解.

总体步骤是分两步:

  • 调用 gn_build 使用 gn gen生成 *.ninja 文件
  • 调用 ninja_build 使用 ninja -w dupbuild=warn -C 生成 *.o *.so *.bin 等最后的文件

gn_build
具体gn是如何生成.ninja文件的,后续有篇幅详细介绍其语法及在鸿蒙中的使用.

    #执行gn编译
    def gn_build(self, cmd_args):
        # Clean out path
        remove_path(self.config.out_path) #先删除out目录
        makedirs(self.config.out_path)    #创建out目录

        # Gn cmd init and execute ,生成 build.ninja, args.gn
        gn_path = self.config.gn_path
        gn_args = cmd_args.get('gn', [])
        gn_cmd = [gn_path,#gn的安装路径 ~/gn
                  'gen',
                  self.config.out_path, #/home/openharmony/out/hispark_aries/ipcamera_hispark_aries
                  '--root={}'.format(self.config.root_path), #项目的根例如:/home/openharmony
                  '--dotfile={}/.gn'.format(self.config.build_path),#/home/openharmony/build/lite/.gn -> root = "//build/lite"
                  f'--script-executable={sys.executable}',#python3
                  '--args={}'.format(" ".join(self._args_list))] + gn_args         
        #   ohos_build_type="debug"
        #   ohos_build_compiler_specified="clang"
        #   ohos_build_compiler_dir="/root/llvm"
        #   product_path="/home/openharmony/vendor/hisilicon/hispark_aries"
        #   device_path="/home/openharmony/device/hisilicon/hispark_aries/sdk_liteos"
        #   ohos_kernel_type="liteos_a" 
        #   enable_ohos_appexecfwk_feature_ability = false
        #   ohos_full_compile=true' 
        #   这些参数也将在exec_command后保存在 args.gn文件中
        exec_command(gn_cmd, log_path=self.config.log_path)#执行 gn gen .. 命令,在./out/hispark_aries/ipcamera_hispark_aries目录下生成如下文件 
        #   obj 子编译项生成的 ninja文件目录,例如:obj/base/global/resmgr_lite/frameworks/resmgr_lite/global_resmgr.ninja
        #   args.gn 各种参数, ohos_build_type="debug" ...
        #   build.ninja 子编译项 例如: build aa: phony dev_tools/bin/aa
        #   build.ninja.d 由那些模块产生的子编译项 例如:../../../base/global/resmgr_lite/frameworks/resmgr_lite/BUILD.gn
        #   toolchain.ninja 工具链 放置了各种编译/链接规则 rule cxx rule alink

ninja_build
关于ninja 的资料可以前往 ninja 参考手册 查看.
具体ninja是如何运行的,后续有篇幅详细介绍其语法及在鸿蒙中的使用.

    # ninja 编译过程
    def ninja_build(self, cmd_args):
        ninja_path = self.config.ninja_path

        ninja_args = cmd_args.get('ninja', [])
        ninja_cmd = [ninja_path,
                     '-w',
                     'dupbuild=warn',
                     '-C',
                     self.config.out_path] + ninja_args
        # ninja -w dupbuild=warn -C /home/openharmony/out/hispark_aries/ipcamera_hispark_aries 
        # 将读取gn生成的文件,完成编译的第二步,最终编译成 .o .bin 文件
        exec_command(ninja_cmd, log_path=self.config.log_path, log_filter=True)
        #生成以下部分文件 
        #NOTICE_FILE     OHOS_Image.bin  bin          build.ninja             config     etc             libs              obj               server.map  test_info             userfs
        #OHOS_Image      OHOS_Image.map  bm_tool.map  build.ninja.d           data       foundation.map  liteos.bin        rootfs.tar        suites      toggleButtonTest.map  userfs_jffs2.img
        #OHOS_Image.asm  args.gn         build.log    bundle_daemon_tool.map  dev_tools  gen             media_server.map  rootfs_jffs2.img  test        toolchain.ninja       vendor

exec_command | utils.py

gn_buildninja_build 最后都会调用 exec_command来执行命令,exec_command是个通用方法,见于
build/lite/hb/common/utils.py,调试时建议在这里打断点,顺瓜摸藤,跟踪相关函数的实现细节.

def exec_command(cmd, log_path='out/build.log', **kwargs):
    useful_info_pattern = re.compile(r'\[\d+/\d+\].+')
    is_log_filter = kwargs.pop('log_filter', False)

    with open(log_path, 'at', encoding='utf-8') as log_file:
        process = subprocess.Popen(cmd,
                                   stdout=subprocess.PIPE,
                                   stderr=subprocess.PIPE,
                                   encoding='utf-8',
                                   **kwargs)
        for line in iter(process.stdout.readline, ''):
            if is_log_filter:
                info = re.findall(useful_info_pattern, line)
                if len(info):
                    hb_info(info[0])
            else:
                hb_info(line)
            log_file.write(line)

    process.wait()
    ret_code = process.returncode

    if ret_code != 0:
        with open(log_path, 'at', encoding='utf-8') as log_file:
            for line in iter(process.stderr.readline, ''):
                if 'ninja: warning' in line:
                    log_file.write(line)
                    continue
                hb_error(line)
                log_file.write(line)

        if is_log_filter:
            get_failed_log(log_path)

        hb_error('you can check build log in {}'.format(log_path))
        if isinstance(cmd, list):
            cmd = ' '.join(cmd)
        raise Exception("{} failed, return code is {}".format(cmd, ret_code))

图为断点调试现场

经常有很多小伙伴抱怨说:不知道学习鸿蒙开发哪些技术?不知道需要重点掌握哪些鸿蒙应用开发知识点?

为了能够帮助到大家能够有规划的学习,这里特别整理了一套纯血版鸿蒙(HarmonyOS Next)全栈开发技术的学习路线,包含了鸿蒙开发必掌握的核心知识要点,内容有(ArkTS、ArkUI开发组件、Stage模型、多端部署、分布式应用开发、WebGL、元服务、OpenHarmony多媒体技术、Napi组件、OpenHarmony内核、OpenHarmony驱动开发、系统定制移植等等)鸿蒙(HarmonyOS NEXT)技术知识点。

在这里插入图片描述

《鸿蒙 (Harmony OS)开发学习手册》(共计892页):https://gitcode.com/HarmonyOS_MN

如何快速入门?

1.基本概念
2.构建第一个ArkTS应用
3.……

开发基础知识:

1.应用基础知识
2.配置文件
3.应用数据管理
4.应用安全管理
5.应用隐私保护
6.三方应用调用管控机制
7.资源分类与访问
8.学习ArkTS语言
9.……

在这里插入图片描述

基于ArkTS 开发

1.Ability开发
2.UI开发
3.公共事件与通知
4.窗口管理
5.媒体
6.安全
7.网络与链接
8.电话服务
9.数据管理
10.后台任务(Background Task)管理
11.设备管理
12.设备使用信息统计
13.DFX
14.国际化开发
15.折叠屏系列
16.……

在这里插入图片描述

鸿蒙开发面试真题(含参考答案):https://gitcode.com/HarmonyOS_MN

在这里插入图片描述

OpenHarmony 开发环境搭建

图片

《OpenHarmony源码解析》:https://gitcode.com/HarmonyOS_MN

  • 搭建开发环境
  • Windows 开发环境的搭建
  • Ubuntu 开发环境搭建
  • Linux 与 Windows 之间的文件共享
  • ……
  • 系统架构分析
  • 构建子系统
  • 启动流程
  • 子系统
  • 分布式任务调度子系统
  • 分布式通信子系统
  • 驱动子系统
  • ……

图片

OpenHarmony 设备开发学习手册:https://gitcode.com/HarmonyOS_MN

图片

写在最后

如果你觉得这篇内容对你还蛮有帮助,我想邀请你帮我三个小忙

  • 点赞,转发,有你们的 『点赞和评论』,才是我创造的动力。
  • 关注小编,同时可以期待后续文章ing🚀,不定期分享原创知识。
  • 想要获取更多完整鸿蒙最新学习资源,请移步前往在这里插入图片描述
Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐