[文章]OpenHarmony轻量和小型系统编译构建指导

阅读量0
2
2
概述
一个基于gn和ninja的构建系统,以支持OpenHarmony组件化开发为目标,提供以下基本功能:
  • 支持按组件拼装产品并编译。
  • 独立构建芯片解决方案厂商源码。
  • 独立构建单个组件。
基本概念
在使用编译构建子系统前,应了解如下基本概念:
  • 子系统
    子系统是一个逻辑概念,它由一个或多个具体的组件组成。OpenHarmony整体遵从分层设计,从下向上依次为:内核层、系统服务层、框架层和应用层。系统功能按照“系统 > 子系统 > 组件”逐级展开,在多设备部署场景下,支持根据实际需求裁剪某些非必要的子系统或组件。
  • 组件
    系统最小的可复用、可配置、可裁剪的功能单元。组件具备目录独立可并行开发、可独立编译、可独立测试的特征。
  • gn
    Generate ninja的缩写,用于产生ninja文件。
  • ninja
    ninja是一个专注于速度的小型构建系统。
  • hb
    OpenHarmony的命令行工具,用来执行编译命令。
目录结构
  1. ├── components                  # 组件描述文件
  2. ├── figure                     # readme中的图片
  3. ├── hb                          # hb pip安装包源码
  4. ├── make_rootfs                 # 文件系统镜像制作脚本
  5. ├── config                      # 编译配置项
  6. │   ├── component               # 组件相关的模板定义
  7. │   ├── kernel                  # 内核相关的编译配置
  8. │   └── subsystem               # 子系统编译配置
  9. ├── platform                    # ld脚本
  10. ├── testfwk                     # 测试编译框架
  11. └── toolchain                   # 编译工具链配置,包括:编译器路径、编译选项、链接选项等
复制代码

构建流程

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

  • hb set: 设置OpenHarmony源码目录和要编译的产品。
  • hb build: 编译产品、开发板或者组件。编译主要过程如下:
    • 读取编译配置:根据产品选择的开发板,读取开发板config.gni文件内容,主要包括编译工具链、编译链接命令和选项等。
    • 调用gn:调用gn gen命令,读取产品配置生成产品解决方案out目录和ninja文件。
    • 调用ninja:调用ninja -C out/board/product启动编译。
    • 系统镜像打包:将组件编译产物打包,设置文件属性和权限,制作文件系统镜像。
配置规则
为了实现芯片解决方案、产品解决方案与OpenHarmony是解耦的、可插拔的,组件、芯片解决方案和产品解决方案的路径、目录树和配置需遵循一定的规则,具体如下:
组件

组件源码路径命名规则为:{领域}/{子系统}/{组件},组件目录树规则如下:

注意:组件的名称、源码路径、功能简介、是否必选、编译目标、RAM、ROM、编译输出、已适配的内核、可配置的特性和依赖等属性定义在build/lite/components目录下对应子系统的json文件中,新增组件时需要在对应子系统json文件中添加相应的组件定义。产品所配置的组件必须在某个子系统中被定义过,否则会校验失败。
  1. component
  2. ├── interfaces
  3. │   ├── innerkits  # 系统内接口,组件间使用
  4. │   └── kits       # 应用接口,应用开发者使用
  5. ├── frameworks     # framework实现
  6. ├── services       # service实现
  7. └── BUILD.gn       # 组件编译脚本
