Nexus7 can’t load native library

Issue

I try to build native libraries (in my case SQLite) to add them to my Android project.

My problem: My Nexus7 with Android 6.0.1 tries to load it from the ../lib/arm/libsqlite3.so path. But this path doesn’t exist.

From the beginning:

  1. I downloaded the sqlite-amalgamation-3310100.zip

  2. In this folder, I created a CMakeLists.txt file with this content:

    cmakeminimumrequired(VERSION 3.4.1)

    adddefinitions(-DSQLITEDQS0)
    adddefinitions(-DSQLITEDEFAULTMEMSTATUS0)
    add
    definitions(-DSQLITEDEFAULTWALSYNCHRONOUS1)
    add
    definitions(-DSQLITELIKEDOESNTMATCHBLOBS1)
    adddefinitions(-DSQLITEMAXEXPRDEPTH0)
    adddefinitions(-DSQLITEOMITDECLTYPE1)
    add
    definitions(-DSQLITEOMITDEPRECATED1)
    adddefinitions(-DSQLITEOMITPROGRESSCALLBACK1)
    adddefinitions(-DSQLITEUSE_ALLOCA1)

    add_library(
    # Specifies the name of the library.
    sqlite3

    # Sets the library as a shared library.
    SHARED
    
    # Provides a relative path to your source file(s).
    shell.c
    sqlite3.c
    sqlite3.h
    sqlite3ext.h
    

    )

  3. I built the lib with this command (followed by make):

    ~/development/sdks/android-sdk/cmake/3.10.2.4988404/bin/cmake \
    -DANDROIDNDK~/development/sdks/android-sdk/ndk/21.0.6113669 \
    -DCMAKE
    TOOLCHAINFILE~/development/sdks/android-sdk/ndk/21.0.6113669/build/cmake/android.toolchain.cmake \
    -DCMAKE
    LIBRARYOUTPUTDIRECTORYarmeabi-v7a \
    -DANDROIDTOOLCHAINclang \
    -DANDROID
    ABIarmeabi-v7a \
    -DANDROIDNATIVEAPI_LEVEL29

I did this for this 4 ABI: armeabi-v7a, arm64-v8a, x86 and x86_64.

After that, I copied the .so files into the app/src/main/jniLibs/<abi> folder, the folder structur looks like this:

.
├── app
│&nbsp;&nbsp; └── src
│&nbsp;&nbsp;     ├── main
│&nbsp;&nbsp;     │&nbsp;&nbsp; ├── jniLibs
│&nbsp;&nbsp;     │&nbsp;&nbsp; │&nbsp;&nbsp; ├── arm64-v8a
│&nbsp;&nbsp;     │&nbsp;&nbsp; │&nbsp;&nbsp; │&nbsp;&nbsp; └── libsqlite3.so
│&nbsp;&nbsp;     │&nbsp;&nbsp; │&nbsp;&nbsp; ├── armeabi-v7a
│&nbsp;&nbsp;     │&nbsp;&nbsp; │&nbsp;&nbsp; │&nbsp;&nbsp; └── libsqlite3.so
│&nbsp;&nbsp;     │&nbsp;&nbsp; │&nbsp;&nbsp; ├── x86
│&nbsp;&nbsp;     │&nbsp;&nbsp; │&nbsp;&nbsp; │&nbsp;&nbsp; └── libsqlite3.so
│&nbsp;&nbsp;     │&nbsp;&nbsp; │&nbsp;&nbsp; └── x86_64
│&nbsp;&nbsp;     │&nbsp;&nbsp; │&nbsp;&nbsp;     └── libsqlite3.so

When I now run the app, I get the following error message:

java.lang.UnsatisfiedLinkError: dlopen failed: cannot locate symbol "__aeabi_memcpy"
referenced by "/data/app/com.example.myapplication-2/lib/arm/libsqlite3.so"...

Why does Android try to load the lib from the lib/arm folder and not from lib/armeabi-v7a? It works when I do the same with a different device with Android 7.1.1.

Btw, The Android Native Lib demo project works too. And when I look into its apk, the native lib is in the lib/armeabi-v7a folder. So why does it work when Android Studio compiles the native code but not when I add a precompiled native lib?

Solution

As Michael wrote, I have to set the right DANDROID_NATIVE_API_LEVEL. To get it running on Android 6.0.1 I have to use API level 23 or below. So the cmake command should look like this:

~/development/sdks/android-sdk/cmake/3.10.2.4988404/bin/cmake \
    -DANDROID_NDK~/development/sdks/android-sdk/ndk/21.0.6113669 \
    -DCMAKE_TOOLCHAIN_FILE~/development/sdks/android-sdk/ndk/21.0.6113669/build/cmake/android.toolchain.cmake \
    -DCMAKE_LIBRARY_OUTPUT_DIRECTORYarmeabi-v7a \
    -DANDROID_TOOLCHAINclang \
    -DANDROID_ABIarmeabi-v7a \
    -DANDROID_NATIVE_API_LEVEL19

Answered By – Ralph Bergmann

Leave a Comment