I started working on the NDK - Native Development Kit using JNI.
From my understanding the NDK contains:
1. The source code containing a set of .so libraries (and c/c++ header files), each specifically compiled to different Android Architecture: such as arm, mips, x86. which supply us some c/c++ APIs to the Android device.
2. The tool chain which is responsible for the build for each Android architecture.
Example of working with the NDK:
I am using in my app, the logcat in c++ code, for this I added to my Android.mk (in Android studios - the gradle properties):
LOCAL_LDLIBS := -llog
And in my c++ code I include the header:
#include <android/log.h>
And I do see the header file in:
\platforms\android-21\arch-arm\usr\include\android\log.h
and the lib file in:
\platforms\android-21\arch-arm\usr\lib\liblog.so
My questions:
Not all APIs that exist in the Java SDK framework exist in the NDK Framework, right?
If I"m right about 1: While it seems very easy to work with the log, how do I know which APIs are supported and which are not?
For example, is there a lib for using the camera/flashlight/gps/Writing to storage or for these I have to use Java code?
I have not seen a clear API or documantation about it, not in the http://developer.android official, and not in the docs provided in the NDK installation (the stableAPIs.html contains minimal description for minimal API set), and not in the many StackOverFlow questions I read.
This is on a different subject, The NDK compiler for the android different architectures is based on GCC to compile our c++ code right? and how do I know which c++ version am I using?
Thanks
Right.
In your NDK directory, go to docs, open Start_Here.html, then click on Stable APIs for a list of APIs supported by the NDK. Note that you can call the Java APIs from C++ code through the Java Native Interface (JNI), but that's a separate topic (and slightly more advanced).
There are both GCC and Clang/LLVM toolchains included with the NDK.By C++ version, do you actually mean compiler version? If you mean compiler version, then you can specify which one you want to be used if you require a specific version:
# Specify that you want GCC 4.8 to be used. This goes in your Application.mk file
NDK_TOOLCHAIN_VERSION := 4.8
If you really meant C++ version, then unless you explictly specified a standard (e.g. with -std=c++11 or -std=c++1y) you're probably getting the C++98 standard (possibly with some extensions).
Related
I'm compiling a 3rd-party Java library for Android that uses JNI. I read the relevant pages on adding C++ support on developer.android but I'm still confused about a couple of issues regarding C++ STL runtime that I was hoping I could clear up here:
1- My library has no control over the app it will be embedded in, so I don't know if there will be other libraries that might use a static/shared STLs. If I use a static C++ runtime with ANDROID_STL=c++_static, is it safe, or should I have to worry about another library that could be using something like gnustl_static which might conflict with mine?
2- If I use a shared C++ runtime with ANDROID_STL=c++_shared, is it a guarantee that a specific element in the STL will use the libc++ runtime or could it be possible to use gnustl if it doesn't exist? For example, If I was using std::string with a shared c++ runtime (c++_shared) in an app that has another library of gnustl_static, will my std::string implementation be taken from libc++ or gnustl?
Ideally, I'd like to have a very stripped down version of a static c++ runtime with (c++_static) that only includes std::vector, std::string and std::map. I was actually planning to use something like -ffunction-sections as described here and #768.
Please advise and thank you.
Environment Details
Pkg.Desc = Android NDK
Pkg.Revision = r15c
Android Studio = 3.1.2
system: cmake Host OS: Arch Linux ($ uname -r % 4.18.5-arch1-1-ARCH)
Compiler: Clang++
STL: c++_static/c++_shared
Your concern is a very real one. But if handled properly, you can find a robust way out.
The warnings about using single C++ runtime across all libraries in the app (and the whole idea to define C++ support in NDK as APP_STL vs. most other flags such as LOCAL_CFLAGS or LOCAL_SHARED_LIBRARIES, are relevant for the native libraries that are connected. JNI libraries that never communicate directly (except through their corresponding Java layers) can use different C++ runtimes. Another point is that normal build will only package one C++ runtime shared lib into the APK. Note that versioning is also a potential hazard: if a developer who adds your library uses a different NDK release, there might be collisions or unexpected side effects when his version of STL runtime works with your code.
Therefore, to achieve maximum flexibility, your library should use a static C++ runtime. This may effect the size of the binary, but if, as you say, you use only a limited subset of STL, this extra will be rather small.
The bottom line, you will have minimum to worry about if build your shared library with libc++_static.
I'm migrating from ndk-build to CMake (it better integrates with Android Studio, and would enable us to have a single CMakeLists.txt for all platforms).
Unfortunately, our projects use some features of Android.mk that I'm not being able to replicate with CMake. More specifically:
TARGET_ARCH: we use this to include different pre-compiled binaries. How can I find the target arch with CMake?
LOCAL_ARM_MODE: is this even available in CMake?
EDIT:
When using Gradle, CMAKE_ANDROID_ARCH_ABI is not set! Use CMAKE_ANDROID_ARCH or ANDROID_ABI.
ORIGINAL:
After a bit more of Google, I've found the answer here: https://cmake.org/cmake/help/v3.7/manual/cmake-toolchains.7.html#cross-compiling-for-android-with-the-ndk
CMAKE_ANDROID_ARCH_ABI or CMAKE_ANDROID_ARCH are similar to the ndk-build TARGET_ARCH.
CMAKE_ANDROID_ARM_MODE allows setting the ARM mode (setting it to ON targets 32-bit ARM processors, while to OFF targets 16-bit Thumb processors).
I am building an application on Android using NDK and V8. I would prefer to use C++11 and GNU STL for features such as shared_ptr; however, the V8 build system seems to be hardcoded to use stlport_static as its STL variant.
Even when patching the build system to generate a fully self-contained library, V8's build does not statically link STLport into its .a files (which is to be expected), and thus I get hundreds of linker errors from unresolved symbols in libv8_base.a et al. I also do not see any way to indicate to ndk-build that it should link in stlport_static when I am using a different STL variant.
Is there a reasonable pattern to linking in stlport_static while using gnustl_static, or, better yet, is there a way of building Android V8 against gnustl_static instead?
You have a problem. Well, mixing different STLs in separate .so's is possible, with extra care; but using two STLs inside one .so is simply impossible.
You either need to implement your own shared_ptr (no big deal), but then you will face the same issue for every other feature that exists in gnustl and not in stlport.
Or you need to port V8 to gnustl (and I am afraid that the MIT license does not allow this).
I working on android project and I need to access the wstring_convert class in c++11 in gcc but the problem is gcc does not have this in its standard library, so am thinking of using clang std library in gcc compiler of this possible, or if there is any other way to use wstring_convert from external library like stlport but stlport development latest update is in 2008 !
Any help is appreciated.
You can choose
NDK_TOOLCHAIN_VERSION := clang
in your Application.mk
The standard C++ library from the LLVM project is:
http://libcxx.llvm.org/
It is a standalone, separate project from clang, but I never heard of someone using it with GCC. There are parts of the standard library which rely on compiler-specific internals (e.g., some type traits), so I am not sure this is going to work.
edit
From the front page:
libc++ is known to work on the following platforms, using g++-4.2 and clang (lack of C++11 language support disables some functionality). Note that functionality provided by is only functional with clang.
So it looks like it might actually work with at least some versions of GCC.
I've been working on an Android project which has several native C++ libraries. Compiling and debugging using Eclipse with ADT plugin works well. Obviously Android NDK uses arm-linux-gnueabi-gcc of some version to compile the native libraries.
Since I've been using NEON intrinsics heavily, I would like to try to compile the native libraries with ARM's official compiler armcc. I read everywhere that armcc is supposed to give better optimized code when using intrinsics. So I downloaded the trial version of DS-5 from ARM website, just to try and see whether there's really any speed difference.
The DS-5 seems to be just a modified version of Eclipse that uses the ARMCC toolchain, so I installed the ADT plugin. But when I compile using DS-5, it seems that the code is still generated using gcc rather than armcc.
Do you have any idea how to force DS-5 or Eclipse to build the Android native code using armcc? Or is it possible (and how) to build the static NDK libraries from command line and then replace the libraries in my project, so they get deployed to the testing phone?
ARM DS-5 Community Edition doesn't include ARM compiler (armcc).
If you could get hold of armcc best would be to separate your processing heavy algorithms to individual compilation units (separate C files), build them with armcc as you would do for any compilation unit. When you get the object files, convert them into an archive then use that in Android.mk as LOCAL_STATIC_LIBRARIES += <your_archive>.
You can't use armcc plainly to build Android compatible libraries mostly because of Bionic dependencies, I think.
You can use armcc to build Android compatible static libraries even though Android has a different C library (bionic). The key is the --library_interface flag for armcc. According to the documentation:
Use an option of the form --library_interface=aeabi_* when linking with an ABI-compliant C library. Options of the form --library_interface=aeabi_* ensure that the compiler does not generate calls to any optimized functions provided by the ARM C library.
In addition, there are a few more flags to ensure compatibility with the Android EABI resulting in the following command for an Android armeabi-v7a target:
armcc --library_interface=aeabi_clib --wchar32 --enum_is_int --no_hide_all --cpu=7-A --fpu=softvfp+vfpv3 -c -o libfunc.o libfunc.c
You can then use armar --create libfunc.a libfunc.o to create a static library that can be linked with the Android NDK as LOCAL_STATIC_LIBRARIES.
I have successfully tested this with Android NDK r10d on Android KitKat 4.4.2.