复制代码
以泛sensor子系统的sensor服务组件为例,组件属性定义描述文件字段说明如下:
  1. {
  2.   "components": [
  3.     {
  4.       "component": "sensor_lite",                # 组件名称
  5.       "description": "Sensor services",          # 组件一句话功能描述
  6.       "optional": "true",                        # 组件是否为最小系统必选
  7.       "dirs": [                                  # 组件源码路径
  8.         "base/sensors/sensor_lite"
  9.       ],
  10.       "targets": [                               # 组件编译入口
  11.         "//base/sensors/sensor_lite/services:sensor_service"
  12.       ],
  13.       "rom": "92KB",                             # 组件ROM值
  14.       "ram": "~200KB",                           # 组件RAM估值
  15.       "output": [ "libsensor_frameworks.so" ],   # 组件编译输出
  16.       "adapted_kernel": [ "liteos_a" ],          # 组件已适配的内核
  17.       "features": [],                            # 组件可配置的特性
  18.       "deps": {                     
  19.         "components": [                          # 组件依赖的其他组件
  20.           "samgr_lite",
  21.           "ipc_lite"

  22.         ],
  23.         "third_party": [                         # 组件依赖的三方开源软件
  24.           "bounds_checking_function"
  25.         ]
  26.       }
  27.     }
  28.   ]
  29. }
复制代码

组件BUILD.gn的编写建议如下:
  • 编译目标名称与组件一致。
  • 组件对外可配置的特性变量需声明在该组件BUILD.gn中,特性变量命名规则:ohos_{subsystem}_{component}_{feature}。特性在组件描述中也需要同步定义,在产品配置文件config.json中按需配置。
  • 宏定义规则:OHOS_{SUBSYSTEM}_{COMPONENT}_{FEATURE}
    说明:组件的编译脚本语言为gn,gn的基本用法请见https://gn.googlesource.com/gn/+/master/docs/quick_start.md。 组件即为gn定义的编译目标,可以为静态库、动态库、可执行文件或group。

以图形的UI组件为例,foundation/graphic/ui/BUILD.gn文件如下:
  1.         # 声明组件可配置的特性
  2.         declare_args() {
  3.           enable_ohos_graphic_ui_animator = false # 动效特性开关
  4.           ohos_ohos_graphic_ui_font = "vector"    # 可配置的字体类型,vector或者bitmap
  5.         }
  6.         
  7.         # 组件基础功能
  8.         shared_library("base") {
  9.           sources = [
  10.             ......
  11.           ]
  12.           include_dirs = [
  13.             ......
  14.           ]
  15.         }
  16.         
  17.         # 仅在animator开启时编译
  18.         if(enable_ohos_graphic_ui_animator ) {
  19.           shared_library("animator") {
  20.             sources = [
  21.               ......
  22.             ]
  23.             include_dirs = [
  24.               ......
  25.             ]
  26.             deps = [ :base ]
  27.           }
  28.         }
  29.         ......
  30.         # target名称建议与组件名称一致, 组件target类型可以是executable(bin文件),shared_library(动态库.so),static_library(静态库.a),group等等
  31.         executable("ui") {
  32.           deps = [
  33.             ":base"
  34.           ]

  35.           # animator特性由产品配置
  36.           if(enable_ohos_graphic_ui_animator ) {
  37.               deps += [
  38.                 "animator"
  39.               ]
  40.           }
  41.         }
复制代码

芯片解决方案
  • 芯片解决方案是指基于某款开发板的完整解决方案,包含驱动、设备侧接口适配、开发板sdk等。
  • 芯片解决方案是一个特殊的组件,源码路径规则为:device/{芯片解决方案厂商}/{开发板}
  • 芯片解决方案组件会随产品选择的开发板默认编译。

芯片解决方案目录树规则如下:
  1. device                                      
  2. └── company                         # 芯片解决方案厂商
  3.     └── board                       # 开发板名称
  4.         ├── BUILD.gn                # 编译脚本
  5.         ├── hals                    # OS南向接口适配
  6.         ├── linux                   # 可选,linux内核版本
  7.         │   └── config.gni          # linux版本编译配置
  8.         └── liteos_a                # 可选,liteos内核版本
  9.             └── config.gni          # liteos_a版本编译配置
复制代码

说明:config.gni为开发板编译相关的配置,编译时会采用该配置文件中的参数编译所有OS组件,编译阶段系统全局可见。

