Skip to main content

Android Native C++ Compilation

# Set Toolchain Table 1. APP_ABI Settings for Different Command Sets | Architecture | Toolchain Name | | ---------- | ------------------------------------ | | ARM | arm-linux-androideabi-**{gcc-version}** | | x86 | x86-**{gcc-version}** | | MIPS | mipsel-linux-android-**{gcc-version}** | | ARM64 | aarch64-linux-android-**{gcc-version}** | | X86-64 | x86\_64-**{gcc-version}** | | MIPS64 | mips64el-linux-android-**{gcc-version}** | # Set Sysroot ``` SYSROOT=$NDK/platforms/android-21/arch-arm ``` # Call Compiler ## Simple call The following is a build method using the `arm-linux-androideabi-4.8` toolchain, which is pre-built within NDK. ``` export CC="$NDK/toolchains/arm-linux-androideabi-4.8/prebuilt/ \ linux-x86/bin/arm-linux-androideabi-gcc-4.8 --sysroot=$SYSROOT" $CC -o foo.o -c foo.c ``` C++ STL (STLport, libc++, or GNU libstdc++) is not available in this method. No exceptions or RTTI are supported. ## Advanced call NDK provides a 'make-standalo

Android Native C++ Compilation



# Set Toolchain

Table 1. APP_ABI Settings for Different Command Sets

| Architecture | Toolchain Name |
| ---------- | ------------------------------------ |
| ARM | arm-linux-androideabi-**{gcc-version}** |
| x86 | x86-**{gcc-version}** |
| MIPS | mipsel-linux-android-**{gcc-version}** |
| ARM64 | aarch64-linux-android-**{gcc-version}** |
| X86-64 | x86\_64-**{gcc-version}** |
| MIPS64 | mips64el-linux-android-**{gcc-version}** |

# Set Sysroot 

```
SYSROOT=$NDK/platforms/android-21/arch-arm 
```

# Call Compiler

## Simple call


The following is a build method using the `arm-linux-androideabi-4.8` toolchain, which is pre-built within NDK.

```
export CC="$NDK/toolchains/arm-linux-androideabi-4.8/prebuilt/ \
  linux-x86/bin/arm-linux-androideabi-gcc-4.8 --sysroot=$SYSROOT" $CC -o foo.o -c foo.c 
```

C++ STL (STLport, libc++, or GNU libstdc++) is not available in this method. No exceptions or RTTI are supported.

## Advanced call

NDK provides a 'make-standalone-toolchain.sh' shell script that allows you to perform custom toolchain installations from the command line.

It is located in `$NDK/build/tools/` directory, where $NDK is the installation root directory of NDK.


```
$NDK/build/tools/make-standalone-toolchain.sh \
  --arch=arm --platform=android-21 --install-dir=/tmp/my-android-toolchain 
```

This command creates a directory named `/tmp/my-android-toolchain/`, which contains a copy of 'android-21/arch-arm' sysroot and a copy of the toolchain binary for 32-bit ARM architecture.


Table 3. Toolchain using `--arch` and its value.

| Toolchain | Value |
| ----------------- | ----------------- |
| mips64 compiler | \--arch=mips64 |
| mips GCC 4.8 compiler | \--arch=mips |
| x86 GCC 4.8 compiler | \--arch=x86 |
| x86\_64 GCC 4.8 compiler | \--arch=x86\_64 |
| mips GCC 4.8 compiler | \--arch=mips |

