cmake-with-ndk.md 5.8 KB
Newer Older
1
# 如何在CMake工程中使用OpenHarmony SDK的Native API(NDK)
2

Z
zengyawen 已提交
3
## 什么是Native API
4

Z
zengyawen 已提交
5
请参看[Native API](../reference/native-api-intro.md)
6

Z
zengyawen 已提交
7
## 如何下载Native API开发包(NDK)
8

H
hhj 已提交
9
1. 推荐使用OpenHarmony正式发布的SDK包 ,下载链接可以从OpenHarmony正式发布版本的[release-notes](../../release-notes/OpenHarmony-v3.2-release.md)中获取,点击release notes中【从站点镜像获取】章节下载。
10

H
hhj 已提交
11
2. IDE OpenHarmony SDK Manager中下载。
12

H
hhj 已提交
13
3. 从每日构建中下载,下载地址 http://ci.openharmony.cn/workbench/cicd/dailybuild/dailylist ,形态组件选择ohos-sdk。
14

Z
zengyawen 已提交
15 16 17
![](figures/ci_download.png)

## 解压Native API开发包
18

H
hhj 已提交
19
下载完成之后,将压缩包放入创建好的文件夹下解压,解压完成效果如下图所示:
Z
zengyawen 已提交
20
![](figures/sdk-structure.png)
21 22 23

配置Linux下的环境,如果只是在IDE中使用,跳过下面几步:

H
hhj 已提交
24
将NDK自带的CMake编译工具添加到环境变量中。
25 26 27 28

```
    #打开.bashrc文件
    vim ~/.bashrc
H
hhj 已提交
29
    #在文件最后添加CMake路径,具体路径用实际放置SDK路径代替
30 31 32 33 34
    export PATH=~/ohos-sdk/ohos-sdk/linux/native/build-tools/cmake/bin:$PATH
    #在命令行执行source ~/.bashrc使环境变量生效
    source ~/.bashrc
```

H
hhj 已提交
35
查看CMake默认路径。
36 37

```
H
hhj 已提交
38
    #在命令行输入which命令查询当前CMake所在路径
39
    which cmake
H
hhj 已提交
40
    #结果路径与.bashrc中设置一致
41 42 43
    ~/ohos-sdk/ohos-sdk/linux/native/build-tools/cmake/bin/cmake
```

Z
zengyawen 已提交
44
## 如何使用Native API开发包编译一个native程序
45

H
hhj 已提交
46
应用开发者可以通过Native API开发包快速的开发出native动态库,静态库与可执行文件,ArkUI应用程序框架可以通过NAPI框架调用到native的动态库中。开发包提供CMake作为官方的编译构建工具。下面通过编写一个C/C++ demo工程来演示如何使用Native API开发包来编译C/C++动态库。
47

Z
zengyawen 已提交
48 49 50 51
### NDK中的文件夹简介

#### build目录中工具链文件ohos.toolchain.cmake