config.gni的关键字段介绍如下:
  1. kernel_type:            开发板使用的内核类型,例如:“liteos_a”, “liteos_m”, “linux”。
  2. kernel_version:         开发使用的内核版本,例如:“4.19”。
  3. board_cpu:              开发板CPU类型,例如:“cortex-a7”, “riscv32”。
  4. board_arch:             开发芯片arch, 例如: “armv7-a”, “rv32imac”。
  5. board_toolchain:        开发板自定义的编译工具链名称,例如:“gcc-arm-none-eabi”。若为空,则使用默认为ohos-clang。
  6. board_toolchain_prefix:编译工具链前缀,例如:“gcc-arm-none-eabi”。
  7. board_toolchain_type:  编译工具链类型,目前支持gcc和clang。例如:“gcc” ,“clang”。
  8. board_cflags:          开发板配置的c文件编译选项。
  9. board_cxx_flags:       开发板配置的cpp文件编译选项。
  10. board_ld_flags:        开发板配置的链接选项。
复制代码

产品解决方案产品解决方案为基于开发板的完整产品,主要包含产品对OS的适配、组件拼装配置、启动配置和文件系统配置等。产品解决方案的源码路径规则为:vendor/{产品解决方案厂商}/{产品名称}_。_产品解决方案也是一个特殊的组件。

产品解决方案的目录树规则如下:
  1. vendor                              
  2. └── company                         # 产品解决方案厂商
  3.     ├── product                     # 产品名称
  4.     │   ├── init_configs
  5.     │   │     ├── etc               # init进程启动配置(可选,仅linux内核需要)
  6.     │   │     └── init.cfg          # 系统服务启动配置
  7.     │   ├── hals                    # 产品解决方案OS适配
  8.     │   ├── BUILD.gn                # 产品编译脚本
  9.     │   └── config.json             # 产品配置文件
  10.     │   └── fs.yml                  # 文件系统打包配置
  11.     └── ......
复制代码

注意:新增产品须按如上的规则创建目录和文件,编译构建系统将按该规则扫描已配置的产品。

