porting-thirdparty-cmake.md 10.9 KB
Newer Older
D
duangavin123 已提交
1
# CMake方式组织编译的库移植
Y
yangni 已提交
2 3


D
duangavin123 已提交
4
以double-conversion库为例,其移植过程如下文所示。
Y
yangni 已提交
5 6


D
duangavin123 已提交
7
## 源码获取
Y
yangni 已提交
8 9 10

从仓库[获取double-conversion源码](https://github.com/google/double-conversion),其目录结构如下表:

D
duangavin123 已提交
11 12
  **表1** 源码目录结构

D
duangavin123 已提交
13
| 名称 | 描述 |
D
duangavin123 已提交
14
| -------- | -------- |
D
duangavin123 已提交
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| double-conversion/cmake/ | CMake组织编译使用到的模板 |
| double-conversion/double-conversion/ | 源文件目录 |
| double-conversion/msvc/ | - |
| double-conversion/test/ | 测试用例源文件 |
| double-conversion/.gitignore | - |
| double-conversion/AUTHORS | - |
| double-conversion/BUILD | - |
| double-conversion/CMakeLists.txt | CMake方式顶层编译组织文件 |
| double-conversion/COPYING | - |
| double-conversion/Changelog | - |
| double-conversion/LICENSE | - |
| double-conversion/Makefile | - |
| double-conversion/README.md | - |
| double-conversion/SConstruct | - |
| double-conversion/WORKSPACE | - |
D
duangavin123 已提交
30 31 32


## 移植思路
Y
yangni 已提交
33 34 35 36

移植思路:通过修改工具链,交叉编译该三方库,生成OpenHarmony平台的可执行文件,最后再通过GN调用CMake的方式添加到OpenHarmony工程中。


D
duangavin123 已提交
37
## 交叉编译
Y
yangni 已提交
38 39


D
duangavin123 已提交
40
### 编译参考
Y
yangni 已提交
41

D
duangavin123 已提交
42
代码仓库的[README.md](https://github.com/google/double-conversion/blob/master/README.md)中详细介绍了使用CMake编译double-conversion库的步骤,以及测试方法。本文参考该指导设置该库的编译配置,并完成测试。若开发人员在移植过程中对该库的编译选项配置有疑惑的地方,可参考该指导。对于其他使用CMake可独立编译的三方库,在移植时可以参考其自带的编译指导。
Y
yangni 已提交
43 44


D
duangavin123 已提交
45 46 47
### 设置执行交叉编译

CMake方式可通过指定工具链进行交叉编译,修改并编译该库,生成OpenHarmony平台的可执行文件,步骤如下:
Y
yangni 已提交
48

D
duangavin123 已提交
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
1. 设置工具链
     将下列clang工具链配置添加到该工程的顶层CMakeLists.txt(即表1中的该文件)中即可。
     
   ```
   set(CMAKE_CROSSCOMPILING TRUE)
   set(CMAKE_SYSTEM_NAME Generic)
   set(CMAKE_CXX_COMPILER_ID Clang)
   set(CMAKE_TOOLCHAIN_PREFIX llvm-)
   #指定c编译工具(确保工具链所在路径已经添加到了PATH环境变量中)和编译标志,使用clang编译时标志中必须指定--target,否则无法交叉编译。
   set(CMAKE_C_COMPILER clang)
   set(CMAKE_C_FLAGS "--target=arm-liteos -D__clang__ -march=armv7-a -w -mfloat-abi=softfp -mcpu=cortex-a7 -mfpu=neon-vfpv4")
   #指定c++编译工具(确保工具链所在路径已经添加到了PATH环境变量中)和编译标志,必须指定--target,否则无法交叉编译。
   set(CMAKE_CXX_COMPILER clang++) 
   set(CMAKE_CXX_FLAGS "--target=arm-liteos -D__clang__ -march=armv7-a -w -mfloat-abi=softfp -mcpu=cortex-a7 -mfpu=neon-vfpv4")
   #指定链接工具和链接标志,必须指定--target和--sysroot,其中OHOS_ROOT_PATH可通过cmake命令后缀参数来指定。
   set(MY_LINK_FLAGS "--target=arm-liteos --sysroot=${OHOS_SYSROOT_PATH}")
   set(CMAKE_LINKER clang)
   set(CMAKE_CXX_LINKER clang++)
   set(CMAKE_C_LINKER clang)
   set(CMAKE_C_LINK_EXECUTABLE
       "${CMAKE_C_LINKER} ${MY_LINK_FLAGS} <FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>")
   set(CMAKE_CXX_LINK_EXECUTABLE
       "${CMAKE_CXX_LINKER} ${MY_LINK_FLAGS} <FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>")
   #指定链接库的查找路径。
   set(CMAKE_SYSROOT ${OHOS_SYSROOT_PATH})
   ```

2. 执行编译
   linux命令行中进入double-conversion的源文件目录(即标1所示目录),执行下列命令:

D
duangavin123 已提交
79
   
D
duangavin123 已提交
80 81 82 83 84 85 86 87 88 89 90 91 92
   ```
   mkdir build && cd build
   cmake .. -DBUILD_TESTING=ON -DOHOS_SYSROOT_PATH="..."
   make -j
   ```

   其中OHOS_SYSROOT_PATH需用绝对路径指定出sysroot目录的位置,以OpenHarmony为例即目录out/hispark_xxx/ipcamera_hispark_xxx/sysroot的绝对路径。上述目录会在全量编译后生成,因此移植前先完成一次全量编译。

3. 查看结果
   步骤2操作完成后,build目录下会生成静态库文件和测试用例:

     **表2** 编译生成文件目录结构
   
D
duangavin123 已提交
93
   | 名称 | 描述 |
D
duangavin123 已提交
94
   | -------- | -------- |
D
duangavin123 已提交
95 96 97 98 99 100 101 102 103 104
   | double-conversion/build/libdouble-conversion.a | 生成的静态库文件 |
   | double-conversion/build/test/ | 目录下存放生成的测试用例和相关CMake缓存文件 |
   | double-conversion/build/CMakeCache.txt | CMake构建过程中的缓存文件 |
   | double-conversion/build/CMakeFiles/ | - |
   | double-conversion/build/cmake_install.cmake | - |
   | double-conversion/build/CTestTestfile.cmake | - |
   | double-conversion/build/DartConfiguration.tcl | - |
   | double-conversion/build/generated/ | - |
   | double-conversion/build/Makefile | - |
   | double-conversion/build/Testing/ | - |
D
duangavin123 已提交
105 106 107 108 109


## 测试

1. 搭建OpenHarmony环境
D
duangavin123 已提交
110
   以Hi3516DV300为例,编译出OpenHarmony镜像,烧写到开发板,相关操作可参考[快速入门小型系统部分](../quick-start/Readme-CN.md)
D
duangavin123 已提交
111 112 113 114 115 116 117 118 119 120 121 122 123 124 125

   进入系统如下所示:

     **图1** OpenHarmony启动成功界面

     ![zh-cn_image_0000001218806027](figures/zh-cn_image_0000001218806027.png)

2. 挂载nfs目录,将表2中test目录下cctest可执行文件放入nfs目录

3. 执行用例
   该库采用非交叉编译时用例是通过make test执行,CMake会有相关的执行结果统计;交叉编译时无法使用该方法,因此可直接执行生成的测试文件完成测试。

   - 挂载成功后执行下列命令可列出用例所有条目:

     
126 127 128 129
     ```
     cd nfs
     ./cctest --list
     ```
D
duangavin123 已提交
130

131
     上述命令执行结果部分展示:
D
duangavin123 已提交
132

D
duangavin123 已提交
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
     ```
     test-bignum/Assign<
     test-bignum/ShiftLeft<
     test-bignum/AddUInt64<
     test-bignum/AddBignum<
     test-bignum/SubtractBignum<
     test-bignum/MultiplyUInt32<
     test-bignum/MultiplyUInt64<
     test-bignum/MultiplyPowerOfTen<
     test-bignum/DivideModuloIntBignum<
     test-bignum/Compare<
     test-bignum/PlusCompare<
     test-bignum/Square<
     test-bignum/AssignPowerUInt16<
     test-bignum-dtoa/BignumDtoaVariousDoubles<
     test-bignum-dtoa/BignumDtoaShortestVariousFloats<
     test-bignum-dtoa/BignumDtoaGayShortest<
     test-bignum-dtoa/BignumDtoaGayShortestSingle<
     test-bignum-dtoa/BignumDtoaGayFixed<
     test-bignum-dtoa/BignumDtoaGayPrecision<
     test-conversions/DoubleToShortest<
     test-conversions/DoubleToShortestSingle<
     ...
     ```
D
duangavin123 已提交
158 159 160 161

   - 以test-bignum条目为例,执行下列命令开始测试:

     
162 163 164
     ```
     ./cctest test-bignum
     ```
D
duangavin123 已提交
165

166
     测试结果如下则表示通过:
D
duangavin123 已提交
167 168

     
169 170 171
     ```
     Ran 13 tests.
     ```
D
duangavin123 已提交
172 173 174 175 176 177 178 179 180


## 将该库编译添加到OpenHarmony工程中

1. 复制库到OpenHarmony工程中
   拷贝已经能够成功交叉编译的库到OpenHarmony的third_party目录,为了不修改要移植的三方库目录下的BUILD.gn文件,再添加一层目录放置新增的gn转CMake编译适配文件,新增的文件有BUILD.gn、build_thirdparty.py、 config.gni,新增后的目录结构如下所示。

     **表3** 添加到工程后的目录结构
   
D
duangavin123 已提交
181
   | 名称 | 描述 |
D
duangavin123 已提交
182
   | -------- | -------- |
D
duangavin123 已提交
183 184 185 186
   | OpenHarmony/third_party/double-conversion/BUILD.gn | 将三方库加入工程的gn适配文件 |
   | OpenHarmony/third_party/double-conversion/build_thirdparty.py | GN调用shell命令脚本文件,由上面GN文件将相关命令传入,实现GN转CMake |
   | OpenHarmony/third_party/double-conversion/config.gni | 三方库编译配置文件,可修改该文件来配置用例是否参与构建等 |
   | OpenHarmony/third_party/double-conversion/double-conversion/ | 要移植的三方库目录 |
D
duangavin123 已提交
187 188 189 190 191

2. 添加gn到CMake适配文件
   - **新增的BUILD.gn文件实现如下,其他采用CMake方式可独立编译的三方库移植到OpenHarmony平台时只需修改路径即可**

     
192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211
     ```
     import("config.gni")
     group("double-conversion") {
         if (ohos_build_thirdparty_migrated_from_fuchisa == true) {
             deps = [":make"]
         }
     }
     if (ohos_build_thirdparty_migrated_from_fuchisa == true) {
         action("make") {
             script = "//third_party/double-conversion/build_thirdparty.py"
             outputs = ["$root_out_dir/log_dc.txt"]
             exec_path = rebase_path(rebase_path("./build", ohos_third_party_dir))
             command = "rm * .* -rf && $CMAKE_TOOLS_PATH/cmake .. $CMAKE_FLAG $CMAKE_TOOLCHAIN_FLAG && make -j"
             args = [
                 "--path=$exec_path",
                 "--command=${command}"
             ]
         }
     }
     ```
D
duangavin123 已提交
212 213 214 215

   - **新增的config.gni用于配置该库,实现如下,其他采用CMake方式可独立编译的三方库移植到OpenHarmony时只需修改CMAKE_FLAG的配置即可。**

     
216 217 218
     ```
     #CMAKE_FLAG: config compile feature
     CMAKE_FLAG = "-DBUILD_TESTING=ON -DCMAKE_CXX_STANDARD=11"
D
duangavin123 已提交
219
   
220 221
     #toolchain:follow up-layer,depend on $ohos_build_compiler
     if (ohos_build_compiler == "clang") {
A
arvinzzz 已提交
222
         CMAKE_TOOLCHAIN_FLAG = "-DOHOS_SYSROOT_PATH=${root_out_dir}sysroot"
223 224 225
     } else {
         CMAKE_TOOLCHAIN_FLAG = ""
     }
D
duangavin123 已提交
226
   
227 228 229
     #CMake tools path,no need setting if this path already joined to $PATH.
     CMAKE_TOOLS_PATH = "setting CMake tools path..."
     ```
D
duangavin123 已提交
230 231 232 233

   - **新增的build_thirdparty.py实现如下,其他采用CMake方式可独立编译的三方库移植到OpenHarmony时无需修改即可使用。**

     
234 235 236 237 238 239
     ```
     import os
     import sys
     from subprocess import Popen
     import argparse
     import shlex
D
duangavin123 已提交
240
   
241 242 243 244 245 246 247
     def cmd_exec(command):
         cmd = shlex.split(command)
         proc = Popen(cmd)
         proc.wait()
         ret_code = proc.returncode
         if ret_code != 0:
             raise Exception("{} failed, return code is {}".format(cmd, ret_code))
D
duangavin123 已提交
248
   
249 250 251 252 253 254
     def main():
         parser = argparse.ArgumentParser()
         parser.add_argument('--path', help='Build path.')
         parser.add_argument('--command', help='Build command.')
         parser.add_argument('--enable', help='enable python.', nargs='*')
         args = parser.parse_args()
D
duangavin123 已提交
255
   
256 257
         if args.enable:
             if args.enable[0] == 'false':
D
duangavin123 已提交
258 259
               return
   
260 261 262 263 264 265 266
         if args.path:
             curr_dir = os.getcwd()
             os.chdir(args.path)
             if args.command:
                 if '&&' in args.command:
                     command = args.command.split('&&')
                     for data in command:
D
duangavin123 已提交
267 268 269 270 271
                       cmd_exec(data)
               else:
                   cmd_exec(args.command)
           os.chdir(curr_dir)
   
272 273 274
      if __name__ == '__main__':
         sys.exit(main())
     ```
D
duangavin123 已提交
275 276 277

   - 在配置文件中添加开关控制该库编译,默认设为关闭

278
     在//build/lite/ohos_var.gni文件中添加下列配置:
D
duangavin123 已提交
279 280

     
281 282 283 284 285
     ```
     declare_args() {
         ohos_build_thirdparty_migrated_from_fuchisa = true
      }
     ```
D
duangavin123 已提交
286 287

3. 编译构建
288
   手动单独构建:
D
duangavin123 已提交
289 290 291

   执行下列命令

D
duangavin123 已提交
292
   
D
duangavin123 已提交
293 294 295 296 297
   ```
   hb build -T //third_party/double-conversion:double-conversion
   ```

   编译成功则build目录下会生成静态库文件和测试用例