1e41f4b71Sopenharmony_ci# Building an NDK Project with CMake 2e41f4b71Sopenharmony_ci 3e41f4b71Sopenharmony_ci 4e41f4b71Sopenharmony_ciIn 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. 5e41f4b71Sopenharmony_ci 6e41f4b71Sopenharmony_ci 7e41f4b71Sopenharmony_ci## Downloading the NDK 8e41f4b71Sopenharmony_ci 9e41f4b71Sopenharmony_ci1. (Recommended) Acquire source code from mirrors for an officially released version. 10e41f4b71Sopenharmony_ci 11e41f4b71Sopenharmony_ci Specifically, access the release notes of the target version, locate the **Acquiring Source Code from Mirror** section, and download the source code based on your system type. 12e41f4b71Sopenharmony_ci 13e41f4b71Sopenharmony_ci 14e41f4b71Sopenharmony_ci2. Download the NDK from the SDK Manager in DevEco Studio. 15e41f4b71Sopenharmony_ci 16e41f4b71Sopenharmony_ci 17e41f4b71Sopenharmony_ci## Decompressing the NDK 18e41f4b71Sopenharmony_ci 19e41f4b71Sopenharmony_ciPlace the downloaded NDK in a folder you prefer and decompress it. 20e41f4b71Sopenharmony_ci 21e41f4b71Sopenharmony_ciBelow shows the directory structure after decompression on Windows or Linux. 22e41f4b71Sopenharmony_ci 23e41f4b71Sopenharmony_ci 24e41f4b71Sopenharmony_ci 25e41f4b71Sopenharmony_ciBelow shows the directory structure after decompression on macOS. 26e41f4b71Sopenharmony_ci 27e41f4b71Sopenharmony_ci 28e41f4b71Sopenharmony_ci 29e41f4b71Sopenharmony_ci### Configuring the Environment Variable 30e41f4b71Sopenharmony_ciSkip this step if the NDK is downloaded from DevEco Studio. 31e41f4b71Sopenharmony_ci1. Add the CMake tool that comes with the NDK to the environment variables. 32e41f4b71Sopenharmony_ci+ Configure the environment variables in Linux. 33e41f4b71Sopenharmony_ci 34e41f4b71Sopenharmony_ci 35e41f4b71Sopenharmony_ci #Open the .bashrc file. 36e41f4b71Sopenharmony_ci vim ~/.bashrc 37e41f4b71Sopenharmony_ci #Append the custom CMake path to the file. 38e41f4b71Sopenharmony_ci export PATH=~/ohos-sdk/ohos-sdk/linux/native/build-tools/cmake/bin:$PATH 39e41f4b71Sopenharmony_ci #Run the source ~/.bashrc command to make the environment variable take effect. 40e41f4b71Sopenharmony_ci source ~/.bashrc 41e41f4b71Sopenharmony_ci 42e41f4b71Sopenharmony_ci+ Configure the environment variables in macOS. 43e41f4b71Sopenharmony_ci 44e41f4b71Sopenharmony_ci 45e41f4b71Sopenharmony_ci # In the current user directory 46e41f4b71Sopenharmony_ci # Open the .bash_profile file. 47e41f4b71Sopenharmony_ci # If the file does not exist, create one. 48e41f4b71Sopenharmony_ci vim ~/.bash_profile 49e41f4b71Sopenharmony_ci # Append the custom CMake path to the file. Save the file and exit. 50e41f4b71Sopenharmony_ci export PATH=~/Ndk/mac-sdk-full/sdk/packages/ohos-sdk/darwin/native/build-tools/cmake/bin:$PATH 51e41f4b71Sopenharmony_ci # Run the source ~/.bash_profile command to make the environment variable take effect. 52e41f4b71Sopenharmony_ci source ~/.bash_profile 53e41f4b71Sopenharmony_ci 54e41f4b71Sopenharmony_ci+ Configure the environment variable in Windows. 55e41f4b71Sopenharmony_ci 56e41f4b71Sopenharmony_ci Right-click **This PC** and choose **Properties** from the shortcut menu. In the displayed dialog box, click the **Advanced System Settings** tab and then click **Environment Variables**. Under **System Variables** dialog box, select the **Path** environment variable and click **Edit**. Add the paths, save the settings, and exit. (If the next step cannot be performed, restart the computer.) 57e41f4b71Sopenharmony_ci 58e41f4b71Sopenharmony_ci  59e41f4b71Sopenharmony_ci 60e41f4b71Sopenharmony_ci Verify whether the environment variable is configured successfully. 61e41f4b71Sopenharmony_ci 62e41f4b71Sopenharmony_ci Open the CLI and run **F:\windows\native\build-tools\cmake\bin\cmake.exe -version**, replacing the path with the actual CMake path. 63e41f4b71Sopenharmony_ci 64e41f4b71Sopenharmony_ci  65e41f4b71Sopenharmony_ci 66e41f4b71Sopenharmony_ci If the information similar to that shown above is displayed, the environment variable is configured successfully. 67e41f4b71Sopenharmony_ci 68e41f4b71Sopenharmony_ci2. Check the default CMake path. 69e41f4b71Sopenharmony_ci + In Linux or macOS 70e41f4b71Sopenharmony_ci ``` 71e41f4b71Sopenharmony_ci #Run the which cmake command. 72e41f4b71Sopenharmony_ci which cmake 73e41f4b71Sopenharmony_ci #The result should be the same as the custom path previously appended to the .bashrc file. 74e41f4b71Sopenharmony_ci ~/ohos-sdk/ohos-sdk/linux/native/build-tools/cmake/bin/cmake 75e41f4b71Sopenharmony_ci ``` 76e41f4b71Sopenharmony_ci + In Windows 77e41f4b71Sopenharmony_ci 78e41f4b71Sopenharmony_ci Right-click **This PC** and choose **Properties** from the shortcut menu. In the displayed dialog box, click the **Advanced System Settings** tab and then click **Environment Variables**. Under **System Variables** dialog box, check the **Path** value. The displayed CMake path should be the one you have added. 79e41f4b71Sopenharmony_ci 80e41f4b71Sopenharmony_ci 81e41f4b71Sopenharmony_ci## Using the NDK to Compile a Native Program 82e41f4b71Sopenharmony_ci 83e41f4b71Sopenharmony_ciYou 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. 84e41f4b71Sopenharmony_ci 85e41f4b71Sopenharmony_ci 86e41f4b71Sopenharmony_ci### Demo Project 87e41f4b71Sopenharmony_ci 88e41f4b71Sopenharmony_ciThe 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. 89e41f4b71Sopenharmony_ci 90e41f4b71Sopenharmony_ci**Demo Project Directory** 91e41f4b71Sopenharmony_ci 92e41f4b71Sopenharmony_ci``` 93e41f4b71Sopenharmony_cidemo 94e41f4b71Sopenharmony_ci ├── CMakeLists.txt 95e41f4b71Sopenharmony_ci ├── include 96e41f4b71Sopenharmony_ci └── sum.h 97e41f4b71Sopenharmony_ci └── src 98e41f4b71Sopenharmony_ci ├── CMakeLists.txt 99e41f4b71Sopenharmony_ci ├── sum.cpp 100e41f4b71Sopenharmony_ci └── hello.cpp 101e41f4b71Sopenharmony_ci``` 102e41f4b71Sopenharmony_ci 103e41f4b71Sopenharmony_ci**CMakeLists.txt in the demo Directory** 104e41f4b71Sopenharmony_ci 105e41f4b71Sopenharmony_ci``` 106e41f4b71Sopenharmony_ci# Specify the minimum CMake version. 107e41f4b71Sopenharmony_ciCMAKE_MINIMUM_REQUIRED(VERSION 3.16) 108e41f4b71Sopenharmony_ci 109e41f4b71Sopenharmony_ci# Set the project name, which is HELLO in this example. 110e41f4b71Sopenharmony_ciPROJECT(HELLO) 111e41f4b71Sopenharmony_ci 112e41f4b71Sopenharmony_ci#Add a subdirectory and build the subdirectory. 113e41f4b71Sopenharmony_ciADD_SUBDIRECTORY(src) 114e41f4b71Sopenharmony_ci``` 115e41f4b71Sopenharmony_ci 116e41f4b71Sopenharmony_ci**CMakeLists.txt in the src Directory** 117e41f4b71Sopenharmony_ci 118e41f4b71Sopenharmony_ci``` 119e41f4b71Sopenharmony_ciSET(LIBHELLO_SRC hello.cpp) 120e41f4b71Sopenharmony_ci 121e41f4b71Sopenharmony_ci# Set compilation flags. 122e41f4b71Sopenharmony_ciSET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O0") 123e41f4b71Sopenharmony_ci 124e41f4b71Sopenharmony_ci# Set the link parameter. The value below is only for exemplary purposes. 125e41f4b71Sopenharmony_ciSET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--emit-relocs --verbose") 126e41f4b71Sopenharmony_ci 127e41f4b71Sopenharmony_ci# Add a libsum dynamic library target. If the compilation is successful, a libsum.so file is generated. 128e41f4b71Sopenharmony_ciADD_LIBRARY(sum SHARED sum.cpp) 129e41f4b71Sopenharmony_ci 130e41f4b71Sopenharmony_ci# Add the executable target called Hello. If the compilation is successful, a Hello executable is generated. 131e41f4b71Sopenharmony_ciADD_EXECUTABLE(Hello ${LIBHELLO_SRC}) 132e41f4b71Sopenharmony_ci 133e41f4b71Sopenharmony_ci# Specify the path to the include directory of the Hello target. 134e41f4b71Sopenharmony_ciTARGET_INCLUDE_DIRECTORIES(Hello PUBLIC ../include) 135e41f4b71Sopenharmony_ci 136e41f4b71Sopenharmony_ci# Specify the name of the library to be linked to the Hello target. 137e41f4b71Sopenharmony_ciTARGET_LINK_LIBRARIES(Hello PUBLIC sum) 138e41f4b71Sopenharmony_ci``` 139e41f4b71Sopenharmony_ci 140e41f4b71Sopenharmony_ci**Source Code** 141e41f4b71Sopenharmony_ci 142e41f4b71Sopenharmony_ci**hello.cpp** source code: 143e41f4b71Sopenharmony_ci 144e41f4b71Sopenharmony_ci``` 145e41f4b71Sopenharmony_ci#include <iostream> 146e41f4b71Sopenharmony_ci#include "sum.h" 147e41f4b71Sopenharmony_ci 148e41f4b71Sopenharmony_ciint main(int argc,const char **argv) 149e41f4b71Sopenharmony_ci{ 150e41f4b71Sopenharmony_ci std::cout<< "hello world!" <<std::endl; 151e41f4b71Sopenharmony_ci int total = sum(1, 100); 152e41f4b71Sopenharmony_ci std::cout<< "Sum 1 + 100=" << total << std::endl; 153e41f4b71Sopenharmony_ci return 0; 154e41f4b71Sopenharmony_ci} 155e41f4b71Sopenharmony_ci``` 156e41f4b71Sopenharmony_ci 157e41f4b71Sopenharmony_ci**sum.h** source code: 158e41f4b71Sopenharmony_ci 159e41f4b71Sopenharmony_ci``` 160e41f4b71Sopenharmony_ciint sum(int a, int b); 161e41f4b71Sopenharmony_ci``` 162e41f4b71Sopenharmony_ci 163e41f4b71Sopenharmony_ci**sum.cpp** source code: 164e41f4b71Sopenharmony_ci 165e41f4b71Sopenharmony_ci``` 166e41f4b71Sopenharmony_ci#include <iostream> 167e41f4b71Sopenharmony_ci 168e41f4b71Sopenharmony_ciint sum(int a, int b) 169e41f4b71Sopenharmony_ci{ 170e41f4b71Sopenharmony_ci return a + b; 171e41f4b71Sopenharmony_ci} 172e41f4b71Sopenharmony_ci``` 173e41f4b71Sopenharmony_ci 174e41f4b71Sopenharmony_ci 175e41f4b71Sopenharmony_ci### Compiling and Building the Demo Project 176e41f4b71Sopenharmony_ci 177e41f4b71Sopenharmony_ci#### In Linux or macOS 178e41f4b71Sopenharmony_ciIn the project directory, create the **build** directory to store the intermediate files generated during CMake building. **NOTE**<br>In the following commands, **ohos-sdk** is the root directory of the downloaded SDK. Replace it with the actual directory. 179e41f4b71Sopenharmony_ci 180e41f4b71Sopenharmony_ci1. 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. Set **DOHOS_ARCH** based on the system architecture. 181e41f4b71Sopenharmony_ci 182e41f4b71Sopenharmony_ci ``` 183e41f4b71Sopenharmony_ci >mkdir build && cd build 184e41f4b71Sopenharmony_ci >cmake -DOHOS_STL=c++_shared -DOHOS_ARCH=armeabi-v7a -DOHOS_PLATFORM=OHOS -DCMAKE_TOOLCHAIN_FILE={ohos-sdk}/linux/native/build/cmake/ohos.toolchain.cmake .. 185e41f4b71Sopenharmony_ci >cmake --build . 186e41f4b71Sopenharmony_ci ``` 187e41f4b71Sopenharmony_ci 188e41f4b71Sopenharmony_ci2. Use **OHOS_STL=c++_static** to link a static C++ library to build the project. 189e41f4b71Sopenharmony_ci 190e41f4b71Sopenharmony_ci ``` 191e41f4b71Sopenharmony_ci >mkdir build && cd build 192e41f4b71Sopenharmony_ci >cmake -DOHOS_STL=c++_static -DOHOS_ARCH=armeabi-v7a -DOHOS_PLATFORM=OHOS -DCMAKE_TOOLCHAIN_FILE={ohos-sdk}/linux/native/build/cmake/ohos.toolchain.cmake .. 193e41f4b71Sopenharmony_ci >cmake --build . 194e41f4b71Sopenharmony_ci ``` 195e41f4b71Sopenharmony_ci 196e41f4b71Sopenharmony_ci In the command, the **OHOS_ARCH** and **OHOS_PLATFORM** variables generate the **--target** options of Clang++. 197e41f4b71Sopenharmony_ci 198e41f4b71Sopenharmony_ci In this example, **--target=arm-linux-ohos** and **--march=armv7a** are generated. 199e41f4b71Sopenharmony_ci 200e41f4b71Sopenharmony_ci **CMAKE_TOOLCHAIN_FILE** specifies the toolchain file. 201e41f4b71Sopenharmony_ci 202e41f4b71Sopenharmony_ci 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. 203e41f4b71Sopenharmony_ci#### In Windows 204e41f4b71Sopenharmony_ci 205e41f4b71Sopenharmony_ciUsing CMake in Windows, unlike that in Linux, requires you to use the **-G** option to specify the generator. 206e41f4b71Sopenharmony_ci 207e41f4b71Sopenharmony_ci 208e41f4b71Sopenharmony_ci 209e41f4b71Sopenharmony_ciIn this example, the Ninja generator, which comes with the NDK, is used, as indicated by **-G "Ninja"**. 210e41f4b71Sopenharmony_ci 211e41f4b71Sopenharmony_ci 212e41f4b71Sopenharmony_ci 213e41f4b71Sopenharmony_ciStep 1. Create the **build** folder in the project directory and run the following command: 214e41f4b71Sopenharmony_ci``` 215e41f4b71Sopenharmony_ci F:\windows\native\build-tools\cmake\bin\cmake.exe -G "Ninja" -D OHOS_STL=c++_shared -D OHOS_ARCH=armeabi-v7a -D OHOS_PLATFORM=OHOS -D CMAKE_TOOLCHAIN_FILE=F:\windows\native\build\cmake\ohos.toolchain.cmake .. 216e41f4b71Sopenharmony_ci``` 217e41f4b71Sopenharmony_ciNote: If debugging is required, add the **-D CMAKE_BUILD_TYPE=normal** option. 218e41f4b71Sopenharmony_ciThe CMake path and the ohos.toolchain.cmake path are where the NDK is downloaded. 219e41f4b71Sopenharmony_ciThe following figure shows the command output. 220e41f4b71Sopenharmony_ci 221e41f4b71Sopenharmony_ci 222e41f4b71Sopenharmony_ci 223e41f4b71Sopenharmony_ciThe **build.ninja** file generated here is what we need. 224e41f4b71Sopenharmony_ci 225e41f4b71Sopenharmony_ciStep 2. Use the ninja command to compile and generate the target file. The following figure shows the location of the target file. 226e41f4b71Sopenharmony_ci 227e41f4b71Sopenharmony_ci 228e41f4b71Sopenharmony_ci 229e41f4b71Sopenharmony_ciUse **ninja -f build.ninja** or **cmake --build**. The following figure shows the command output. 230e41f4b71Sopenharmony_ci 231e41f4b71Sopenharmony_ci 232