关键的目录和文件详细介绍如下:
  • vendor/company/product/init_configs/etc
    该文件夹中包含rcS脚本,Sxxx脚本和fstab脚本。init进程在启动系统服务之前执行这些脚本。执行的流程为“rcS->fstab->S00-xxx“。Sxxx脚本中的内容与开发板和产品需要有关,主要包括设备节点的创建、创建目录、扫描设备节点、修改文件权限等等。这些文件在产品编译的BUILD.gn中按需拷贝到产品out目录中,最终打包到rootfs镜像中。
  • vendor/company/product/init_configs/init.cfg
    init进程启动服务的配置文件,当前支持解析的命令有:
    • start:  启动某个服务
    • mkdir: 创建文件夹
    • chmod: 修改指定路径/文件的权限
    • chown: 修改指定路径/文件的属组
    • mount: 挂载命令
    该文件中的各个字段的解释如下:
  1. {
  2.     "jobs" : [{                                                     # job数组,一个job对应一个命令集合。job的执行顺序:pre-init -> init -> post-init。
  3.             "name" : "pre-init",
  4.             "cmds" : [
  5.                 "mkdir /storage/data",                              # 创建目录
  6.                 "chmod 0755 /storage/data",                         # 修改权限,权限值的格式为0xxx, 如0755
  7.                 "mkdir /storage/data/log",
  8.                 "chmod 0755 /storage/data/log",
  9.                 "chown 4 4 /storage/data/log",                      # 修改属组,第一个数字为uid, 第二个数字为gid
  10.                 ......
  11.                 "mount vfat /dev/mmcblock0 /sdcard rw,umask=000"    # 挂载,格式为: mount [文件系统类型] [source] [target] [flags] [data]
  12.                                                                     # 其中flags仅支持:nodev、noexec、nosuid和rdonly
  13.             ]
  14.         }, {
  15.             "name" : "init",
  16.             "cmds" : [                                              # 按cmds数组顺序启动启动服务
  17.                 "start shell",                                      # 注意:start与服务名称之间有且只有一个空格
  18.                 ......
  19.                 "start service1"
  20.             ]
  21.         }, {
  22.             "name" : "post-init",                                   # 最后执行的job, init进程启动完成后的处理(如驱动初始化后再mount设备)
  23.             "cmds" : []
  24.         }
  25.     ],
  26.     "services" : [{                                                 # service数组,一个service对应一个进程
  27.             "name" : "shell",                                       # 服务名称
  28.             "path" : ["/sbin/getty", "-n", "-l", "/bin/sh", "-L", "115200", "ttyS000", "vt100"],    # 可执行文件全路径,path必须为第一个元素
  29.             "uid" : 0,                                              # 进程的uid,须与二进制文件的uid保持一致
  30.             "gid" : 0,                                              # 进程的gid,须与二进制文件的gid保持一致
  31.             "once" : 0,                                             # 是否为一次性进程,1:进程退出后,init不在重新拉起。0:常驻进程,进程若退出,init将重新拉起
  32.             "importance" : 0,                                       # 是否为关键进程,1:是关键进程,若进程退出,init将会重启单板。0:非关键进程,若进程退出,init不会重启单板
  33.             "caps" : [4294967295]
  34.         },
  35.         ......
  36.     ]
  37. }

  38. {
  39.         "product_name": "ipcamera",                       # 产品名称
  40.     "version": "3.0",                                 # config.json的版本号, 固定"3.0"
  41.     "type": "small",                                  # 系统类型, 可选[mini, small, standard]
  42.         "ohos_version": "OpenHarmony 1.0",                # 选择的OS版本
  43.         "device_company": "hisilicon",                    # 芯片厂商
  44.         "board": "hispark_taurus",                        # 开发板名称
  45.         "kernel_type": "liteos_a",                        # 选择的内核类型
  46.         "kernel_version": "3.0.0",                        # 选择的内核版本
  47.         "subsystems": [                           
  48.           {
  49.             "subsystem": "aafwk",                         # 选择的子系统
  50.             "components": [
  51.               { "component": "ability", "features":[ "enable_ohos_appexecfwk_feature_ability = true" ] }   # 选择的组件和组件特性配置
  52.             ]
  53.           },
  54.           {
  55.            ......
  56.           }
  57.           ......
  58.           更多子系统和组件
  59.         }
  60. }

  61. fs_dir_name: 必填,声明文件系统文件名, 如rootfs、userfs
  62. fs_dirs:     选填,配置out下文件目录与文件系统文件目录的映射关系,每个文件目录对应一个列表
  63. source_dir:  选填,out下目标文件目录,若缺失则将根据target_dir在文件系统下创建空目录
  64. target_dir:  必填,文件系统下对应文件目录
  65. ignore_files:选填,声明拷贝忽略文件
  66. dir_mode:    选填,文件目录权限,默认755
  67. file_mode:   选填,该文件目录下所有文件的权限,默认555
  68. fs_filemode: 选填,配置需要特殊声明权限的文件,每个文件对应一个列表
  69. file_dir:    必填,文件系统下具体文件路径
  70. file_mode:   必填,文件权限声明
  71. fs_symlink:  选填,配置文件系统软连接
  72. fs_make_cmd: 必填,配置需要制作文件系统脚本,OS提供的脚本在build/lite/make_rootfs下, 支持linux,liteos内核和ext4、jffs2、vfat格式。也支持芯片解决方案厂商自定义。
  73. fs_attr:     选填,根据配置项动态调整文件系统

  74. group("product") { # target名称需与product名称即三级目录名称一致
  75.   deps = []
  76.   # 拷贝init配置
  77.   deps += [ "init_configs" ]
  78.   # 其他
  79.   ......
  80. }
复制代码

使用指导前提条件开发环境需安装gn、ninja构建工具、python 3.7.4及以上和hb。安装方法请见搭建系统基础环境。

