Best Architecture for C++ Libraries used in Android - android

I am compiling a c++ library to be used on my Android device.
In compiling the library I did not take into account the architecture I was building the library for.
As a result I have a 64 bit dynamically linked shared library x86_64 which only works on 64 bit systems.
I intend to link this library to my android device using the JNA tool.
What is the appropriate way to compile my c++ library for android architecture and JNA.

You must use the Android NDK.
Depending on the target architecture, you must select the appropriate toolchain/cross-compiler, e.g. ARM, MIPS or x86.
See also Getting Started with the NDK
JNI or JNA have nothing to do with how the library is built. You must build the library for your target architecture, so it can be used on your phone or tablet.
To access this library from Java, you may use either JNI or JNA.
With JNI, you must implement glue code in C/C++. With JNA on the other side, you do more or less the same, but you use an existing library (libffi) and implement the glue code in Java. This is done dynamically at runtime and may be thought of something like reflection for a library.

Related

Android NDK: Static or shared C++ runtime for 3rd-party Java library

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.

How to use external native library in Android

I am trying to learn NDK, and I'd like to use external library (libopus). After reading some articles, I got these steps:
git clone https://android.googlesource.com/platform/external/libopus
mv libopus jni
NDK_PROJECT_PATH=. ndk-build
It crated libs/armeabi/libopus.so file. Yay, awesome! ... And now what? How can I use this library? How can I call its functions and methods?
Also, will my app run on non-ARM architectures (x86, MIPS), because armeabi suggests it'll be ARM only.
You can not just use standard Linux libraries. Java/Android uses the Java Native Interface (JNI) which is special C code that builds the bridge between Java part and native part.
It looks like you already have NDK installed. Look into the project samples, e.g. the "hello-jni" project. In this example you can see what JNI C code you have to write and how to access the self written functions from within your Java code.
Regarding the architectures: Yes, an ARM library is for the ARM platform only. If you want to create a cross-platform App you have to compile all native libraries for each supported platform (usually ARM, ARMv7, x86 and MIPS).

Use ARMCC to compile Android native library

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.

How to add already compiled C library to Android?

I have already compiled libraries (for linux(.a) and windows(.dll)). I need to import one of those (I guess for Android I will have to use .a) libraries into my android project.
So I have read some tutorials on NDK, but here is a question - do I need to have source files in order to add libraries to android or I can add already compiled?
You have to use the Android NDK to recompile the library. The ARM architecture is completely different from the x86 architecture. The system calls are different on Linux and Windows. It just cannot be done.

Libraries available on Android NDK?

Are there any libraries available by default in the Android NDK? If not, can I use any c++/c library, as long as I include it myself?
In particular, I need compression, encryption, regex and sqlite. I was thinking of using zlib, crypto++, sqlite(duh!) and boost, but can use anything else if it is already available.
Also, if nothing is available built-in, would you recommend something other then my above choice (I prefer public-domain when possible, or BSD or similar)
SQLite is available on Android via abstracted database access in Java. The ‍.so itself is private. You can of course compile your own SQLite library if you require modifications, but in general you should access it from Java. I have done this for encryption purposes.
zlib is available to the NDK
crypto++ could of course be compiled via the NDK
Boost certainly works on Android/NDK (I'm currently using it heavily)
By default Android NDK delivers some libraries, so called 'stable native APIs' (http://developer.android.com/sdk/ndk/overview.html):
libc (C library) headers
libm (math library) headers
JNI interface headers
libz (Zlib compression) headers
liblog (Android logging) header
OpenGL ES 1.1 and OpenGL ES 2.0 (3D graphics libraries) headers
libjnigraphics (Pixel buffer access) header (for Android 2.2 and above).
A Minimal set of headers for C++ support
OpenSL ES native audio libraries
Android native application APIS
First, I think you need to download the NDK package from here: http://developer.android.com/sdk/ndk/index.html and investigate the documentation from the package. I'm sure you will get the answers to most of your questions.
And quick answer to your questions. Yes there are libraries by default in the Android NDK. For example standard C and C++ libraries.
This is only a partial answer with respect to Crypto++....
Crypto++ has a wiki page with build instructions from the command line at Android (Command Line). The process will create the various libraries and show you how to build cryptest.exe to verify the library on a device. But you will still need to create you wrapper project using Android's build system.
Piotr Morgwai Kotarbiński has a page on building the Crypto++ library with Android's modified build system. See Building Crypto++ with NDK toolchain. I don't believe Piotr's article verifies the library on a device.

Categories

Resources