My scenario is quite simple. I have a native library that I compile using the externalNativeBuild system with CMake. This works well for building my application, but I would like to load that same library during machine-local (i.e. non-emulator) unit tests.
If I have an existing Gradle NDK setup that includes the following, is there a way to reuse this to compile the library for the host operating system (e.g. macOS)?
defaultConfig {
ndk {
abiFilters 'x86', 'x86_64', 'armeabi', 'armeabi-v7a', 'arm64-v8a'
}
externalNativeBuild {
cmake {
arguments '-DANDROID_TOOLCHAIN=clang', '-DANDROID_STL=c++_static'
}
}
}
externalNativeBuild {
cmake {
path 'CMakeLists.txt'
}
}
I also did some research on exactly this topic, it's not possible without a fair amount of manual work. Here's what I came up with:
Sadly there is no out of the box support for this in Gradle except what the Aadroid plugin for Gradle provides specifically for Android projects by invoking CMake or ndk-build.
The easiest way to go seems to be invoke CMake with another toolchain for building host binaries. You can do that by directly invoking Cmake with the host toolchain or add some custom tasks to Gradle that do it for you.
Unit Tests in C
If you want to unit test your C code only, you can have CMake compile an executable that uses your usual library and tests it.
Unit Tests in Java
If you want to do the tests on level of the Java code which invokes the C code via JNI you also have to move the library which CMake outputs in the right place for the JVM to find it when you try to load the native library.
Solve this problem for humanity
IMO all of this is much harder than it should be. Other alternatives, which would make it even harder are trying to
It would be really interesting for the Android ecosystem if someone took a shot at implementing the 2nd suggestion.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With