hb工具使用说明hb是OpenHarmony的命令行工具,用来执行编译命令。以下对hb的常用命令进行说明。
hb set
  1. hb set -h
  2. usage: hb set [-h] [-root [ROOT_PATH]] [-p]

  3. optional arguments:
  4.   -h, --help            show this help message and exit
  5.   -root [ROOT_PATH], --root_path [ROOT_PATH]
  6.                         Set OHOS root path
  7.   -p, --product         Set OHOS board and kernel
复制代码

  • hb set 后无参数,进入默认设置流程
  • hb set -root dir可直接设置代码根目录
  • hb set -p设置要编译的产品

hb env
查看当前设置信息
  1. hb env
  2. [OHOS INFO] root path: xxx
  3. [OHOS INFO] board: hispark_taurus
  4. [OHOS INFO] kernel: liteos
  5. [OHOS INFO] product: ipcamera
  6. [OHOS INFO] product path: xxx/vendor/hisilicon/ipcamera
  7. [OHOS INFO] device path: xxx/device/hisilicon/hispark_taurus/sdk_linux_4.19
复制代码

hb build
  1. hb build -h
  2. usage: hb build [-h] [-b BUILD_TYPE] [-c COMPILER] [-t [TEST [TEST ...]]]
  3.                 [--dmverity] [--tee] [-p PRODUCT] [-f] [-n]
  4.                 [-T [TARGET [TARGET ...]]] [-v] [-shs] [--patch]
  5.                 [component [component ...]]

  6. positional arguments:
  7.   component             name of the component

  8. optional arguments:
  9.   -h, --help            show this help message and exit
  10.   -b BUILD_TYPE, --build_type BUILD_TYPE
  11.                         release or debug version
  12.   -c COMPILER, --compiler COMPILER
  13.                         specify compiler
  14.   -t [TEST [TEST ...]], --test [TEST [TEST ...]]
  15.                         compile test suit
  16.   --dmverity            Enable dmverity
  17.   --tee                 Enable tee
  18.   -p PRODUCT, --product PRODUCT
  19.                         build a specified product with
  20.                         {product_name}@{company}, eg: camera@huawei
  21.   -f, --full            full code compilation
  22.   -n, --ndk             compile ndk
  23.   -T [TARGET [TARGET ...]], --target [TARGET [TARGET ...]]
  24.                         Compile single target
  25.   -v, --verbose         show all command lines while building
  26.   -shs, --sign_haps_by_server
  27.                         sign haps by server
  28.   --patch               apply product patch before compiling

  29.   --dmverity            Enable dmverity
  30.   -p PRODUCT, --product PRODUCT
  31.                         build a specified product with
  32.                         {product_name}@{company}, eg: ipcamera@hisilcon
  33.   -f, --full            full code compilation
  34.   -T [TARGET [TARGET ...]], --target [TARGET [TARGET ...]]
  35.                         Compile single target
复制代码

  • hb build后无参数,会按照设置好的代码路径、产品进行编译,编译选项使用与之前保持一致。-f 选项将删除当前产品所有编译产品,等同于hb clean + hb build.
  • hb build {component_name}:基于设置好的产品对应的单板、内核,单独编译组件(e.g.:hb build kv_store)。
  • hb build -p ipcamera@hisilicon:免set编译产品,该命令可以跳过set步骤,直接编译产品。
  • 在device/device_company/board下单独执行hb build会进入内核选择界面,选择完成后会根据当前路径的单板、选择的内核编译出仅包含内核、驱动的镜像。

hb clean
清除out目录对应产品的编译产物,仅保留args.gn、build.log。清除指定路径可输入路径参数:hb clean out/board/product,默认将清除当前hb set的产品对应out路径。
  1. hb clean
  2. usage: hb clean [-h] [out_path]

  3. positional arguments:
  4.   out_path    clean a specified path.

  5. optional arguments:
  6.   -h, --help  show this help message and exit
复制代码