H
hhj 已提交
52
CMake编译时需要读取该文件中的默认值,比如编译器架构、C++库链接方式等,这个需要在编译时通过CMAKE_TOOLCHAIN_FILE指出该文件的路径,便于CMake在编译时定位到该文件。在编译的时候需要为CMake指定参数来控制编译目标的属性,具体要指定的参数在下面的[命令行构建](#命令行构建)会具体介绍。
53

Z
zengyawen 已提交
54
#### build-tools文件夹放的是NDK提供的编译工具
55 56

```
H
hhj 已提交
57
    #键入下一行命令查看CMake的版本
58 59 60 61 62 63 64
    cmake -version
    #结果
    cmake version 3.16.5

    CMake suite maintained and supported by Kitware (kitware.com/cmake).
```

Z
zengyawen 已提交
65 66 67 68 69 70 71 72 73
#### llvm文件夹放的是NDK提供的编译器

![](figures/images.png)

### NDK使用的简单demo

#### demo目录图

```
74 75 76 77 78 79 80 81
    demo
      ├── CMakeLists.txt
      ├── include
           └── sum.h
      └── src
           ├── CMakeLists.txt
           ├── sum.cpp
           └── hello.cpp
Z
zengyawen 已提交
82 83 84
```

#### CMakeLists.txt内容
85 86

```
H
hhj 已提交
87
    # 指定CMake的最小版本
88 89 90 91 92 93 94 95 96
    CMAKE_MINIMUM_REQUIRED(VERSION 3.16)

    # 工程名称,这里我们就叫HELLO
    PROJECT(HELLO)

    #添加一个子目录并构建该子目录。
    ADD_SUBDIRECTORY(src bin)
```

Z
zengyawen 已提交
97 98
#### 内部CMakeLists.txt内容

99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120
```
    SET(LIBHELLO_SRC hello.cpp)

    # 设置编译参数
    SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O0")   
 
    # 设置链接参数,具体参数可以忽略,纯粹为了举例
    SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--emit-relocs --verbose")    

    # 添加一个libsum动态库目标,编译成功会生成一个libsum.so
    ADD_LIBRARY(sum SHARED sum.cpp)

    # 生成可执行程序,添加一个Hello的可执行程序目标,编译成功会生成一个Hello可执行程序
    ADD_EXECUTABLE(Hello ${LIBHELLO_SRC})

    # 指定Hello目标include目录路径
    TARGET_INCLUDE_DIRECTORIES(Hello PUBLIC ../include)

    # 指定Hello目标需要链接的库名字
    TARGET_LINK_LIBRARIES(Hello PUBLIC sum)
```

H
hhj 已提交
121
详细CMake手册参考 https://cmake.org/cmake/help/v3.16/guide/tutorial/ 。
122

Z
zengyawen 已提交
123 124
#### 源码内容

125
hello.cpp 源码
Z
zengyawen 已提交
126

127 128 129 130 131 132 133 134 135 136 137 138
```
    #include <iostream>
    #include "sum.h"

    int main(int argc,const char **argv)
    {
        std::cout<< "hello world!" <<std::endl;
        int total = sum(1, 100);
        std::cout<< "Sum 1 + 100=" << total << std::endl;
        return 0;
    }
```
Z
zengyawen 已提交
139

140
sum.h源码
Z
zengyawen 已提交
141

142 143 144 145
```
    int sum(int a, int b);

```
Z
zengyawen 已提交
146

147
sum.cpp源码
Z
zengyawen 已提交
148

149 150 151 152 153 154 155 156 157
```
    #include <iostream>
    
    int sum(int a, int b)
    {
        return a + b;
    }
```

Z
zengyawen 已提交
158
### ohos.toolchain.cmake中关键变量
159 160 161 162 163

| 参数   | 类型 |备注|
|--------|------|------|
|OHOS_STL|c++_shared/c++_static|默认是c++_shared,用来控制是动态链接libc++_shared.so还是静态链接libc++_static.a,对于同一个应用中的全部native库需要采用同一种链接方式,这个是由c++运行时中一些全局状态导致的|
|OHOS_ARCH|armeabi-v7a/arm64-v8a/x86_64|设置native需要支持的ABI,当前支持三种ABI|
164
|OHOS_PLATFORM|OHOS|平台选择,当前只支持OpenHarmony平台|
165 166
|CMAKE_TOOLCHAIN_FILE|工具链文件|就是ohos.toolchain.cmake文件,里面根据上面参数指定了对应平台的交叉编译参数|

Z
zengyawen 已提交
167 168
### 命令行构建

H
hhj 已提交
169
在工程目录下,创建build目录,用来放置CMake构建时产生的中间文件。注意: ohos-sdk是下载下来的SDK的根目录,开发者需要自行替换成实际的下载目录。
Z
zengyawen 已提交
170

H
hhj 已提交
171
1. 采用OHOS_STL=c++_shared动态编译。
Z
zengyawen 已提交
172 173

   ```
174 175 176
    >mkdir build && cd build
    >cmake -DOHOS_STL=c++_shared -DOHOS_ARCH=armeabi-v7a -DOHOS_PLATFORM=OHOS -DCMAKE_TOOLCHAIN_FILE={ohos-sdk}/linux/native/build/cmake/ohos.toolchain.cmake ..
    >cmake --build .
Z
zengyawen 已提交
177
   ```
178

H
hhj 已提交
179
2. 采用OHOS_STL=c++_static静态编译。
Z
zengyawen 已提交
180 181

   ```
182 183 184
    >mkdir build && cd build
    >cmake -DOHOS_STL=c++_static -DOHOS_ARCH=armeabi-v7a -DOHOS_PLATFORM=OHOS -DCMAKE_TOOLCHAIN_FILE={ohos-sdk}/linux/native/build/cmake/ohos.toolchain.cmake ..
    >cmake --build .
Z
zengyawen 已提交
185
   ```