| C++ support with the Android NDK |
| ================================ |
| |
| |
| The Android platform provides a very minimal C++ runtime support library |
| (/system/lib/libstdc++) and corresponding headers for it in the NDK. |
| |
| By default, this 'system' runtime does *not* provide the following: |
| |
| - Standard C++ Library support (except a few trivial headers). |
| - C++ exceptions support |
| - RTTI support |
| |
| However, the NDK provides various "helper C++ runtimes" which can provide them, |
| or a subset of these features. |
| |
| To select the runtime you want to use, define APP_STL inside your |
| Application.mk to one of the following values: |
| |
| system -> Use the default minimal system C++ runtime library. |
| gabi++_static -> Use the GAbi++ runtime as a static library. |
| gabi++_shared -> Use the GAbi++ runtime as a shared library. |
| stlport_static -> Use the STLport runtime as a static library. |
| stlport_shared -> Use the STLport runtime as a shared library. |
| gnustl_static -> Use the GNU STL as a static library. |
| gnustl_shared -> Use the GNU STL as a shared library. |
| c++_static -> Use the LLVM libc++ as a static library. |
| c++_shared -> Use the LLVM libc++ as a shared library. |
| |
| The 'system' runtime is the default if there is no APP_STL definition in |
| your Application.mk. As an example, to use the static GNU STL, add a line like: |
| |
| APP_STL := gnustl_static |
| |
| To your Application.mk. You can only select a single C++ runtime that all |
| your code will depend on. It is not possible to mix shared libraries compiled |
| against different C++ runtimes. |
| |
| IMPORTANT: Defining APP_STL in Android.mk has no effect! |
| |
| If you are not using the NDK build system, you can still use on of |
| STLport, libc++ or GNU STL via "make-standalone-toolchain.sh --stl=". |
| see docs/STANDALONE-TOOLCHAIN.html for more details. |
| |
| The capabilities of the various runtimes vary. See this table: |
| |
| C++ C++ Standard |
| Exceptions RTTI Library |
| |
| system no no no |
| gabi++ yes yes no |
| stlport yes yes yes |
| gnustl yes yes yes |
| libc++ yes yes yes |
| |
| # |
| |
| - - - - |
| I. Runtimes overview: |
| --------------------- |
| |
| ### I.1. System runtime: |
| |
| The system runtime only provides a very small number of C++ standard headers. |
| |
| This corresponds to the actual C++ runtime provided by the Android platform. |
| If you use it, your C++ binaries will automatically be linked against the |
| system libstdc++. |
| |
| The only headers provided here are the following: |
| |
| cassert cctype cerrno cfloat climits cmath csetjmp csignal cstddef |
| cstdint cstdio cstdlib cstring ctime cwchar new stl_pair.h typeinfo |
| utility |
| |
| Anything else is _not_ supported, including std::string or std::vector. |
| |
| |
| ### I.2. GAbi++ runtime: |
| |
| This is a new minimalistic runtime that provides the same headers than |
| the system one, with the addition of RTTI (RunTime Type Information) and |
| exception handling support. |
| |
| If you insist on using it, read the "RTTI Support" and |
| "Static runtime considerations" sections below. |
| |
| |
| ### I.3. STLport runtime: |
| |
| This is a port of STLport (http://www.stlport.org) that can be used on |
| Android. It will provide you with a complete set of C++ standard library |
| headers, with RTTI and exception handling support. |
| |
| That's because the library embeds its own copy of GAbi++. |
| |
| Available as both both static and shared libraries. To use it, use either |
| one of these two lines in your Application.mk: |
| |
| APP_STL := stlport_shared |
| APP_STL := stlport_static |
| |
| Note that 'stlport_shared' is preferred, for reasons explained in |
| "Static runtime considerations". The shared library file is named |
| libstlport_shared.so instead of "libstdc++.so" as on other platforms. |
| |
| |
| ### I.4. GNU STL runtime: |
| |
| This is the GNU Standard C++ Library (a.k.a. libstdc++-v3), providing the |
| more features. Note that the shared library file is named "libgnustl_shared.so". |
| |
| |
| ### I.5. libC++ runtime: |
| |
| This is a port of LLVM libc++: http://libcxx.llvm.org/. Note that the shared library |
| file is named "libc++_shared.so". |
| |
| |
| Please read the "C++ Exceptions support", "RTTI Support" and |
| "Static runtime considerations" sections below. |
| |
| |
| - - - - |
| II. Important Considerations: |
| ----------------------------- |
| |
| ### II.1. C++ Exceptions support: |
| |
| The NDK toolchain supports C++ exceptions, since NDK r5, however all C++ |
| sources are compiled with -fno-exceptions support by default, for |
| compatibility reasons with previous releases. |
| |
| To enable it, use the new LOCAL_CPP_FEATURES variable in your Android.mk, |
| as in: |
| |
| LOCAL_CPP_FEATURES += exceptions |
| |
| See docs/ANDROID-MK.html for more details about this variable. |
| |
| Another way to do the same is to define it in your LOCAL_CPPFLAGS definition |
| (but using LOCAL_CPP_FEATURES is preferred), as in: |
| |
| LOCAL_CPPFLAGS += -fexceptions |
| |
| More simply, add a single line to your Application.mk, the setting will |
| automatically apply to all your project's NDK modules: |
| |
| APP_CPPFLAGS += -fexceptions |
| |
| IMPORTANT: You *will* have to select a C++ runtime that supports |
| exceptions to be able to link / run your code. |
| |
| |
| ### II.2. RTTI support: |
| |
| Similarly, the NDK toolchain supports C++ RTTI (RunTime Type Information) |
| since NDK r5, but all C++ sources are built with -fno-rtti by default for |
| compatibility reasons. To enable it, add the following to your module |
| declarations: |
| |
| LOCAL_CPP_FEATURES += rtti |
| |
| This will be equivalent to: |
| |
| LOCAL_CPPFLAGS += -frtti |
| |
| Or more simply to your Application.mk: |
| |
| APP_CPPFLAGS += -frtti |
| |
| |
| ### II.3. Static runtimes: |
| |
| Please keep in mind that the static library variant of a given C++ runtime |
| SHALL ONLY BE LINKED INTO A SINGLE BINARY for optimal conditions. |
| |
| What this means is that if your project consists of a single shared |
| library, you can link against, e.g., stlport_static, and everything will |
| work correctly. |
| |
| On the other hand, if you have two shared libraries in your project |
| (e.g. libfoo.so and libbar.so) which both link against the same static |
| runtime, each one of them will include a copy of the runtime's code in |
| its final binary image. This is problematic because certain global |
| variables used/provided internally by the runtime are duplicated. |
| |
| This is likely to result in code that doesn't work correctly, for example: |
| |
| - memory allocated in one library, and freed in the other would leak |
| or even corrupt the heap. |
| |
| - exceptions raised in libfoo.so cannot be caught in libbar.so (and may |
| simply crash the program). |
| |
| - the buffering of std::cout not working properly |
| |
| This problem also happens if you want to link an executable and a shared |
| library to the same static library. |
| |
| In other words, if your project requires several shared library modules, |
| then use the shared library variant of your C++ runtime. |
| |
| |
| ### II.4. Shared runtimes: |
| |
| If you use the shared library variant of a given C++ runtime, keep in mind |
| that you must load it before any library that depends on it when your |
| application starts. |
| |
| As an example, let's consider the case where we have the following modules |
| |
| * libfoo.so |
| * libbar.so which is used by libfoo.so |
| * libstlport_shared.so, used by both libfoo and libbar |
| |
| You will need to load the libraries in reverse dependency order, as in: |
| |
| static { |
| System.loadLibrary("stlport_shared"); |
| System.loadLibrary("bar"); |
| System.loadLibrary("foo"); |
| } |
| |
| Note that you shouldn't use the 'lib' prefix when calling |
| System.loadLibrary(), unless you specify the full path as in: |
| |
| System.loadLibrary("/path/to/libstlport_shared.so") |
| |
| Which is not recommended, since this hard-codes the path in your code. |
| |
| - - - - |
| III. EXTRAS: |
| ------------ |
| |
| ### III.1. STLport-specific issues: |
| |
| This NDK provides prebuilt static and shared libraries for STLport, |
| but you can force it to be rebuilt from sources by defining the following |
| in your environment or your Application.mk before building: |
| |
| STLPORT_FORCE_REBUILD := true |
| |
| STLport is licensed under a BSD-style open-source license. See |
| sources/cxx-stl/stlport/README for more details about the library. |
| |
| |
| ### III.2. GNU libstdc++ license is GPLv3 + linking exception! |
| |
| Be aware that the GNU libstdc++ is covered by the GPLv3 license (and *not* |
| the LGPLv2 or LGPLv3 as some assume), full details available here: |
| |
| http://gcc.gnu.org/onlinedocs/libstdc++/manual/license.html |
| |
| Be sure that you comply with all clauses of this license. |
| |
| |
| ### III.3. libc++-specific issues: |
| |
| "-std=c++11" is turned on by default. |
| |
| Similiar to GNU libstdc++, you need to explicitly turns on exceptions or rtti |
| support in "LOCAL_CPP_FEATURES" if you wish. |
| |
| It's likely that you need libatomic if you #include <atomic>. Add |
| "LOCAL_LDLIBS += -latomic" for ndk-build, and "-latomic" for standalone toolchain. |
| Note that -latomic is only available in gcc4.8, not gcc4.6. Clang3.4/3.3 use gcc4.8's |
| as/ld/headers/libraries so they get -latomic too. The version of libatomic in gcc4.8 |
| *may* work for gcc4.6, although it's not tested and you have to copy them manually. |
| |
| This NDK provides prebuilt static and shared libraries for libc++ |
| compiled by clang, but you can force it to be rebuilt from sources by defining |
| the following in your environment or your Application.mk before building: |
| |
| LIBCXX_FORCE_REBUILD := true |
| |
| Around 98% of current 4645 tests passes when compiling libc++ with |
| clang for all supported ABIs. The remaining fails are mostly in the areas |
| of wchar_t and locale Android bionic don't support. Switching locale |
| from the default produces the following warning in logcat |
| |
| newlocale() WARNING: Trying to set locale to en_US.UTF-8 other than "", "C" or "POSIX" |
| |
| Using gabi++ as run-time also causes some issues in the nested exception and propagation too, |
| which will be addressed when libc++ switches to use libc++abi in the future. |
| |
| More fails when compiling libc++ with gcc4.8 mostly because the lack of support |
| in _Atomic (ETA: gcc 4.9). See platform/ndk.git |
| 29d9f88ef5a33cd65b4b9977aed628bc195facf3 for details |
| |
| Using libc++ with gcc4.6 is not recommended (at least not tested at |
| this moment) because its c++11 support isn't great |
| |
| See "black_list*" in |
| tests/device/test-libc++-shared-full/jni/Android.mk for tests which fail to |
| compile, and tests/device/test-libc++-shared-full/BROKEN_RUN for tests |
| which fails to run correctly. |
| |
| ### IV. Future Plans: |
| |
| - uSTL support? |
| |