新增组件
本小节介绍如何新增一个组件,首先确定组件归属的子系统和组件名称,然后按如下步骤新增:
  • 源码开发完成后,添加组件编译脚本。
    以编译组件hello_world可执行文件为例,applications/sample/hello_world/BUILD.gn可以写为:
  1. executable("hello_world") {
  2.   include_dirs = [
  3.     "include",
  4.    ]
  5.   sources = [
  6.     "src/hello_world.c"
  7.   ]
  8. }
复制代码

如上编译脚本,可编译出一个可在OpenHarmony上运行的名为hello_world的可执行文件。

单独编译该组件,hb set任意选择一款产品,然后使用-T选项单独编译组件:
  1. hb build -f -T //applications/sample/hello_world

  2. {
  3.   "components": [
  4.     {
  5.       "component": "hello_world",
  6.       "description": "Hello world.",
  7.       "optional": "true",
  8.       "dirs": [
  9.         "applications/sample/hello_world"
  10.       ],
  11.       "targets": [
  12.         "//applications/sample/hello_world"
  13.       ]
  14.     },
  15.     ...
  16.    ]
  17. }

  18. {
  19.     "product_name": "hello_world_test",
  20.     "ohos_version": "OpenHarmony 1.0",
  21.     "device_company": "hisilicon",
  22.     "board": "hispark_taurus",
  23.     "kernel_type": "liteos_a",
  24.     "kernel_version": "1.0.0",
  25.     "subsystems": [
  26.       {
  27.         "subsystem": "applications",
  28.         "components": [
  29.           { "component": "hello_world", "features":[] }
  30.         ]
  31.       },
  32.       ...
  33.     ]
  34. }
复制代码

  • 编译产品。
    • 代码根目录输入hb set选择对应产品。
    • 执行hb build。
新增芯片解决方案

编译构建支持添加新的芯片解决方案厂商,具体步骤如下:
  • 创建芯片解决方案目录。
    按照芯片解决方案配置规则创建目录,以芯片厂商realtek的“rtl8720“开发板为例, 在代码根目录执行:
  1. mkdir -p device/realtek/rtl8720

  2. # Kernel type, e.g. "linux", "liteos_a", "liteos_m".
  3. kernel_type = "liteos_a"

  4. # Kernel version.
  5. kernel_version = "3.0.0"

  6. # Board CPU type, e.g. "cortex-a7", "riscv32".
  7. board_cpu = "real-m300"

  8. # Board arch, e.g. "armv7-a", "rv32imac".
  9. board_arch = ""

  10. # Toolchain name used for system compiling.
  11. # E.g. gcc-arm-none-eabi, arm-linux-harmonyeabi-gcc, ohos-clang, riscv32-unknown-elf.
  12. # Note: The default toolchain is "ohos-clang". It's not mandatory if you use the default toochain.
  13. board_toolchain = "gcc-arm-none-eabi"

  14. # The toolchain path instatlled, it's not mandatory if you have added toolchian path to your ~/.bashrc.
  15. board_toolchain_path =
  16.     rebase_path("//prebuilts/gcc/linux-x86/arm/gcc-arm-none-eabi/bin",
  17.                 root_build_dir)

  18. # Compiler prefix.
  19. board_toolchain_prefix = "gcc-arm-none-eabi-"

  20. # Compiler type, "gcc" or "clang".
  21. board_toolchain_type = "gcc"

  22. # Board related common compile flags.
  23. board_cflags = []
  24. board_cxx_flags = []
  25. board_ld_flags = []

  26. group("rtl8720") { # target类型也可以shared_library, static_library, executable
  27.   # 具体内容
  28.   ......
  29. }
复制代码

  • 编译芯片解决方案。
    在开发板目录下执行hb build,即可启动芯片解决方案的编译。
新增产品解决方案

