NDK r10 b 32 bit or 64 bit or compile using both and how to achieve it

Shajo picture Shajo · Apr 26, 2015 · Viewed 9.7k times · Source

When I ndk compile a project using r10b 64 bit builder it compiles good without any problem

I am able to run the project in Lollipop succesfully and app runs as it supposed to be

But when I run the project in JellyBean at runtime I get the following error

could not load library "libopenvpn.so" needed by "/data/data/de.blinkt.openvpn/cache/pievpn.armeabi-v7a"; caused by soinfo_relocate(linker.cpp:987): cannot locate symbol "srandom" referenced by "libopenvpn.so"...CANNOT LINK EXECUTABLE

so when I researched I found its due to using 64 builder and solution is to use 32 bit builder.

When I use 32 builder I get the following error during compilation itself.

Android NDK: NDK Application 'local' targets unknown ABI(s): arm64-v8a x86_64 Android NDK: Please fix the APP_ABI definition in ./jni/Application.mk
/Users/ShajilShocker/Documents/Android/NDK/android-ndk-r10b/build/core/setup-app.mk:112: *** Android NDK: Aborting . Stop.

so If I omit arm64-v8a and x86_64 then it'd possibly compile but it won't run on 64 bit devices it seems.

is it possible that I can compile the same project first using 32 bit (commenting 64 architectures) and compile using 64 bit(uncomment 64 architectures) and run on both.

Any help is highly appreciated !

Thanks !

Answer

BitBank picture BitBank · Apr 27, 2015

64-bit ARM & X86 devices (not sure about MIPS) running Lollipop can execute 32 or 64-bit native code (ARMv7a/ARMv8 and X86/X64). Android allows you to bind native code libraries with multiple ABI's (CPU-specific code) into an APK. These are also called "FAT" binaries. For example, to build a FAT binary containing both ARMv7a and ARMv8 code, add the following line to your Application.mk file:

APP_ABI := arm64-v8a armeabi-v7a

Then, in your Android.mk file, you can add specific settings for each CPU type:

ifeq ($(TARGET_ARCH_ABI),armeabi-v7a)
<your custom ARM 32-bit build instructions here>
endif

ifeq ($(TARGET_ARCH_ABI),arm64-v8a)
<your custom ARM 64-bit build instructions here>
endif

When you run your fat binary containing both 32 and 64-bit code on a 32-bit system, it will load the 32-bit code and vice versa. There shouldn't be any need to conditionally compile in the code for each target device. That's the purpose of the fat binary - the system automatically loads the library appropriate for the target architecture.