2

I have Android app which builds armeabi-v7a and arm64-v8a. Here is the build.gradle:

apply plugin: 'com.android.library'

allprojects {
    repositories {
        jcenter()
        google()
    }
}

android {
    compileSdkVersion 28
    defaultConfig {
        minSdkVersion 21
        targetSdkVersion 28
        versionCode 1
        versionName "1.0"
        externalNativeBuild {
            cmake {
                // Linker flags and Visibility options keeps the size of the library small
                cppFlags "-std=c++11"
                arguments "-DANDROID_STL=gnustl_static",
                          "-DANDROID_CPP_FEATURES=rtti exceptions",
                          "-DANDROID_TOOLCHAIN=gcc"
            }
        }
    }

    buildTypes {
        release {
            ndk {
                abiFilters 'armeabi-v7a', 'arm64-v8a'
            }
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            externalNativeBuild {
                cmake {
                    cppFlags "-Wl,--exclude-libs=ALL -Wl,--gc-sections -fvisibility=hidden -fvisibility-inlines-hidden -ffunction-sections"
                }
            }
        }
        debug {
            ndk {
                abiFilters 'armeabi-v7a', 'arm64-v8a'
            }
        }
    }
    externalNativeBuild {
        cmake {
            path 'CMakeLists.txt'
        }
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
}

I am using the minSdkVersion = 21 to support arm64. I would like to change the minSdkVersion based on the abiFilters i.e., use 16 for v7 and use 21 for arm64.

shizhen
  • 12,251
  • 9
  • 52
  • 88
ssk
  • 9,045
  • 26
  • 96
  • 169

2 Answers2

2

You don't need to do anything mentioned in the selected answer. Just set minSdkVersion 16 and the 64-bit ABIs will automatically use minSdkVersion 21 because that's the lowest available API for 64-bit.

Dan Albert
  • 10,079
  • 2
  • 36
  • 79
  • After long time of debugging I found out that this is not necessarily the case. It works with the latest NDK 23 like your describe here, but when compiling my cpp file with NDK 16 the compiled 64bit variants were not included in the apk. The approach with the build variants and having a different minsdk (21) worked fine though. I hope I can save somebody some wasted hours figuring this out :) – Michael Troger Aug 22 '21 at 10:48
1

For how the minSdkVersion property works, see below quotes from official documentation:

  1. If there exists a platform version for the ABI equal to minSdkVersion, CMake uses that version. Otherwise,
  2. if there exists platform versions lower than minSdkVersion for the ABI, CMake uses the highest of those platform versions. This is a reasonable choice because a missing platform version typically means that there were no changes to the native platform APIs since the previous available version.
  3. Otherwise, CMake uses the next available platform version higher than minSdkVersion.

And it has ever been mentioned in may answer to your another question: Android Studio CMake/Ninja Not Used for Building an NDK project.

I am using the minSdkVersion = 21 to support arm64. I would like to change the minSdkVersion based on the abiFilters i.e., use 16 for v7 and use 21 for arm64.

My understanding is that you are trying to support older (api level lower than 21) 32-bit devices without 64-bit native binaries. I would like to say "productFlavor" is the right direction to go. E.g. you can have your gradle configuration like below to achieve what you expect:


android {
   ...

    flavorDimensions "api", "mode"

    productFlavors {

        minApi16 {
            dimension "api"
            minSdkVersion 16
            versionCode android.defaultConfig.versionCode
            versionNameSuffix "-minApi16"
            ndk {
                abiFilters 'armeabi-v7a'
            }
        }

        minApi21 {
            dimension "api"
            minSdkVersion 21
            versionCode android.defaultConfig.versionCode
            versionNameSuffix "-minApi21"
            ndk {
                abiFilters 'arm64-v8a'
            }
        }

    }
   ...
}

The minSdkVersion 16 and minSdkVersion 21 will help you choose the best suitable NDK version.


Edit #1

How to choose different minSdkVersion for different android ABI?

minSdkVersion is the property telling the minimum Android version that your app can install on. For one single APK, this is an unconditional characteristic. So:

  • If you want to have one single APK to support all the devices starting from api 16, then you have to set your minSdkVersion to 16.
  • If you want to have one single APK to support both 32-bit devices and 64-bit devices, you have to provide a complete set of ALL the shared libraries both 32-bit and 64-bit.

Or else, you have to provide different APKs split by ABIs and minSdkVersion.

shizhen
  • 12,251
  • 9
  • 52
  • 88
  • Thanks for the answer. How does minApi16 correspond to armeabi-v7a while building (same for minApi21 w.r.t arm64-v8a)? – ssk Jun 03 '19 at 16:27
  • You can add `abiFilters` inside the minApi16 flavor to let it only have `armeabi-v7a` and same for minApi21, see my updates in the answer. – shizhen Jun 04 '19 at 01:16
  • You don't need to do this. Just set `minSdkVersion 16` and it automatically uses 21 for arm64 because that was the first available version. – Dan Albert Jun 05 '19 at 19:42