Ven Shine
Ven Shine

Reputation: 9326

I want to use different library in debug and release mode In Android

debug:

jniLibs/armeabi/a.so

release:

jniLibs/armeabi/b.so

I want to use a.so in debug mode and b.so in release mode, how can I do in build.gradle or other?

The .so library is third library, placed in jniLibs/armeabi/. I don't know the specific call timing, so I cannot use System.loadLibrary() method.

Thanks!

Upvotes: 0

Views: 2098

Answers (4)

Joma
Joma

Reputation: 3859

My Original answer - Where to place JNI/native libraries in Android Studio Project

Based on shizhen answer

Year Gradle Version Android Studio Version CMake Version NDK Version
2024 8.4 Android Studio Iguana - 2023.2.1 3.22.1 26.2.11394342

build.gradle.kts - module or app

android {
 
    ...
 
    buildTypes {
        release {
            isMinifyEnabled = false
            proguardFiles(
                getDefaultProguardFile("proguard-android-optimize.txt"),
                "proguard-rules.pro"
            )
            sourceSets {
                getByName("release"){
                    jniLibs.srcDirs("src/main/nativeLibs/Release")
                }
            }

        }
        debug {
            sourceSets {
                getByName("debug"){
                    jniLibs.srcDirs("src/main/nativeLibs/Debug")
                }
            }
        }
    }

    ...

}

With the Android perspective. Only the "jniLibs" folder is shown with the respective ABIs. Check mark (debug) or (release) depending on the selected variant.

Android perspective - Debug Android perspective - Release Project perspective
debug release project perspective

CMakeList.txt

${CMAKE_BUILD_TYPE} can be Debug or Release when building is active.
${CMAKE_ANDROID_ARCH_ABI} can be amr64-v8a or armeabi-v7a or x86 or x86_64 when building is active.

cmake_minimum_required(VERSION 3.22.1)

set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED TRUE)
project("xdata")

set(LIB_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../nativeLibs/${CMAKE_BUILD_TYPE}/${CMAKE_ANDROID_ARCH_ABI})
set(MY_LIB "${LIB_PATH}/libMy.so")

include_directories(${CMAKE_SOURCE_DIR}/include)

add_library(${CMAKE_PROJECT_NAME} SHARED
        libinsane.cpp)

target_link_libraries(${CMAKE_PROJECT_NAME}
        android
        ${MY_LIB}
        log
        )

Upvotes: 1

shizhen
shizhen

Reputation: 12583

Historically the NDK supported ARMv5 (armeabi), and 32-bit and 64-bit MIPS, but support for these ABIs was removed in NDK r17.

Also, note below anouncement from Google:

Starting August 1, 2019, your apps published on Google Play will need to support 64-bit architectures. 64-bit CPUs deliver faster, richer experiences for your users. Adding a 64-bit version of your app provides performance improvements, makes way for future innovation, and sets you up for devices with 64-bit-only hardware.

So, you should stop using the legacy armeabi for your Android applications. And, start to use the 64-bit ABIs. See https://developer.android.com/distribute/best-practices/develop/64-bit and https://developer.android.com/ndk/guides/abis for more details.

For how to organise the debug and release build type, theoretically, you can put the mynative-lib.so anywhere you like, e.g. they are under /Users/<your-usr-name>/android/jniLibs. But, I would like recommend you to arrange your debug and release build types as below (per each supported ABI):

jniLibs
├── debug
│    ├── arm64-v8a
│    │   └── mynative-lib.so
│    ├── armeabi-v7a
│    │   └── mynative-lib.so
│    ├── x86
│    │   └── mynative-lib.so
│    └── x86_64
│        └── mynative-lib.so
└── release
     ├── arm64-v8a
     │   └── mynative-lib.so
     ├── armeabi-v7a
     │   └── mynative-lib.so
     ├── x86
     │   └── mynative-lib.so
     └── x86_64
         └── mynative-lib.so

Then configure your app/build.gradle file for it to point to the correct build types, i.e.

android {
    ...
    sourceSets {
        main {
            // put your jni libs that do not distinguish debug and release.
            jniLibs.srcDirs += "/Users/<your-usr-name>/android/jniLibs"]
        }
        debug {
            // put your debug version jni libs.
            jniLibs.srcDirs += "/Users/<your-usr-name>/android/jniLibs/debug"]
        }
        release {
            // put your release version jni libs.
            jniLibs.srcDirs += "/Users/<your-usr-name>/android/jniLibs/release"]
        }
    }
    ...
}

NOTE: Replace /Users/<your-usr-name>/android/jniLibs with your own correct path.

Upvotes: 2

user1506104
user1506104

Reputation: 7086

Here is another alternative. Add your debug SO file like so:

app/src/debug/jniLibs/armeabi/<yourdebug>.so

Retain your release SO file in the main sourceset like so:

app/src/main/jniLibs/armeabi/<yourrelease>.so

It is important that <yourdebug>.so and <yourrelease>.so have the same filename for this to work.

Cheers!

Upvotes: 4

user1506104
user1506104

Reputation: 7086

If you are using System.loadLibrary() to load your SO files, do this:

public final static boolean IS_DEBUG = BuildConfig.BUILD_TYPE.equalsIgnoreCase("debug");

static {
    if(IS_DEBUG) {
        System.loadLibrary("yourdebugso");
    }
    else {
        System.loadLibrary("yourreleaseso");
    }
}

Upvotes: 1

Related Questions