Table 4. Toolchain using `--toolchain` and its value.`

| Toolchain | Value |
|:-------------:|:-------------------------------------------------------------------------:|
| arm | --toolchain=arm-linux-androideabi-4.8 
--toolchain=arm-linux-androideabi-4.9
--toolchain=arm-linux-android-clang3.5
--toolchain=arm-linux-android-clang3.6| | x86 | \--toolchain=x86-linux-android-4.8
\--toolchain=x86-linux-android-4.9
\--toolchain=x86-linux-android-clang3.5
\--toolchain=x86-linux-android-clang3.6 | | mips | \--toolchain=mips-linux-android-4.8
\--toolchain=mips-linux-android-4.9
\--toolchain=mips-linux-android-clang3.5
\--toolchain=mips-linux-android-clang3.6 | | arm64 | \--toolchain=aarch64-linux-android-4.9
\--toolchain=aarch64-linux-android-clang3.5
\--toolchain=aarch64-linux-android-clang3.6 | | x86\_64 | \--toolchain=x86\_64-linux-android-4.9
\--toolchain=x86\_64-linux-android-clang3.5
\--toolchain=x86\_64-linux-android-clang3.6 | | mips64 | \--toolchain=mips64el-linux-android-4.9
\--toolchain=mips64el-linux-android-clang3.5
\--toolchain=mips64el-linux-android-clang3.6 | # CMakeList.txt ``` # For more information about using CMake with Android Studio, read the # documentation: https://d.android.com/studio/projects/add-native-code.html # Sets the minimum version of CMake required to build the native library. cmake_minimum_required(VERSION 3.4.1) # Creates and names a library, sets it as either STATIC # or SHARED, and provides the relative paths to its source code. # You can define multiple libraries, and CMake builds them for you. # Gradle automatically packages shared libraries with your APK. ``` Here's how to add a `.cpp` library. ``` add_library( # Sets the name of the library. native-lib # Sets the library as a shared library. SHARED # Provides a relative path to your source file(s). src/main/cpp/native-lib.cpp ) ``` ``` add_library( # Sets the name of the library. blerp # Sets the library as a shared library. SHARED # Provides a relative path to your source file(s). src/main/cpp/detection/blerp.cpp ) add_library( # Sets the name of the library. util # Sets the library as a shared library. SHARED # Provides a relative path to your source file(s). src/main/cpp/detection/util.cpp ) add_library( # Sets the name of the library. input-processing # Sets the library as a shared library. SHARED # Provides a relative path to your source file(s). src/main/cpp/detection/input_processing.cpp ) ``` Multiple cpp files can be grouped into the third parameter of add_library and registered as one library. (Thanks to `코드몬`) ``` add_library( # Sets the name of the library. native-lib2 # Sets the library as a shared library. SHARED # Provides a relative path to your source file(s). native-lib.cpp common/hmac.cpp common/sha1.cpp common/sha256.cpp ) ``` The following code is used to declare a directory containing the header file. ``` # Specifies a path to native header files. include_directories( src/main/cpp/include ) ``` The following is the code that finds the library and allocates its name to it. ``` # Searches for a specified prebuilt library and stores the path as a # variable. Because CMake includes system libraries in the search path by # default, you only need to specify the name of the public NDK library # you want to add. CMake verifies that the library exists before # completing its build. find_library( # Sets the name of the path variable. log-lib # Specifies the name of the NDK library that # you want CMake to locate. log ) ``` The following code defines the target of the library. ``` # Specifies libraries CMake should link to your target library. You # can link multiple libraries, such as libraries you define in this # build script, prebuilt third-party libraries, or system libraries. target_link_libraries( # Specifies the target library. native-lib # Links the target library to the log library # included in the NDK. ${log-lib} ) ``` `input-processing` is dependent on the `util`, and `util` is dependent on the `blerp`. ``` target_link_libraries( input-processing util ) target_link_libraries( util blerp ) ``` # Note When using a mix code of C and C++, the name of the function created in C and the name of the function declared in C++ are made similar so that the function compiled in C++ can also be used in C. - [About "name mangling" on C++](https://spikez.tistory.com/19) By explicitly declaring `extern "C"`, the function declared in this part has a function execution name in the form of C, which can also be used in C. In this case, the declaration form of the function must follow the criterion of C, and a function that follows the criterion of C++ (such as specifying a class or using a template) will fail. - [What is the effect of extern “C” in C++?](https://stackoverflow.com/questions/1041866/what-is-the-effect-of-extern-c-in-c) ``` // blerp.h #include typedef struct { uint32_t *pixels; unsigned int w; unsigned int h; } image_t; #define getByte(value, n) (value >> (n*8) & 0xFF) #ifdef __cplusplus extern "C" { #endif void copy_element(image_t *image, unsigned int x, unsigned int y, uint32_t color); #ifdef __cplusplus } #endif ``` # References - [Add C and C++ codes to the project](https://developer.android.com/studio/projects/add-native-code?hl=ko) - [Standalond Toolchain](https://developer.android.com/ndk/guides/standalone_toolchain?hl=ko) - [CMake: target\_link\_libraries](https://cmake.org/cmake/help/v3.12/command/target_link_libraries.html)

Comments