Android: missing features in CMake vs ndk-build - android

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).

Related

C++20 standard library on Android? std::source_location support

I have an issue with Android support in log4cplus. I can use std::source_location in MSVC and in both GCC and Clang on Ubuntu. But the Android NDK, while it uses Clang 14, seems to lack that. Is there some variable I can use to enable it or C++20 conforming standard C++ library in CMake Android build? See https://github.com/wilx/log4cplus/actions/runs/4213340922/workflow for the GitHub action descriptor.
Libc++ only supports std::source_location starting with LLVM/Clang version 16, see https://libcxx.llvm.org/Status/Cxx20.html, which as far as I can tell means that at the moment no Android NDK supports it.
On Ubuntu you are probably using libstdc++ with Clang, which is a separate implementation of the standard library (part of GCC).

Find the NDK version used for building OpenCV Android native libraries

Suppose I have prebuilt OpenCV Android native libraries, such as this. How to find which version of NDK is used for building this?
I am curios about this because OpenCV 3.4.3 prebuilt Android libraries seems to incompatible (?) with NDK r18.
OpenCV library contained this information. Open the prebuilt library in Notepad++ and search for "General configuration for OpenCV".
Assuming it was built with a new enough version of the NDK (I don't remember exactly when we added this, but it's been a year or two), there's an ELF note baked into the binaries. Can use https://android.googlesource.com/platform/ndk/+/master/parse_elfnote.py to parse it. It'll show you something like the following:
$ python parse_elfnote.py $NDK/sources/cxx-stl/llvm-libc++/libs/arm64-v8a/libc++_shared.so
----------ABI INFO----------
ABI_ANDROID_API: 21
ABI_NDK_VERSION: r18
ABI_NDK_BUILD_NUMBER: 5002713

Android NDK native libraries and documentation

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).

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.

Which compiler does Android NDK use?

I'm writing ARM NEON-based code for an Android application and I was struggling with certain compiler flags not being recognized. I later realized that support for those flags was only added quite recently and that my GCC version is older. I'm doing the whole thing on Windows and am limited by what versions Cygwin has to offer. Here's my question: before I go and try to build GCC 4.6.0 on my Windows machine and make Cygwin like it, will it work for me or does the NDK use its own version of the GCC and my upgrade will not at all affect it? If it does, is it possible to tell it to use a different compiler?
Regarding NDK r8d it can be modified in 2 ways (see Andriod ndk):
For ndk-build, export the NDK_TOOLCHAIN_VERSION=4.7 variable or add it to Application.mk.
For standalone builds, add the --toolchain= option to make-standalone-toolchain.sh
--toolchain=arm-linux-androideabi-4.7
Default compiler is set in ndk/build/core/setup-toolchain.mk (see NDK_TOOLCHAIN and NDK_TOOLCHAIN_VERSION)
The NDK itself invokes a customized cross-compiler built on the arm-eabi-gcc compiler. There are examples out there of people creating custom toolchains using bog-standard GCC implementations with support for ARM instruction sets but that's way out of my league. Most of the stuff I've read in the past always discussed using the toolchain included with the NDK to compile native code.
Corollary: Most of the people who have complained and have had to make their own toolchain have been people that were upset with the (supposed) sub-par C++ support of the NDK toolchain's compiler. I can't speak to this because some of the articles were older and Android changes so rapidly. It also hasn't been an opinion that seems to pop up all too frequently.
GCC is deprecated in favor of clang as of NDK 11 (March 2016)
Mentioned on the official revision history: https://developer.android.com/ndk/downloads/revision_history.html
How to switch between compilers is asked at:
How to switch between gcc and clang in Android NDK Revision 11?
Latest C++11 features with Android NDK
And you can check it easily with:
enum CONSTEXPR {N = 256};
char s[N];
#ifdef __clang__
snprintf(s, N, "%s", "clang" __clang_version__);
#else
# ifdef __GNUC__
snprintf(s, N, "%s %d.%d.%d", "gcc", __GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__);
# endif
#endif
then just log s or return it to a TextView.

Categories

Resources