• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Building an NDK Project with CMake
2
3
4In many complex application projects, C++ projects are compiled and built in command line mode through build systems such as CMake. The following describes how to switch an existing CMake project to the OpenHarmony toolchain so that CMake can be used to build the project.
5
6
7## Downloading the NDK
8
9You can download the NDK in either of the following modes:
10
111. (Recommended) Acquire source code from mirrors for an officially released version. For details, see [release notes](../../release-notes/OpenHarmony-v4.0-release.md).
122. Download the NDK from the SDK Manager in DevEco Studio.
13
14
15## Decompressing the NDK
16
17Place the downloaded NDK in a folder you prefer and decompress it. Below shows the directory structure after decompression.
18
19![en-us_image_0000001726080989](figures/en-us_image_0000001726080989.png)
20
21Configure the Linux environment as follows: (Skip them if the NDK is downloaded from DevEco Studio.)
22
231. Add the CMake tool that comes with the NDK to the environment variables.
24   ```
25   #Open the .bashrc file.
26   vim ~/.bashrc
27   #Append the custom CMake path to the file.
28   export PATH=~/ohos-sdk/ohos-sdk/linux/native/build-tools/cmake/bin:$PATH
29   #Run the source ~/.bashrc command to make the environment variables take effect.
30   source ~/.bashrc
31   ```
32
332. Check the default CMake path.
34   ```
35   #Run the which cmake command.
36   which cmake
37   #The result should be the same as the custom path previously appended to the .bashrc file.
38   ~/ohos-sdk/ohos-sdk/linux/native/build-tools/cmake/bin/cmake
39   ```
40
41
42## Using the NDK to Compile a Native Program
43
44You can use the NDK to quickly develop a native program, including native dynamic libraries, static libraries, and executable files. The following exemplifies how to use the NDK to compile an executable program and a dynamic library in a C/C++ demo project.
45
46
47### Demo Project
48
49The following is a CMake demo project. This project contains two directories. The **include** directory contains the header files of the library, and the **src** directory contains all source code. Specifically, the **src** directory contains two files: **sum.cpp** (algorithm file) and **main.cpp** (main entry file for invoking algorithms). The two files are compiled into an executable program and an algorithm dynamic library.
50
51**Demo Project Directory**
52
53```
54demo
55  ├── CMakeLists.txt
56  ├── include
57       └── sum.h
58  └── src
59       ├── CMakeLists.txt
60       ├── sum.cpp
61       └── main.cpp
62```
63
64**CMakeLists.txt in the demo Directory**
65
66```
67# Specify the minimum CMake version.
68CMAKE_MINIMUM_REQUIRED(VERSION 3.16)
69
70# Set the project name, which is HELLO in this example.
71PROJECT(HELLO)
72
73#Add a subdirectory and build the subdirectory.
74ADD_SUBDIRECTORY(src)
75```
76
77**CMakeLists.txt in the src Directory**
78
79```
80SET(LIBHELLO_SRC hello.cpp)
81
82# Set compilation flags.
83SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O0")
84
85# Set the link parameter. The value below is only for exemplary purposes.
86SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--emit-relocs --verbose")
87
88# Add a libsum dynamic library target. If the compilation is successful, a libsum.so file is generated.
89ADD_LIBRARY(sum SHARED sum.cpp)
90
91# Add the executable target called Hello. If the compilation is successful, a Hello executable is generated.
92ADD_EXECUTABLE(Hello ${LIBHELLO_SRC})
93
94# Specify the path to the include directory of the Hello target.
95TARGET_INCLUDE_DIRECTORIES(Hello PUBLIC ../include)
96
97# Specify the name of the library to be linked to the Hello target.
98TARGET_LINK_LIBRARIES(Hello PUBLIC sum)
99```
100
101**Source Code**
102
103**hello.cpp** source code:
104
105```
106#include <iostream>
107#include "sum.h"
108
109int main(int argc,const char **argv)
110{
111    std::cout<< "hello world!" <<std::endl;
112    int total = sum(1, 100);
113    std::cout<< "Sum 1 + 100=" << total << std::endl;
114    return 0;
115}
116```
117
118**sum.h** source code:
119
120```
121int sum(int a, int b);
122```
123
124**sum.cpp** source code:
125
126```
127#include <iostream>
128
129int sum(int a, int b)
130{
131    return a + b;
132}
133```
134
135
136### Compiling and Building the Demo Project
137
138In the project directory, create the **build** directory to store the intermediate files generated during CMake building.
139
140> **NOTE**
141>
142> In the following commands, **ohos-sdk** is the root directory of the downloaded SDK. Replace it with the actual directory.
143
1441. Use **OHOS_STL=c++_shared** to dynamically link the C++ library to build a project. If **OHOS_STL** is not specified, **c++_shared** is used by default.
145
146   ```
147    >mkdir build && cd build
148    >cmake -DOHOS_STL=c++_shared -DOHOS_ARCH=armeabi-v7a -DOHOS_PLATFORM=OHOS -DCMAKE_TOOLCHAIN_FILE={ohos-sdk}/linux/native/build/cmake/ohos.toolchain.cmake ..
149    >cmake --build .
150   ```
151
1522. Use **OHOS_STL=c++_static** to link a static C++ library to build the project.
153
154   ```
155    >mkdir build && cd build
156    >cmake -DOHOS_STL=c++_static -DOHOS_ARCH=armeabi-v7a -DOHOS_PLATFORM=OHOS -DCMAKE_TOOLCHAIN_FILE={ohos-sdk}/linux/native/build/cmake/ohos.toolchain.cmake ..
157    >cmake --build .
158   ```
159
160   In the command, the **OHOS_ARCH** and **OHOS_PLATFORM** variables generate the **--target** command parameters of Clang++. In this example, the two parameters are **--target=arm-linux-ohos** and **--march=armv7a**. **CMAKE_TOOLCHAIN_FILE** specifies the toolchain file. In this file, **--sysroot={ndk_sysroot directory}** is set for Clang++ by default, instructing the compiler to search for the root directory of system header files.
161