The NDK supports multiple C++ runtime libraries. This document provides information about these libraries, the tradeoffs involved, and how to use them.
In C++, it is not safe to define more than one copy of the same function or object in a single program. This is one aspect of the One Definition Rule present in the C++ standard.
When using a static runtime (and static libraries in general), it is easy to accidentally break this rule. For example, the following application breaks this rule:
# Application.mk APP_STL := c++_static
# Android.mk include $(CLEAR_VARS) LOCAL_MODULE := foo LOCAL_SRC_FILES := foo.cpp include $(BUILD_SHARED_LIBRARY) include $(CLEAR_VARS) LOCAL_MODULE := bar LOCAL_SRC_FILES := bar.cpp LOCAL_SHARED_LIBRARIES := foo include $(BUILD_SHARED_LIBRARY)
In this situation, the STL, including and global data and static constructors, will be present in both libraries. The runtime behavior of this application is undefined, and in practice crashes are very common. Other possible issues include:
- Memory allocated in one library, and freed in the other, causing memory leakage or heap corruption.
- Exceptions raised in
libfoo.sogoing uncaught in
libbar.so, causing your app to crash.
- Buffering of
std::coutnot working properly.
Beyond the behavioral issues involved, linking the static runtime into multiple libraries will duplicate the code in each shared library, increasing the size of your application.
In general, you can only use a static variant of the C++ runtime if you have one and only one shared library in your application.
However, if all of your application's native code is contained in a single shared library, we recommend using the static runtime. In this situation it is safe to do so and it will allow the linker to inline and prune as much unused code as possible, leading to the best optimized and smallest application possible.
If your app targets a version of Android earlier than Android 4.3 (Android API level 18), and you use the shared library variant of a given C++ runtime, you must load the shared library before any other library that depends on it.
Rather than managing this yourself, we recommend using ReLinker.
One STL Per App
Historically the NDK supported GNU libstdc++ and STLport in addition to libc++. If your application depends on prebuilt libaries that were built against an NDK different than the one used to build your application, you will need to ensure that it does so in a compatible manner.
An application should not use more than one C++ runtime. The various STLs are
not compatible with one another. As an example, the layout of
in libc++ is not the same as it is in gnustl. Code written against one STL will
not be able to use objects written against another. This is just one example;
the incompatibilities are numerous.
This rule extends beyond your code. All of your dependencies must use the same STL that you have selected. If you depend on a closed source third-party dependency that uses the STL and does not provide a library per STL, you do not have a choice in STL. You must use the same STL as your dependency.
It is possible that you will depend on two mutually incompatible libraries. In this situation the only solutions are to drop one of the dependencies or ask the maintainer to provide a library built against the other STL.
C++ Runtime Libraries
Table 1. NDK C++ Runtimes and Features.
|none||No headers, limited C++.|
libc++ is available as both a static and shared library.
Selecting a C++ Runtime
If you are using CMake, you can specify a runtime from Table 1 with the
ANDROID_STL variable in your module-level
build.gradle file. To learn more,
see Using CMake Variables.
If you are using ndk-build, you can specify a runtime from Table 1 with the
APP_STL variable in your Application.mk file. For example:
APP_STL := c++_shared
You may only select one runtime for your app, and can only do in Application.mk.
When using a Standalone Toolchain, the
toolchain will use the shared STL by default. To use the static variant, add
-static-libstdc++ to your linker flags.
C++ exceptions are supported by libc++, but they are disabled by default in ndk-build. This is because historically C++ exceptions were not available in the NDK. CMake and standalone toolchains have C++ exceptions enabled by default.
To enable exceptions across your whole application in ndk-build, add the following line to your Application.mk file:
APP_CPPFLAGS := -fexceptions
To enable exceptions for a single ndk-build module, add the following line to the given module in its Android.mk:
LOCAL_CPP_FEATURES := exceptions
Alternatively, you can use:
LOCAL_CPPFLAGS := -fexceptions
As with exceptions, RTTI is supported by libc++, but is disabled by default in ndk-build. CMake and standalone toolchains have RTTI enabled by default.
To enable RTTI across your whole application in ndk-build, add the following line to your Application.mk file:
APP_CPPFLAGS := -frtti
To enable RTTI for a single ndk-build module, add the following line to the given module in its Android.mk:
LOCAL_CPP_FEATURES := rtti
Alternatively, you can use:
LOCAL_CPPFLAGS := -frtti
LLVM's libc++ is the C++ standard library that has been used by the Android OS since Lollipop, and as of NDK r18 is the only STL available in the NDK.
The shared library for libc++ is
libc++_shared.so, and the static
libc++ is dual-licensed under both the University of Illinois "BSD-Like" license and the MIT license. For more information, see the license file.
The system runtime refers to
/system/lib/libstdc++.so. This library should not
be confused with GNU's libstdc++.
The system C++ runtime provides support for the basic C++ Runtime ABI.
Essentially, this library provides
delete. In contrast to the other
options available in the NDK, there is no support for exception handling or
There is no standard library support aside from the C++ wrappers for the C
library headers such as
<cstdio>. If you want an STL, you should use one of
the other options presented on this page.
There is also the option to have no STL. There are no linking or licensing requirements in that case.