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.

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.

// blerp.h 
#include <stdint.h>
typedef struct {
    uint32_t *pixels;
    unsigned int w;
    unsigned int h;
} image_t; 

#define getByte(value, n) (value &gt;&gt; (n*8) &amp; 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

Comments