1# 使用CMake与OHOS NDK编译三方库 2 3OHOS NDK支持通过工具链使用CMake编译C/C++代码,工具链文件是用于自定义交叉编译工具链行为的 CMake 文件。OHOS NDK使用的编译工具链在OHOS SDK目录下的位置:`native/build/cmake/ohos.toolchain.cmake`。 4使用命令行进行CMake编译时,需要指定工具链文件ohos.toolchain.cmake所在路径。 5本文介绍CMake与OHOS NDK搭配如何使用。 6 7## OpenHarmony NDK获取方式 8 91. 获取已发布版本,参考:[OpenHarmony Release Notes](https://gitee.com/openharmony/docs/tree/master/zh-cn/release-notes#openharmony-release-notes),选择对应版本,在“从镜像站点获取”小节下载对应版本SDK包,NDK包含在SDK包中。 102. 获取每日构建版本,每日构建地址:[OpenHarmony dailybuilds](http://ci.openharmony.cn/workbench/cicd/dailybuild/dailylist),在每日构建形态组件中选择"ohos-sdk",下载对应SDK包,NDK包含在SDK包中。 11 123. 获取源码构建版本,参考:[sourcecode acquire](https://gitee.com/openharmony/docs/blob/master/zh-cn/device-dev/get-code/sourcecode-acquire.md),下载OpenHarmony源码,执行以下命令编译SDK: 13(1)若首次编译OpenHarmony源码,需要安装依赖:`./build/build_scripts/env_setup.sh`, 完成后执行:`source ~/.bashrc` 14 (2)下载预编译工具链:`./build/prebuilts_download.sh` 15 (3)编译SDK:`./build.sh --product-name ohos-sdk` 16 (4)生成SDK所在路径:`out/sdk/packages` 17 18## OpenHarmony NDK说明 19 20SDK包中native所在目录即是NDK,目录如下: 21 22``` 23native 24 ├── build 25 │ └── cmake 26 │ ├── ohos.toolchain.cmake # 编译的工具链 27 │ └── sdk_native_platforms.cmake 28 ├── build-tools # cmake编译工具所在目录 29 ├── docs 30 ├── llvm # llvm编译器工具链 31 ├── nativeapi_syscap_config.json # NDK提供的SystemCapability的相关头文件 32 ├── ndk_system_capability.json # NDK提供的SystemCapability的描述文件 33 ├── oh-uni-package.json # 版本信息 34 ├── NOTICE.txt 35 └── sysroot 36``` 37 38* build目录 39 build目录下的ohos.toolchain.cmake是工具链文件,使用CMake编译时,需要指定工具链文件ohos.toolchain.cmake所在路径。cmake编译时需要读取该文件中的默认值,比如编译器的选择、编译平台。 40* build-tools 41 build-tools目录下是NDK自带的cmake编译工具,配置编译环境时需要添加cmake路径 42* llvm 43 llvm目录是OHOS NDK提供的编译器工具 44 45 46## 环境配置 47 48### linux 49 50将OHOS NDK自带的build-tools目录下cmake工具添加到环境变量 51 52``` 53# 打开.bashrc文件 54vim ~/.bashrc 55# 在文件最后添加cmake路径,该路径是自己的放置文件的路径,之后保存退出 56export PATH=${OHOS SDK路径}/ohos-sdk/linux/native/build-tools/cmake/bin:$PATH 57# 在命令行执行source ~/.bashrc使环境变量生效 58source ~/.bashrc 59``` 60 61使用`which cmake`和`cmake --version`验证是否生效。 62 63### windows 64 65右键点击我的电脑,在下拉框中选择我的电脑,点击高级系统设置,点击环境变量,点击Path后点编辑,点击新建,将路径添加进去。 66 67 68使用`cmake --version`验证是否生效。 69 70 71## CMake编译 72 73使用CMake编译时,需要指定工具链文件,同时还需要指定OHOS平台的参数 74常用参数如下: 75 76| 参数 | 类型 | 备注 | 77| ------------------------ | ------------------------- | ------------------- | 78| OHOS_STL | c++_shared/c++_static | 默认是c++_shared | 79| OHOS_ARCH | armeabi-v7a | 设置ABI | 80| OHOS_PLATFORM | OHOS | 平台选择 | 81| CMAKE_TOOLCHAIN_FILE | 工具链文件 | - | 82 83### linux 84 85#### 创建demo工程 86 87工程目录 88 89``` 90├── CMakeLists.txt 91└── src 92 ├── CMakeLists.txt 93 └── hello.cpp 94``` 95 96外部 CMakeLists.txt内容: 97 98``` 99#cmake的版本 100CMAKE_MINIMUM_REQUIRED(VERSION 3.16) 101#工程名称 102PROJECT(HELLO) 103#添加一个子目录并构建该子目录。 104ADD_SUBDIRECTORY(src bin) 105``` 106 107src目录下源码文件hello.cpp内容: 108 109```cpp 110#include <iostream> 111 112int main(int argc,const char **argv) 113{ 114 std::cout<< "hello world!" <<std::endl; 115 return 0; 116} 117``` 118 119src目录下CMakeLists.txt内容: 120 121``` 122SET(LIBHELLO_SRC hello.cpp) 123 124#添加静态库 125ADD_LIBRARY(hello_static STATIC ${LIBHELLO_SRC}) 126#将静态库的名字hello_static修改为hello 127SET_TARGET_PROPERTIES(hello_static PROPERTIES OUTPUT_NAME "hello") 128 129#添加动态库 130ADD_LIBRARY(hello SHARED ${LIBHELLO_SRC}) 131#将动态库的名字修改为hello 132SET_TARGET_PROPERTIES(hello PROPERTIES OUTPUT_NAME "hello") 133 134#生成可执行程序 135ADD_EXECUTABLE(Hello ${LIBHELLO_SRC}) 136``` 137 138#### 编译 139 140使用OHOS_STL=c++_shared动态编译: 141 142``` 143# 在demo工程目录下创建build目录,用于存放cmake构建过程中的中间文件 144step1:mkdir build && cd build 145# 传递参数给CMake 146step2:cmake -DOHOS_STL=c++_shared -DOHOS_ARCH=armeabi-v7a -DOHOS_PLATFORM=OHOS -DCMAKE_TOOLCHAIN_FILE=${OHOS SDK路径}/ohos-sdk/linux/native/build/cmake/ohos.toolchain.cmake .. 147# 执行cmake构建命令 148step3:cmake --build . 149``` 150 151构建成功build/bin目录下的产物 152 153``` 154build/bin 155├── CMakeFiles 156├── cmake_install.cmake 157├── Hello 158├── libhello.a 159├── libhello.so 160└── Makefile 161``` 162 163### windows 164 165#### 创建demo 166 167源码hello.cpp内容: 168 169```cpp 170#include <iostream> 171 172int main(int argc,const char **argv) 173{ 174 std::cout<< "hello world!" <<std::endl; 175 return 0; 176} 177``` 178 179源码同级目录下CMakeLists.txt内容: 180 181``` 182#cmake的版本 183CMAKE_MINIMUM_REQUIRED(VERSION 3.16) 184 185#工程名称 186PROJECT(HELLO) 187 188#生成可执行程序 189ADD_EXECUTABLE(Hello hello.cpp) 190``` 191 192#### 编译 193 194在windows下使用cmake进行编译,通过`-G`参数选择使用的生成器,这点和linux有区别。 195 196``` 197step1:在demo工程CMakeList.txt的同级目录创建build目录,然后再build目录下打开powerShell 198step2:传递cmake参数 199${OHOS NDK所在路径}\native\build-tools\cmake\bin\cmake.exe -G "Ninja" -DOHOS_STL=c++_shared -DOHOS_ARCH=armeabi-v7a -DOHOS_PLATFORM=OHOS -DCMAKE_TOOLCHAIN_FILE=D:\develop\OHOS-NDK\native\build\cmake\ohos.toolchain.cmake .. 200step3:cmake --build . 201``` 202 203执行成功后生成的产物中build.ninja文件是根据指定的ninja生成器生成的目标文件,Hello是生成的可执行程序。 204 205## OHOS平台相关参数说明 206 207CMake与OHOS NDK搭配使用自定义OHOS交叉工具链,涉及一些OHOS平台的工具链参数。一般在使用CMake编译时,常用OHOS_STL,OHOS_ARCH,OHOS_PLATFORM参数。 208 209| OHOS平台参数 | 说明 | 210| --- | ------ | 211| OHOS_AR | 指定构建过程中处理静态库的归档工具,默认设置为NDK中提供的归档工具llvm-ar | 212| OHOS_ARCH |设置目标ABI,默认arm64-v8a,可选armeabi-v7a,x86_64 | 213| OHOS_ARM_NEON | 指定ARM架构目标二进制文件生成指令集类型,默认 thumb| 214| OHOS_ASM_COMPILER_FLAGS | 设置ASM编译器flags | 215|OHOS_COMMON_LINKER_FLAGS |设置通用链接器flags | 216| OHOS_C_COMPILER_FLAGS| 设置C编译器flags | 217| OHOS_DEBUG_COMPILER_FLAGS | 编译器在debug模式的flags,默认启用-O0 -g -fno-limit-debug-info| 218| OHOS_EXE_LINKER_FLAGS | 设置传递给链接可执行文件的链接器的flags | 219| OHOS_LLVM | 指定OHOS平台使用的llvm版本,如arm-linux-ohos ,根据设置的OHOS_ARCH决定 | 220| OHOS_PIE | 指定是否在构建过程中启用PIE编译选项,默认设置为true,为应用程序启用PIE | 221| OHOS_PLATFORM | 指定构建时使用的平台,仅支持OHOS | 222| OHOS_PLATFORM_LEVEL | 指定目标OHOS平台的级别,默认为1 | 223|OHOS_RANLIB| 指定在交叉编译过程中用来生成静态库索引表的工具ranlib的路径 | 224| OHOS_RELEASE_COMPILER_FLAGS | 指定release构建模式下编译器的flags | 225| OHOS_SDK_NATIVE | 指定OHOS SDK中native所在的路径| 226| OHOS_SDK_NATIVE_PLATFORM | 指定ohos sdk中native平台,如ohos-1 | 227| OHOS_SDK_NATIVE_PLATFORM_LEVEL | 指定ohos sdk中native平台级别 | 228| OHOS_SDK_NATIVE_TOOLCHAIN_DEFINED | 定义ohos sdk中native下的交叉编译工具链 | 229| OHOS_STL | 指定构建时使用的STL类型,默认c++_shared,可选c++_static | 230| OHOS_TOOLCHAIN | 指定CMake构建中交叉编译工具链,默认clang | 231| OHOS_TOOLCHAIN_NAME | 指定交叉编译工具链名称,默认根据OHOS_ARCH决定 |