OpenCL on Android >= API 23 - android-ndk

I want to know how android nougat dynamic linkage restrictions will affect using opencl libraries provided by vendors in newer (in api 24 any dynamic linkage except linking to ndk public libraries will fail) android versions ?

Related

Android cash : UnsatisfiedLinkError: dlopen failed: cannot locate symbol "pthread_cond_clockwait"

I am trying to import native libraries(.so files) into the android studio.
I created a jniLibs folder and directory with ABI name and respective .so files in it.
made changes in build.gradle and tried to load them.
Then, the error occurs of java.lang.UnsatisfiedLinkError: dlopen failed: cannot locate symbol "pthread_cond_clockwait"
can someone give idea how to solve this issue?
That API is only available on API 30+ devices (note the __INTRODUCED_IN(30)):
int pthread_cond_clockwait(pthread_cond_t* __cond,
pthread_mutex_t* __mutex,
clockid_t __clock,
const struct timespec* __timeout) __INTRODUCED_IN(30);
You're probably seeing the problem on an older device.
As per the Android documentation, it is important to realize that the NDK API level is your app's minimum supported API level:
The API level you build against with the NDK has a very different meaning than compileSdkVersion does for Java. The NDK API level is your app's minimum supported API level. In ndk-build, this is your APP_PLATFORM setting. With CMake, this is -DANDROID_PLATFORM.
So you need to compile the library with the correct NDK API level:
Problem: Your NDK API level is higher than the API supported by your device.
Solution: Set your NDK API level (APP_PLATFORM) to the minimum version of Android your app supports.

Shared library bundled in the apk is not found at runtime

I do some native Android development which involves OpenSSL.
I cross compile it for armeabi (32b) using the Android NDK stand-alone toolchains. I cross-compile the native C libraries, copy the OpenSSL/native library .so files inside of my libs/ folder, which is referenced by my gradle this way:
sourceSets {
main {
jniLibs.srcDir(file("libs/"))
}
}
Anyway, the end result is that my .apk looks like this:
- > classes.dex
- > lib/
-> armeabi/
-> libcrypto.so
-> libssl.so
-> libmynativelibrary.so
- > res/ (...)
- > resources.arsc
- > META-INF/ (...)
- > kotlin/ (...)
- > AndroidManifest.xml
The shared libraries are correct 32-bit ARM ELF files. I've been using this exact APK on an API level 24 device with great success (Android 7.0+).
The issue: When I switch to an API level 21 device (Android 5.1-, I suspect that I would have the same issue with Android 6.0), the program instantly crashes when loading libmynativelibrary.so.
Since libcrypto.so is a dependency of libmynativelibrary.so, the program attempts to load it. It actually works fine on API level 24+, but crashes on API level 23-. It's because the loaded library is not the one in my .apk, but the one in the system. And such libraries seem to not be available below API level 24.
My question: How do I explicitly tell Android to look for the library in the .apk file first instead of the regular system libraries directories?
Thanks in advance.
Before Nogut, the system libraries were not protected from user apps. The name collisions are problematic, they caused Google to invent a separate namespace for the C++ shared runtime library, which is part of Android NDK.
The OpenSSL libraries are also widely used beyond your control. They may get loaded into your process even before you have a chance to load your own libssl.
Therefore, the best choice would be to build OpenSSL as static libs, and have libmynativelibrary.so linked to it statically. This way you have a monolithic binary that does not depend on others.
If you cannot follow this course, you should build OpenSSL libraries with mangled names, e.g. libmyssl.so and libmycrypto.so. This may help to avoid the simple name clash with system libraries.
Even better, follow the example of NDK and provide a unique namespace to you SSL API.
Don't expect that loading the libraries explicitly from their unpacked location at ApplicationInfo.nativeLibraryDir will be a robust solution: as I hunted before, the system libraries may happen to get loaded into your address space before.
Note that before Lollipop, you have too manually load all non-system dependencies, and in the proper order.
Also, the new NDK has dropped armeabi , so consider switching to armeabi-v7a.

Which (if any) NDK libraries/headers are compatible with other toolchains

I'm working on a project that is compiled using the arm-linux-musleabi toolchain which builds against musl libc. What are my options to use NDK features such as Android jni.h? Am I wrong when assuming that jni.h on Android NDK is not the same as standard jni.h that targets actual Java? I know porting the project to NDK could be the best approach, but let's assume that its not possible for my case. In other words, 'build using NDK' is not an option even though it would be the wiser path. Also note that JNI features are just used as an example, this question applies to any Android NDK c/c++ libraries that may be used as a drop in with non-ndk toolchains.

How to declare some symbols used by JNI shared library weak in Android Studio NDK?

I have a JNI shared library built using the experimental Gradle NDK plug-in for Android Studio, and this library links to some OS library symbols that only exist after a specific Android version.
How to I define these specific symbols to be weak linked, or as a fallback, make the entire OS library containing them weak linked? The intent is that the JNI library doesn't fail to load on these older OSes and the symbols are just null at run time.
Concrete example: signal() in libc doesn't appear to be available pre-4.0.

Feature compliance across different OS versions for the Android NDK

Are NDK features OS dependent? For example, if I have Gingerbread 2.3, can I only use NDK features for 2.3 and below, or can I take advantage of the latest fixes and features the NDK provides?
The main reason I'm asking is because it seems like the NDK is a completely different beast than the SDK, and due to the nature of C/C++ and the underlying internals of the OS should be cross version compatible.
Unfortunately it is as version-dependent as SDK. Each release of NDK bundles an ever-growing list of platforms. Typically, ndk-build chooses the platform according to android:targetSdkVersion as defined in AndroidManifest.XML.

Resources