往期鸿蒙全套实战精彩文章必看内容:
- 鸿蒙开辟核心知识点,看这篇文章就够了
- 最新版!鸿蒙HarmonyOS Next应用开辟实战学习路线
- 鸿蒙HarmonyOS NEXT开辟技术最全学习路线指南
- 鸿蒙应用开辟实战项目,看这一篇文章就够了(部分项目附源码)
简介
CMake是一个跨平台的构建工具,用于管理构建过程、编译、链接和打包软件项目,它可以天生Makefile等用于不同操作体系和编译器的构建脚本。CMake的配置过程是跨平台的,因此可以在不同的操作体系上运行,比方Linux、Windows和macOS。
CMake构建过程可分为以下三个主要步骤:
- 配置(Configuration):配置阶段是CMake剖析CMakeLists.txt文件的过程。在配置阶段,CMake会读取CMakeLists.txt文件,并执行其中的下令。CMakeLists.txt文件是CMake的核心,其界说了项目的构建规则和依赖关系。
- 天生(Generation):天生阶段是CMake根据配置阶段的效果,天生实际构建文件的过程。在天生阶段,CMake会将CMakeLists.txt文件中界说的构建规则和依赖关系转为构建工具可以明白的形式。
- 构建(Build):构建阶段是使用构建工具(如Make或DevEco Studio)根据天生的构建文件,编译源代码并链接天生目标文件的过程。在构建阶段,构建工具会读取天生的构建文件,按照其中界说的规则和依赖关系,执行实际的编译和链接操作。
CMake构建三方库适配流程
本末节先容怎样在Linux环境下,使用CMake构建工具通过ohos sdk编译cJSON三方库源码,天生ohos平台三方库的so及二进制文件。
环境准备
- 首先需要Linux编译环境。 开辟者可以选择熟悉的发行版来进行环境搭建,这里以Ubuntu为例,Ubuntu目前主要支持Ubuntu18.04和Ubuntu20.04(Ubuntu22.04暂不支持)。
- HarmonyOS SDK镜像下载:从DevEco Studio的SDK Manager中获取SDK,或通过CI平台进行下载。
- tar -zxvf解压SDK文件。随着版本更新,SDK版本大概会有变更,开辟者可自行下载最新版本,此处以4.0.10.5版本为例。
- owner@ubuntu:/mnt/e/ohosSDK$ tar -zxvf version-Master_Version-OpenHarmony_4.0.10.5-20230824_120921-ohos-sdk-public_monthly.tar.gz
复制代码 - 进入到SDK的linux目录,解压工具包。
- owner@ubuntu:/mnt/e/ohosSDK$ cd ohos-sdk/linux
- owner@ubuntu:/mnt/e/ohosSDK/ohos-sdk/linux$ for i in *.zip;do unzip ${i};done # 通过for循环一次解压所有的工具包
- owner@ubuntu:/mnt/e/ohosSDK/ohos-sdk/linux$ ls
- ets native toolchains
- ets-linux-x64-4.0.10.5-Release.zip native-linux-x64-4.0.10.5-Release.zip toolchains-linux-x64-4.0.10.5-Release.zip
- js previewer
- js-linux-x64-4.0.10.5-Release.zip previewer-linux-x64-4.0.10.5-Release.zip
复制代码 - 获取三方库源码(适配三方库假如没有指定版本,一样寻常取三方库最新版本)。
- owner@ubuntu:/mnt/e/cmake$ git clone https://github.com/DaveGamble/cJSON.git -b v1.7.18 # 通过git下载指定版本的源码
- Cloning into 'cJSON'...
- remote: Enumerating objects: 4545, done.
- remote: Total 4545 (delta 0), reused 0 (delta 0), pack-reused 4545
- Receiving objects: 100% (4545/4545), 2.45 MiB | 1.65 MiB/s, done.
- Resolving deltas: 100% (3026/3026), done.
- Note: switching to 'd348621ca93571343a56862df7de4ff3bc9b5667'.
- You are in 'detached HEAD' state. You can look around, make experimental
- changes and commit them, and you can discard any commits you make in this
- state without impacting any branches by switching back to a branch.
- If you want to create a new branch to retain commits you create, you may
- do so (now or later) by using -c with the switch command. Example:
- git switch -c <new-branch-name>
- Or undo this operation with:
- git switch -
- Turn off this advice by setting config variable advice.detachedHead to false
复制代码 编译三方库
- 新建编译目录。 为防止污染源码目录文件,推荐在三方库源码目录新建一个编译目录,用于天生需要编译的配置文件。
本用例中在cJSON目录下新建一个build目录:
- owner@ubuntu:/mnt/e/cmake$ cd cJSON-1.7.18 # 进入cJSON目录
- owner@ubuntu:/mnt/e/cmake/cJSON-1.7.18$ mkdir build && cd build # 创建编译目录并进入到编译目录
- owner@ubuntu:/mnt/e/cmake/cJSON-1.7.18/build$
复制代码 - 执行cmake编译下令,配置交叉编译参数,天生Makefile。
- owner@ubuntu:/mnt/e/cmake/cJSON-1.7.18/build$ /xxx/ohos-sdk/linux/native/build-tools/cmake/bin/cmake -DCMAKE_TOOLCHAIN_FILE=/xxx/ohos-sdk/linux/native/build/cmake/ohos.toolchain.cmake -DCMAKE_INSTALL_PREFIX=/xxx/cJSON -DOHOS_ARCH=arm64-v8a .. -L # 执行cmake命令
- -- The C compiler identification is Clang 12.0.1
- -- Check for working C compiler: /mnt/e/ohosSDK/ohos-sdk/linux/native/llvm/bin/clang # 采用sdk内的编译器
- -- Check for working C compiler: /mnt/e/ohosSDK/ohos-sdk/linux/native/llvm/bin/clang -- works
- ...
- # 省略部分cmake信息
- ...
- ENABLE_PUBLIC_SYMBOLS:BOOL=ON
- ENABLE_SAFE_STACK:BOOL=OFF
- ENABLE_SANITIZERS:BOOL=OFF
- ENABLE_TARGET_EXPORT:BOOL=ON
- ENABLE_VALGRIND:BOOL=OFF
- owner@ubuntu:/mnt/e/cmake/cJSON-1.7.18/build$ ls # 执行完cmake成功后在当前目录生成Makefile文件
- cJSONConfig.cmake cJSONConfigVersion.cmake CMakeCache.txt CMakeFiles cmake_install.cmake CTestTestfile.cmake fuzzing libcjson.pc Makefile tests
复制代码 参数阐明:
- CMAKE_TOOLCHAIN_FILE:交叉编译配置文件路径,设置为ohos工具链配置文件。
- CMAKE_INSTALL_PREFIX:配置安装三方库路径。
- OHOS_ARCH: 配置交叉编译的CPU架构,一样寻常为arm64-v8a(编译64位的三方库)或armeabi-v7a(编译32位的三方库),本示例中设置编译为64位的cJSON库。
- -L: 体现cmake中可配置项目。
部分文件产物阐明:
- Makefile:构建项目的Makefile文件,包含了编译、链接等指令。
- CMakeCache.txt:CMake的缓存文件,记录了CMake的配置选项和变量信息。
- CMakeFiles:CMake的临时文件目录,包含了一些中央文件和构建信息,方便后续重新天生Makefile时使用。
- cmake_install.cmake:安装规则文件,用于执行安装操作,将编译好的文件安装到指定的目录下。
- CTestTestfile.cmake:用于执行测试的CMake脚本文件,方便进行自动化测试。
- 执行编译。 执行make对cJSON进行编译:
- owner@ubuntu:/mnt/e/cmake/cJSON-1.7.18/build$ make # 执行make命令进行编译
- Scanning dependencies of target cjson
- [ 2%] Building C object CMakeFiles/cjson.dir/cJSON.c.o
- clang: warning: argument unused during compilation: '--gcc-toolchain=/mnt/e/ohosSDK/ohos-sdk/linux/native/llvm' [-Wunused-command-line-argument]
- /mnt/e/cmake/cJSON-1.7.18/cJSON.c:561:9: warning: 'long long' is an extension when C99 mode is not enabled [-Wlong-long]
- ...
- # 省略部分make信息
- ...
- clang: warning: argument unused during compilation: '--gcc-toolchain=/mnt/e/ohosSDK/ohos-sdk/linux/native/llvm' [-Wunused-command-line-argument]
- [ 97%] Building C object fuzzing/CMakeFiles/fuzz_main.dir/cjson_read_fuzzer.c.o
- clang: warning: argument unused during compilation: '--gcc-toolchain=/mnt/e/ohosSDK/ohos-sdk/linux/native/llvm' [-Wunused-command-line-argument]
- [100%] Linking C executable fuzz_main
- [100%] Built target fuzz_main
复制代码 - 获取编译完成后的文件。 编译成功后开辟者可以通过file下令检察文件的属性,以此判定交叉编译是否成功,如下信息体现libcjson.so为aarch64架构文件,即交叉编译成功:
- owner@ubuntu:/mnt/e/cmake/cJSON-1.7.18/cJSON/build$ file libcjson.so.1.7.18 # 查看文件属性命令
- libcjson.so.1.7.18: ELF 64-bit LSB shared object, ARM aarch64, version 1 (SYSV), dynamically linked, BuildID[sha1]=a79e4b52a332702b4853f2d6cac2fcd7dff95023, with debug_info, not stripped
复制代码 - 执行安装下令。编译成功后,执行make install将编译好的二进制文件以及头文件安装到cmake配置的安装路径下:
- owner@ubuntu:/mnt/e/cmake/cJSON-1.7.18/cJSON/build$ make install # 执行安装命令
- [ 4%] Built target cjson
- [ 8%] Built target cJSON_test
- ...
- # 省略部分make install信息
- ...
- -- Installing: /mnt/e/cmake/cJSON-1.7.18/cJSON/lib/cmake/cJSON/cJSONConfig.cmake
- -- Installing: /mnt/e/cmake/cJSON-1.7.18/cJSON/lib/cmake/cJSON/cJSONConfigVersion.cmake
- owner@ubuntu:/mnt/e/cmake/cJSON-1.7.18/cJSON/build$
复制代码- owner@ubuntu:/mnt/e/cmake/cJSON-1.7.18/build$ ls /mnt/e/cmake/cJSON-1.7.18/cJSON # 查看安装文件
- include lib
- owner@ubuntu:/mnt/e/cmake/cJSON-1.7.18/build$ ls /mnt/e/cmake/cJSON-1.7.18/cJSON/lib
- cmake libcjson.so libcjson.so.1 libcjson.so.1.7.18 pkgconfig
复制代码 测试验证
交叉编译完后,需要对三方库进行测试验证。为保证三方库功能的完整性,需要基于原生库的测试用例进行测试验证。为此,需要集成一套可以在OH环境上进行make、cmake、 ctest等操作的工具,详细步骤如下:
- 搭建ohos测试环境: 首先要明确需要的工具,如:camke、make、busybox、perl、shell_cmd等。
- busybox:是一个Unix工具聚集,其提供一系列的下令和工具,方便开辟职员在资源受限的环境中进行体系配置和维护。
- perl:是一种通用、直译式、动态的步调语言,具有强盛的文本处理能力,实用于文本处理和各种编程使命。
- shell_cmd:是用户向体系内核发出控制哀求,与之交互的文本流,shell是一个下令行表明器,将用户下令剖析为操作体系所能明白的指令,实现用户与操作体系的交互。
下载工具源码并进行编译,将工具编译完成后天生的二进制文件拷贝到ohos设备,配置测试环境。
- 将工具包上传进ohos设备的/data目录。
- # 发送到ohos设备的/data目录
- hdc file send xxx\arm_cmake_make.tar.gz /data
- hdc file send xxx\arm_busybox.tar.gz /data
- hdc file send xxx\arm_perl.tar.gz /data
- hdc file send xxx\arm_shell_cmd.tar.gz /data
复制代码 - 进入ohos设备,手动配置环境。
- # 进入ohos设备命令行终端
- hdc shell
- # 根目录挂载 读写权限
- mount -o remount,rw /
- # 创建/usr目录
- mkdir /usr
- # 进入/data目录
- cd /data
- # 解压所有工具压缩包
- tar -zxvf *.tar.gz
- # 拷贝cmake make perl shell工具二进制到/usr目录
- cp -rf arm_cmake_make/* /usr
- cp -rf arm_perl/* /usr
- cp -rf arm_shell_cmd/* /usr
- # 验证
- cmake -version
- make -v
- perl -v
- # 拷贝busybox工具到/bin
- cp -rf arm_busybox/bin/busybox /bin
- # 将toybox替换为busybox
- cd /bin
- mv toybox toybox_bak
- # toybox被改为toybox_bak后, 导致原来的命令无法直接使. 需要采用"toybox_bak xxxcmd"的模式使用, 如下
- toybox_bak mv busybox toybox
- # 验证
- diff -v
- # toybox原本是不支持diff命令,这里可以直接使用diff是因为toybox已经创建了diff的软连接, 但是toybox并没有真正实现. 因此替换为编译的busybox
- # 基本的环境搭建完成
复制代码
- 准备测试资源。 使用原生库的测试用例进行测试,为了保证测试时不进行编译操作,需要把整个编译的源码作为测试资源包推送到开辟板,且需要保证三方库在开辟板的路径与编译时路径一致。
- owner@ubuntu:/mnt/e/cmake$ tar -zcf cJSON-1.7.18.tar.gz cJSON-1.7.18/
复制代码 打包完资源后,需要将资源通过hdc下令推送到开辟板:
- hdc file send xxx/cJSON-1.7.18.tar.gz /data/ # 推送资源到开发板
- hdc shell # 进入开发板系统
- # mkdir -p /mnt/e # 设置与编译时同样的路径
- # cd /mnt/e
- # ln -s /data/cJSON-1.7.18 ./cmake # 系统根目录空间有限,建议通过软链接配置路径
- # cd cmake
- # tar -zxf cJSON-1.7.18.tar.gz # 解压测试资源
复制代码 - 执行测试。 进入到cJSON的编译目录build,执行ctest测试下令进行测试:
- # cd xxx/cJSON-1.7.18/build
- # ctest # 执行ctest测试命令,以下为测试信息
- Test project /data/cJSON-1.7.18/cJSON/build
- Start 1: cJSON_test
- 1/19 Test #1: cJSON_test ....................... Passed 0.02 sec
- Start 2: parse_examples
- 2/19 Test #2: parse_examples ................... Passed 0.02 sec
- Start 3: parse_number
- 3/19 Test #3: parse_number ..................... Passed 0.02 sec
- Start 4: parse_hex4
- 4/19 Test #4: parse_hex4 ....................... Passed 0.10 sec
- Start 5: parse_string
- 5/19 Test #5: parse_string ..................... Passed 0.01 sec
- Start 6: parse_array
- 6/19 Test #6: parse_array ...................... Passed 0.01 sec
- Start 7: parse_object
- 7/19 Test #7: parse_object ..................... Passed 0.01 sec
- Start 8: parse_value
- 8/19 Test #8: parse_value ...................... Passed 0.01 sec
- Start 9: print_string
- 9/19 Test #9: print_string ..................... Passed 0.01 sec
- Start 10: print_number
- 10/19 Test #10: print_number ..................... Passed 0.01 sec
- Start 11: print_array
- 11/19 Test #11: print_array ...................... Passed 0.01 sec
- Start 12: print_object
- 12/19 Test #12: print_object ..................... Passed 0.01 sec
- Start 13: print_value
- 13/19 Test #13: print_value ...................... Passed 0.01 sec
- Start 14: misc_tests
- 14/19 Test #14: misc_tests ....................... Passed 0.01 sec
- Start 15: parse_with_opts
- 15/19 Test #15: parse_with_opts .................. Passed 0.01 sec
- Start 16: compare_tests
- 16/19 Test #16: compare_tests .................... Passed 0.01 sec
- Start 17: cjson_add
- 17/19 Test #17: cjson_add ........................ Passed 0.01 sec
- Start 18: readme_examples
- 18/19 Test #18: readme_examples .................. Passed 0.01 sec
- Start 19: minify_tests
- 19/19 Test #19: minify_tests ..................... Passed 0.01 sec
- 100% tests passed, 0 tests failed out of 19
- Total Test time (real) = 0.37 sec
复制代码 由以上测试效果可以看出,测试用例未出现错误,当前测试成功。
常见题目
执行ctest进行测试时,报如下错误:
解决措施
大概缘故原由为三方库源码文件推送到开辟板时的路径,与编译时的路径不一致导致。
推送路径和编译路径需要保持一致,或者参考测试流程,在文件推送到开辟板后,通过配置软链接方式使路径保持一致,再执行ctest进行测试。
看完三件事❤️
- 假如你觉得这篇内容对你还蛮有帮助,我想约请你帮我三个小忙:
- 点赞,转发,有你们的 『点赞和评论』,才是我创造的动力。
- 关注作者 ,不定期分享原创知识。
- 同时可以等待后续文章ing
|