编译构建支持芯片解决方案和组件的灵活拼装,形成定制化的产品解决方案。具体步骤如下:
  • 创建产品目录
    按照产品解决方案配置规则创建产品目录,以基于“rtl8720“开发板的wifiiot模组为例,在代码根目录执行:
  1. mkdir -p vendor/my_company/wifiiot

  2. {
  3.     "product_name": "wifiiot",                        # 产品名称
  4.     "version": "3.0",                                 # config.json的版本号, 固定"3.0"
  5.     "type": "small",                                  # 系统类型, 可选[mini, small, standard]
  6.     "ohos_version": "OpenHarmony 1.0",                # 使用的OS版本
  7.     "device_company": "realtek",                      # 芯片解决方案厂商名称
  8.     "board": "rtl8720",                               # 开发板名称
  9.     "kernel_type": "liteos_m",                        # 选择的内核类型
  10.     "kernel_version": "3.0.0",                        # 选择的内核版本
  11.     "subsystems": [                           
  12.       {
  13.         "subsystem": "kernel",                        # 选择的子系统
  14.         "components": [
  15.           { "component": "liteos_m", "features":[] }  # 选择的组件和组件特性
  16.         ]
  17.       },
  18.       ...
  19.       {
  20.          更多子系统和组件
  21.       }
  22.     ]
  23. }

  24. -
  25.   fs_dir_name: rootfs # 镜像的名称
  26.   fs_dirs:
  27.     -
  28.       # 将编译生成的out/my_board/my_product/bin目录下的文件拷贝到rootfs/bin中,并忽略测试bin
  29.       source_dir: bin
  30.       target_dir: bin
  31.       ignore_files:
  32.         - Test.bin
  33.         - TestSuite.bin
  34.     -
  35.       # 将编译生成的out/my_board/my_product/libs目录下的文件拷贝到rootfs/lib中,忽略所有.a文件,并设置文件和文件夹的权限为644和755
  36.       source_dir: libs
  37.       target_dir: lib
  38.       ignore_files:
  39.         - .a
  40.       dir_mode: 755
  41.       file_mode: 644
  42.     -
  43.       source_dir: usr/lib
  44.       target_dir: usr/lib
  45.       ignore_files:
  46.         - .a
  47.       dir_mode: 755
  48.       file_mode: 644
  49.     -
  50.       source_dir: config
  51.       target_dir: etc
  52.     -
  53.       source_dir: system
  54.       target_dir: system
  55.     -
  56.       source_dir: sbin
  57.       target_dir: sbin
  58.     -
  59.       source_dir: usr/bin
  60.       target_dir: usr/bin
  61.     -
  62.       source_dir: usr/sbin
  63.       target_dir: usr/sbin
  64.     -
  65.       # 创建一个proc空目录
  66.       target_dir: proc
  67.     -
  68.       target_dir: mnt
  69.     -
  70.       target_dir: opt
  71.     -
  72.       target_dir: tmp
  73.     -
  74.       target_dir: var
  75.     -
  76.       target_dir: sys
  77.     -
  78.       source_dir: etc
  79.       target_dir: etc
  80.     -
  81.       source_dir: vendor
  82.       target_dir: vendor
  83.     -
  84.       target_dir: storage

  85.   fs_filemode:
  86.     -
  87.       file_dir: lib/ld-uClibc-0.9.33.2.so
  88.       file_mode: 555
  89.     -
  90.       file_dir: lib/ld-2.24.so
  91.       file_mode: 555
  92.     -
  93.       file_dir: etc/init.cfg
  94.       file_mode: 400
  95.   fs_symlink:
  96.     -
  97.       # 在rootfs/lib下创建软连接ld-musl-arm.so.1 -> libc.so
  98.       source: libc.so
  99.       link_name: ${fs_dir}/lib/ld-musl-arm.so.1
  100.     -
  101.       source: mksh
  102.       link_name: ${fs_dir}/bin/sh
  103.     -
  104.       source: mksh
  105.       link_name: ${fs_dir}/bin/shell
  106.   fs_make_cmd:
  107.     # 使用脚本将rootfs制作为ext4格式的image
  108.     - ${root_path}/build/lite/make_rootfs/rootfsimg_linux.sh ${fs_dir} ext4
  109. -
  110.   fs_dir_name: userfs
  111.   fs_dirs:
  112.     -
  113.       source_dir: storage/etc
  114.       target_dir: etc
  115.     -
  116.       source_dir: data
  117.       target_dir: data
  118.   fs_make_cmd:
  119.     - ${root_path}/build/lite/make_rootfs/rootfsimg_linux.sh ${fs_dir} ext4

  120. # 需要打patch的路径
  121. foundation/communication/dsoftbus:
  122.   # 该路径下需要打的patch存放路径
  123.   - foundation/communication/dsoftbus/1.patch
  124.   - foundation/communication/dsoftbus/2.patch
  125. third_party/wpa_supplicant:
  126.   - third_party/wpa_supplicant/1.patch
  127.   - third_party/wpa_supplicant/2.patch
  128.   - third_party/wpa_supplicant/3.patch
  129. ...
