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 >> (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
# 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 #includetypedef 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
Post a Comment