编译构建使用指导.md 13.1 KB
Newer Older
Y
yangni 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
# 编译构建使用指导<a name="ZH-CN_TOPIC_0000001060378721"></a>

-   [目录结构](#section56731811102915)
-   [编译命令](#section1475192018291)
-   [开发步骤](#section4207112818418)

## 目录结构<a name="section56731811102915"></a>

```
build/lite                          # 编译构建主目录
├── config                       # 编译相关的配置项
│   ├── boards                  # 开发板相关的变量定义。包括:开发板名、目标架构、目标CPU等
│   ├── component               # OpenHarmony组件相关的模板定义。包括:静态库、动态库、扩展组件、模拟器库等
│   ├── kernel                  # OpenHarmony内核的编译变量定义与配置参数
│   └── subsystem               # OpenHarmony子系统列表
├── ndk                          # NDK相关编译脚本与配置参数
├── platform                     # 平台相关的配置文件
│   ├── hi3516dv300_liteos_a    # hi3516dv300, liteos_a平台。包括:平台全量配置表,启动文件。
│   ├── hi3518ev300_liteos_a    # hi3518ev300, liteos_a平台。包括:平台全量配置表,启动文件。
│   └── hi3861v100_liteos_riscv # hi3861v100, liteos_riscv平台。包括:平台全量配置表,启动文件。
├── product                      # 产品全量配置表。包括:配置单元、子系统列表、编译器等。
├── toolchain                    # 编译工具链相关。包括:编译器路径、编译选项、链接选项等。
└── tools                        # 编译构建依赖的工具。包括:mkfs等。
```

## 编译命令<a name="section1475192018291"></a>

-   使用方法:

    ```
    python build.py product [options]
    ```

34
    product为build/lite/product/xxx.json, product名称和json配置文件中的组件均可自定义。默认json文件中的组件为对应平台支持的全集。
Y
yangni 已提交
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200

-   编译选项:

    -b, --build\_type                 Debug or release

    -t, --test                              Build with test suit

    -T, --target                         Build single target

-   编译输出: 代码根目录/out/product


## 开发步骤<a name="section4207112818418"></a>

1.  添加组件

    本节以添加一个自定义的组件为例,描述了如何编译组件、编译库、编译可执行文件。

    示例组件example由两个功能feature1和feature2组成。feture1的目标为一个动态库,feature2的目标为一个可执行文件。示例组件example的完整目录结构如下:

    ```
    example                         # 自定义组件
    ├── BUILD.gn                 # 自定义组件gn脚本,BUILD.gn为固定名称
    ├── feature1                 # 自定义单元1
    │   ├── BUILD.gn            # 自定义单元1的gn脚本,BUILD.gn为固定名称
    │   ├── include             # 头文件文件夹
    │   │   └── helloworld1.h  # 头文件1
    │   └── src                 # 源文件文件夹
    │       └── helloworld1.c   # 源文件1 
    ├── feature2                 # 自定义单元2
    │   ├── BUILD.gn            # 自定义单元2的gn脚本,BUILD.gn为固定名称
    │   ├── include             # 头文件文件夹
    │   │   └── helloworld2.h  # 头文件2
    │   └── src                 # 源文件文件夹
    │       └── helloworld2.c   # 源文件2
    ├── build.sh                 # 自定义组件build.sh脚本,非必要
    └── Makefile                 # 自定义组件Makefile脚本,非必要
    ```

    示例1:编写动态库gn脚本example/feature1/BUILD.gn,示例如下:

    ```
    # helloworld动态库编译示例
    # helloworld的Build.gn文件
    shared_library("helloworld_lib") {
      sources = [
        "src/helloworld1.c"
      ]
      include_dirs = [
        "include",
        "../feature2_example/include" #(可选)如果依赖 feature2_example 可以加入该include
      ]
    }
    ```

    示例2:编写可执行文件gn脚本example/feature2/BUILD.gn,示例如下:

    内置函数executable,可编译出可执行文件。示例如下:

    ```
    #编译可执行.bin文件
    executable("hello_world_bin") {
      sources = [
        "src/helloworld2.c"
      ]
      include_dirs = [
        "include",
        "../feature2_example/include"    #(可选)如果依赖 feature2_example 可以加入该include
      ]
      #(可选)如果依赖 feature1_example 可以加入该deps
      deps = [
          "../feature1_example:helloworld1"
      ]
    }
    ```

    示例3,编译组件脚本example/BUILD.gn:

    ```
    import("//build/lite/config/component/lite_component.gni")
    lite_component("example_gn") {
      features = [
        "feature_example1:helloworld_lib",
        "feature_example2:hello_world_bin",
      ]
    }
    ```

    示例4,三方开源软件的build.sh或Makefile工程, 可用gn脚本调用混合编译:

    ```
    build_ext_component("example_mk") {
      exec_path = rebase_path(rebase_path(".", root_build_dir))
      outdir = rebase_path(get_path_info(".", "out_dir"))
      prebuilts = "sh build.sh"
      command = "make clean && make"
    }
    ```

    全局可引用的变量定义在:build/lite/ohos\_var.gni

    用户常用变量说明见表1:

    **表 1**  用户常用变量

    <a name="table520317612613"></a>
    <table><thead align="left"><tr id="row13203861262"><th class="cellrowborder" valign="top" width="33.33333333333333%" id="mcps1.2.4.1.1"><p id="p2203368619"><a name="p2203368619"></a><a name="p2203368619"></a>变量</p>
    </th>
    <th class="cellrowborder" valign="top" width="33.33333333333333%" id="mcps1.2.4.1.2"><p id="p15203765620"><a name="p15203765620"></a><a name="p15203765620"></a>取值范围</p>
    </th>
    <th class="cellrowborder" valign="top" width="33.33333333333333%" id="mcps1.2.4.1.3"><p id="p6203669616"><a name="p6203669616"></a><a name="p6203669616"></a>说明</p>
    </th>
    </tr>
    </thead>
    <tbody><tr id="row42036617616"><td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.1 "><p id="p1643814011561"><a name="p1643814011561"></a><a name="p1643814011561"></a>ohos_kernel_type</p>
    </td>
    <td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.2 "><p id="p114385019568"><a name="p114385019568"></a><a name="p114385019568"></a>"liteos_a", "liteos_riscv"</p>
    </td>
    <td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.3 "><p id="p820396265"><a name="p820396265"></a><a name="p820396265"></a>内核类型</p>
    </td>
    </tr>
    <tr id="row62033619614"><td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.1 "><p id="p134381805564"><a name="p134381805564"></a><a name="p134381805564"></a>board_name</p>
    </td>
    <td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.2 "><p id="p9203161968"><a name="p9203161968"></a><a name="p9203161968"></a>"hi3516dv300", "hi3518ev300", "hi3861v100"</p>
    </td>
    <td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.3 "><p id="p172031169619"><a name="p172031169619"></a><a name="p172031169619"></a>开发板类型</p>
    </td>
    </tr>
    <tr id="row1620318610614"><td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.1 "><p id="p1143880135612"><a name="p1143880135612"></a><a name="p1143880135612"></a>ohos_build_compiler</p>
    </td>
    <td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.2 "><p id="p22041613618"><a name="p22041613618"></a><a name="p22041613618"></a>"gcc", "clang"</p>
    </td>
    <td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.3 "><p id="p9204861469"><a name="p9204861469"></a><a name="p9204861469"></a>编译工具链类型</p>
    </td>
    </tr>
    <tr id="row6392114583815"><td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.1 "><p id="p539294514383"><a name="p539294514383"></a><a name="p539294514383"></a>ohos_build_type</p>
    </td>
    <td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.2 "><p id="p7392144510388"><a name="p7392144510388"></a><a name="p7392144510388"></a>"debug", "release"</p>
    </td>
    <td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.3 "><p id="p53921145123819"><a name="p53921145123819"></a><a name="p53921145123819"></a>编译类型</p>
    </td>
    </tr>
    </tbody>
    </table>

    举例:ohos\_kernel\_type的使用方式,component\_example/feature2\_example/BUILD.gn。

    ```
    lite_library("helloworld") {
      if (ohos_kernel_type == "liteos_a") {
        target_type = "shared_library"
      }
      else if (ohos_kernel_type == "liteos_riscv") {
        target_type = "static_library"
      }
      sources = [
        "src/helloworld1.c"
      ]
      include_dirs = [
        "include"
      ]
    }
    ```

2.  编译产品解决方案

201
    产品解决方案的配置在build/lite/product 目录下,如ipcamera\_hi3516dv300.json,构建时会读取该文件包含所有用户自定义子系统、组件等配置。以编译ipcamera\_hi3516dv300为例,编译命令如下:
Y
yangni 已提交
202 203

    ```
204
    python build.py ipcamera_hi3516dv300
Y
yangni 已提交
205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275
    ```

3.  编译输出

    编译所生产的文件都归档在out目录下,例如在代码所在目录下,运行"python build.py wifiiot -b debug",编译wifiiot完成后,会有如下结果生成:

    ```
    out/
    └── wifiiot                               # 产品名
    ├── args.gn                               # gn编译,用户自定义变量
    ├── build.log                             # 编译日志
    ├── build.ninja
    ├── build.ninja.d
    ├── gen
    ├── Hi3861_boot_signed_B.bin              # 带签名的bootloader备份文件
    ├── Hi3861_boot_signed.bin                # 带签名的bootloader文件
    ├── Hi3861_loader_signed.bin              # 烧写工具使用的加载文件
    ├── Hi3861_wifiiot_app_allinone.bin       # 产线工装烧写文件(已经包含独立烧写程序和loader程序)
    ├── Hi3861_wifiiot_app.asm                # Kernel asm文件
    ├── Hi3861_wifiiot_app_burn.bin           # 烧写文件
    ├── Hi3861_wifiiot_app_flash_boot_ota.bin # Flash Boot升级文件
    ├── Hi3861_wifiiot_app.map                # Kernel map文件
    ├── Hi3861_wifiiot_app_ota.bin            # Kernel 升级文件
    ├── Hi3861_wifiiot_app.out                # Kernel 输出文件
    ├── Hi3861_wifiiot_app_vercfg.bin         # 安全启动配置boot和kernel版本号,防版本回滚
    ├── libs                                  # 库文件夹
    ├── NOTICE_FILE
    ├── obj
    ├── suites
    └── toolchain.ninja
    ```

    注:烧写文件,烧写程序建议使用"Hi3861\_wifiiot\_app\_allinone.bin"。

    运行"python build.py ipcamera\_hi3518ev300 -b debug",编译ipcamera\_hi3518ev300完成后,会有如下结果生成\(同ipcamera\_hi3516dv300\):

    ```
    out/
    └── ipcamera_hi3518ev300            # 产品名
    ├── args.gn                         # gn编译,用户自定义变量
    ├── bin                             # 链接bin所在文件夹
    ├── bm_tool.map                     # map文件
    ├── build.log                       # 编译日志
    ├── build.ninja
    ├── build.ninja.d
    ├── bundle_daemon_tool.map          # map文件
    ├── data                            # 媒体camera依赖底层资源配置文件
    ├── dev_tools                       # 研发自测试
    ├── foundation.map                  # map文件
    ├── gen
    ├── libaudio_api.so
    ├── libs                            # 镜像包含库文件
    ├── liteos.bin                      # liteos基础内核bin文件
    ├── media_server.map                # map文件
    ├── NOTICE_FILE
    ├── obj                             # 二进制文件,编译结果文件夹
    ├── OHOS_Image                      # liteos整包bin文件,未strip
    ├── OHOS_Image.asm                  # 汇编代码
    ├── OHOS_Image.bin                  # liteos整包烧录bin文件
    ├── OHOS_Image.map                  # map文件
    ├── rootfs.img                      # 编译出的库和app的镜像
    ├── rootfs.tar                      # rootfs的压缩
    ├── suites                          # xts编译结果
    ├── test                            # 测试用例编译结果
    ├── toolchain.ninja
    ├── userfs                          # 用户可读写的分区
    ├── userfs.img                      # img格式的用户可读写的分区,对应启动之后的/storage目录
    └── vendor                          # 芯片的Firmware文件及配置文件
    ```