复制代码

配置完成后,编译时增加–patch参数,即可在产品编译前将配置的Patch文件打到对应目录中,再进行编译:
  1. hb build -f --patch

  2. group("wifiiot") { # target名称与产品名一致
  3.   deps = []
  4.   # 拷贝init配置
  5.   deps += [ "init_configs" ]
  6.   # 将hals加入编译
  7.   deps += [ "hals" ]
  8.   # 其他
  9.   ......
  10. }
复制代码

  • 编译产品。
    在代码根目录执行hb set按提示选择新增的产品,然后执行hb build即可启动编译。
常见问题编译构建过程中,提示“usr/sbin/ninja: invalid option – w”
  • 现象描述:
    编译失败,提示“usr/sbin/ninja: invalid option – w”。
  • 可能原因:
    编译环境中ninja版本太低,不支持–w选项。
  • 解决办法:
    卸载环境中ninja和gn,按照获取工具。
编译构建过程中,提示“/usr/bin/ld: cannot find -lncurses”
  • 现象描述:
    编译失败,提示“/usr/bin/ld: cannot find -lncurses”。
  • 可能原因:
    编译环境ncurses库缺失。
  • 解决办法:
  1. sudo apt-get install lib32ncurses5-dev
复制代码
编译构建过程中,提示“line 77: mcopy: command not found”
  • 现象描述:
    ​编译失败,提示“line 77: mcopy: command not found”。
  • 可能原因:
    编译环境未安装mcopy。
  • 解决办法:
  1. ​sudo apt-get install dosfstools mtools
复制代码
编译构建过程中,提示“riscv32-unknown-elf-gcc: error trying to exec ‘cc1’: execvp: No such file or directory”
  • 现象描述:
    编译失败,提示“riscv32-unknown-elf-gcc: error trying to exec ‘cc1’: execvp: No such file or directory”。
  • 可能原因:
    当前用户对riscv编译器路径下的文件访问权限不够。
  • 解决办法:
    查询gcc_riscv32所在目录。
  1. which riscv32-unknown-elf-gcc
复制代码
  • 使用chmod命令修改目录权限为755。
编译构建过程中,提示“No module named ‘Crypto’”
  • 现象描述:
    编译失败,提示“No module named ‘Crypto’”。
  • 可能原因:
    python3未安装Crypto。
  • 解决办法:
    • 查询Python版本号。
python3 --versionsudo pip3 install pycryptodome
  • sudo pip3 install pycryptodome

编译构建过程中,提示“xx.sh : xx unexpected operator”
  • 现象描述:
    编译失败:“xx.sh [: xx unexpected operator”。
  • 可能原因:
    编译环境shell不是bash。
  • 解决办法:
  1. sudo rm -rf /bin/sh
  2. sudo ln -s /bin/bash /bin/sh
复制代码

回帖

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容图片侵权或者其他问题,请联系本站作侵删。 侵权投诉
链接复制成功,分享给好友