androidandroid-ndkandroid-native-library

Nexus7 can't load native library


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:

cmake_minimum_required(VERSION 3.4.1)

add_definitions(-DSQLITE_DQS=0)
add_definitions(-DSQLITE_DEFAULT_MEMSTATUS=0)
add_definitions(-DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1)
add_definitions(-DSQLITE_LIKE_DOESNT_MATCH_BLOBS=1)
add_definitions(-DSQLITE_MAX_EXPR_DEPTH=0)
add_definitions(-DSQLITE_OMIT_DECLTYPE=1)
add_definitions(-DSQLITE_OMIT_DEPRECATED=1)
add_definitions(-DSQLITE_OMIT_PROGRESS_CALLBACK=1)
add_definitions(-DSQLITE_USE_ALLOCA=1)

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
)

  1. I built the lib with this command (followed by make):
~/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_DIRECTORY=armeabi-v7a \
    -DANDROID_TOOLCHAIN=clang \
    -DANDROID_ABI=armeabi-v7a \
    -DANDROID_NATIVE_API_LEVEL=29

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
│   └── src
│       ├── main
│       │   ├── jniLibs
│       │   │   ├── arm64-v8a
│       │   │   │   └── libsqlite3.so
│       │   │   ├── armeabi-v7a
│       │   │   │   └── libsqlite3.so
│       │   │   ├── x86
│       │   │   │   └── libsqlite3.so
│       │   │   └── x86_64
│       │   │       └── 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_DIRECTORY=armeabi-v7a \
        -DANDROID_TOOLCHAIN=clang \
        -DANDROID_ABI=armeabi-v7a \
        -DANDROID_NATIVE_API_LEVEL=19