Using Android Studio 2.2 and higher, you can use the NDK and CMake to compile C and C++ code into a native library. Android Studio then packages your library into your APK using Gradle, the IDE's integrated build system.
If you are new to using CMake with Android Studio, go to Add C and C++ Code to Your Project to learn the basics of adding native sources to your project, creating a CMake build script, and adding your CMake project as a Gradle dependency. This page provides some additional information you can use to customize your CMake build.
Understanding the CMake build command
When debugging CMake build issues, it's helpful to know the specific build arguments that Android Studio uses when cross-compiling for Android.
Android Studio saves the build arguments it uses for executing a CMake build, in
a cmake_build_command.txt file. For each
Application Binary Interface (ABI) that your app targets, and each build
type for those ABIs (namely, release or debug), Android
Studio generates a copy of the cmake_build_command.txt
file for that specific configuration. Android Studio then places the files it generates in the
following directories:
<project-root>/<module-root>/.externalNativeBuild/cmake/<build-type>/<ABI>/
Tip: In Android Studio, you can quickly view these files by using the search
keyboard shortcut (shift+shift) and entering
cmake_build_command.txt in the input field.
The following snippet shows an example of the CMake arguments to build
a debuggable release of the hello-jni
sample targeting the armeabi-v7a architecture.
Executable : /usr/local/google/home/{$USER}/Android/Sdk/cmake/3.6.3155560/bin/cmake
arguments :
-H/usr/local/google/home/{$USER}/Dev/github-projects/googlesamples/android-ndk/hello-jni/app/src/main/cpp
-B/usr/local/google/home/{$USER}/Dev/github-projects/googlesamples/android-ndk/hello-jni/app/.externalNativeBuild/cmake/arm7Debug/armeabi-v7a
-GAndroid Gradle - Ninja
-DANDROID_ABI=armeabi-v7a
-DANDROID_NDK=/usr/local/google/home/{$USER}/Android/Sdk/ndk-bundle
-DCMAKE_LIBRARY_OUTPUT_DIRECTORY=/usr/local/google/home/{$USER}/Dev/github-projects/googlesamples/android-ndk/hello-jni/app/build/intermediates/cmake/arm7/debug/obj/armeabi-v7a
-DCMAKE_BUILD_TYPE=Debug
-DCMAKE_MAKE_PROGRAM=/usr/local/google/home/{$USER}/Android/Sdk/cmake/3.6.3155560/bin/ninja
-DCMAKE_TOOLCHAIN_FILE=/usr/local/google/home/{$USER}/Android/Sdk/ndk-bundle/build/cmake/android.toolchain.cmake
-DANDROID_NATIVE_API_LEVEL=23
-DANDROID_TOOLCHAIN=clang
jvmArgs :
Build arguments
The following table highlights the key CMake build arguments for Android. For a list
of the standard build arguments you can set for the cmake command-line executable,
see the CMake
manual.
| Build Arguments | Description |
-G <build-system>
|
Type of build files that CMake generates.
For projects in Android Studio with native code, the
If |
-DANDROID_ABI <abi>
|
The target ABI. The NDK supports a set of ABIs, as described in ABI Management. This option is similar to theAPP_ABI variable that the ndk-build tool uses.
By default, Gradle builds your native library into separate
If the target ABI is not specified, CMake defaults to using
Valid target names are:
|
-DANDROID_NDK <path>
|
Absolute path to the root directory of the NDK installation on your host. |
-DCMAKE_LIBRARY_OUTPUT_DIRECTORY <path>
|
Location on your host where CMake puts the LIBRARY target
files when built.
|
-DCMAKE_BUILD_TYPE <type>
|
Similar to the build types for the ndk-build
tool. The valid values are Release and Debug. To
simplify debugging, CMake does not strip the release or debug version as part of
the build. However, Gradle strips binaries when it packages them in the APK.
|
-DCMAKE_MAKE_PROGRAM <program-name>
|
Tool to launch the native build system. You can set the value to be the full path to
an executable or the tool name if it's in the PATH. For
cross-compilation with Android Studio, this value is set to the CMake
ninja generator bundled with the Android SDK.
|
-DCMAKE_TOOLCHAIN_FILE <path>
|
Path to the android.toolchain.cmake file that CMake uses for
cross-compiling for Android. Typically, this file is located in the
$NDK/build/cmake/ directory, where $NDK is the NDK
installation directory on your host. For more information about the toolchain
file, see Cross Compiling for Android.
|
-DANDROID_NATIVE_API_LEVEL <level>
|
Android API level that CMake compiles for. |
-DANDROID_TOOLCHAIN <type>
|
The compiler toolchain that CMake uses. Valid values are
clang (default) and gcc (deprecated) .
|
Using CMake variables in Gradle
Once you link
Gradle to your CMake project, you can configure certain NDK-specific
variables that change the way CMake builds your native libraries. To pass an
argument to CMake from your module-level build.gradle file, use
the following DSL:
android {
...
defaultConfig {
...
// This block is different from the one you use to link Gradle
// to your CMake build script.
externalNativeBuild {
cmake {
...
// Use the following syntax when passing arguments to variables:
// arguments "-DVAR_NAME=VALUE"
arguments "-DANDROID_ARM_NEON=TRUE"
}
}
}
buildTypes {...}
// Use this block to link Gradle to your CMake build script.
externalNativeBuild {
cmake {...}
}
}
The following table describes some of the variables you can configure when using CMake with the NDK.
| Variable name | Arguments | Description |
|---|---|---|
ANDROID_TOOLCHAIN
|
|
Specifies the compiler toolchain CMake should use. |
ANDROID_PLATFORM
|
For a complete list of platform names and corresponding Android system images, see Android NDK Native APIs. |
Specifies the name of the target Android platform. For example,
|
ANDROID_STL
|
For a complete list of options, see Helper Runtimes
By default, CMake uses |
Specifies the STL CMake should use. |
ANDROID_PIE
|
|
Specifies whether to use position-independent executables (PIE). Android's dynamic linker supports PIE on Android 4.1 (API level 16) and higher. |
ANDROID_CPP_FEATURES
|
This variable is empty by default. However, the following are a few examples of arguments you can pass:
|
Specifies certain C++ features CMake needs to use when compiling your native library, such as RTTI (RunTime Type Information) and C++ exceptions. |
ANDROID_ALLOW_UNDEFINED_SYMBOLS
|
|
Specifies whether to throw an undefined symbol error if CMake
encounters an undefined reference while building your native library.
To disable these types of errors, set this variable to
|
ANDROID_ARM_MODE
|
|
Specifies whether to generate ARM target binaries in |
ANDROID_ARM_NEON
|
|
Specifies whether CMake should build your native library with NEON support. |
ANDROID_DISABLE_NO_EXECUTE
|
|
Specifies whether to enable NX
bit, or No eXecute, security feature. To disable this feature, pass
|
ANDROID_DISABLE_RELRO
|
|
Specifies whether to enable read-only relocations. |
ANDROID_DISABLE_FORMAT_STRING_CHECKS
|
|
Specifies whether to compile your source code with format string
protection. When enabled, the compiler throws an error if a
non-constant format string is used in a |
Reporting problems
If you run into any issues that aren't due to the open source version of CMake,
report them via the android-ndk/ndk
issue tracker on GitHub.

