I want to add ndk.abiFilters property in gradle.properties file. Now I've this property inside build.gradle.
Here is part of my build.gradle
buildTypes {
debug {
ndk {
abiFilters "x86", "armeabi-v7a", "armeabi"
//abiFilters ABI_FILTERS
}
}
}
Here's part of my gradle.properties file
ABI_FILTERS = "x86", "armeabi-v7a", "armeabi"
Problem is that String from gradle.properties is not correctly converted for use with abiFilters. I tried many variants but with no luck. What is the correct way how to do this correctly? Thank you for help.
In gradle.properties you can have for example:
ABI_FILTERS=armeabi-v7a;x86 //delimiter can be anything (change below)
Then in build.gradle there is (for example in debug buildType section):
ndk {
abiFilters = []
abiFilters.addAll(ABI_FILTERS.split(';').collect{it as String})
}
Now each developer can choose independetly abi for his current testing device (gradle.properties is in .gitignore).
Thanks Igor Ganapolsky for starting hint.
Following works with Gradle 2.3:
abiFilters 'x86', 'x86_64', 'armeabi', 'armeabi-v7a', 'arm64-v8a'
gradle.properties file
ABI_FILTERS = ["armeabi", "x86"]
build.gradle file
ndk {
abiFilters = []
abiFilters.addAll(ABI_FILTERS)
}
Use this:
flavorDimensions "abi"
productFlavors {
arm7 {
dimension "abi"
ndk.abiFilters 'armeabi-v7a'
}
x86 {
dimension "abi"
ndk.abiFilters 'x86'
}
}
You can see an example of this setting in the Google samples for NDK: https://github.com/android/ndk-samples/blob/8132651aba8db36b14e0d0461c7cb46d3778f99c/other-builds/ndkbuild/hello-neon/app/build.gradle
This can also be done for flutter.
Add:
android{
buildTypes{
debug {
ndk {
abiFilters 'arm64-v8a'
}
}
}
}
to android\app\build.gradle. That works to remove the x86 libflutter.so libraries from the debug builds and shortens installation time. Works for gradle 7.2
Related
I'm following the guide on Android ABIS doc and it said to use 'arm64-v8a' to meet with Play Store 64 bit requirements.
I added my so files under libs/arm64-v8a/ And then I added abiFilter as follows:
defaultConfig {
...
ndk {
abiFilters 'armeabi' 'arm64-v8a'
}
...
}
When I build the project, I keep getting error
Could not get unknown property 'arm64-v8a' for object of type com.android.build.gradle.internal.dsl.NdkOptions.
I'm using Android Studio 3.6 rc-03, Gradle version 5.6.4, with ndk version of 21.0.6113669.
Nevermind, I forgot to add "," between 'armeabi' and 'arm64-v8a'
This is working now
ndk {
abiFilters 'armeabi', 'arm64-v8a'
}
I am attempting to build all ABIs for my project but would only like to package a subset of them into my app. For example, I would like to build "x86", "x86_64", "armeabi-v7a" and "arm64-v8a" but only package "x86" (for example).
Reading this document (https://developer.android.com/studio/projects/gradle-external-native-builds.html#jniLibs) under section "Specify ABIs", it seems very possible using the snippet they provided as an example. However, this does not seem to be working for me.
My code snippet is as follows.
android {
defaultConfig {
ndk {
abiFilters 'armeabi-v7a'
}
externalNativeBuild {
cmake {
abiFilters 'armeabi-v7a', 'x86'
}
}
}
externalNativeBuild {
cmake {
path "CMakeLists.txt"
}
}
}
In the snippet above, from my understanding of the document, it should build both armeabi-v7a and x86, but only package armeabi-v7a in my APK. This is not working though.
I am using Android plugin 3.1.0 and NDK 16.1.4479499
what you are looking for, is controlled by splits.
splits {
abi {
enable true
reset()
include 'armeabi-v7a'
universalApk false //don't generate an additional APK that contains all the ABIs
}
}
I need to have a separate CMakeLists.txt for each Android ABI. I tried to use product flavor to set the path for CMakeLists.txt. But I am getting following error on running ./gradlew assembleDebug or any other gradle command from command line.
Could not find method path() for arguments [CMakeLists.txt] on object
of type
com.android.build.gradle.internal.dsl.ExternalNativeCmakeOptions.
Here is how I have set product flavor in build.gradle.
productFlavors {
arm64_v8a {
ndk {
abiFilters "arm64-v8a"
}
externalNativeBuild {
cmake {
path "CMakeLists.txt"
}
}
}
x86_64 {
ndk {
abiFilters "x86_64"
}
externalNativeBuild {
cmake {
path "CMakeLists.txt"
}
}
}
}
NOTE - I had initially named the files as "CMakeLists_arm64-v8a.txt" and "CMakeLists_x86_64.txt". But that was failing so tried same name.
How to fix this or is there a workaround for this?
No, you cannot have CMakeLists.txt paths different for different flavors and/or ABIs, but you can use the arguments to add conditionals in your cmake script, for example like this:
flavorDimensions "abi"
productFlavors {
arm64_v8a {
dimension "abi"
ndk {
abiFilters "arm64-v8a"
}
externalNativeBuild {
cmake {
arguments "-DFLAVOR=ARM"
}
}
}
x86_64 {
dimension "abi"
ndk {
abiFilters "x86_64"
}
externalNativeBuild {
cmake {
arguments "-DFLAVOR=x86"
}
}
}
}
Now you can check this in your CMakeLists.txt:
if (FLAVOR STREQUAL 'ARM')
include(arm.cmake)
endif()
But in your case, you can rely on the argument that is defined by Android Studio, and don't need your own parameter:
if (ANDROID_ABI STREQUAL 'arm64-v8a')
include(arm.cmake)
endif()
Actually, you probably don't need separate productFlavors at all, but rather use splits to produce thin APKs for each ABI.
I'm working with AS and I don't need the x86_64 package in realm. The x86_64 package cause some problems with other libs. How to remove the package?
abiFilters will be a good solution. The method will limit the abi and only add the specified abi when building the apk.
defaultConfig {
applicationId "com.example.app"
minSdkVersion 16
targetSdkVersion 24
versionCode 1
versionName "1.0"
ndk {
abiFilters "armeabi", "armeabi-v7a", "x86"
}
// ...
}
This means only those specified arch-folders will be used and the rest can be deleted.
Well, you can remove any of the architecture folders, but keep in mind, that means the library in question (this case it's realm) will not work on those architectures that you remove.
To be frank, you can just simply remove it, but as I mentioned above, that is no good.
You can include/exclude different architectures from your build by a technique called splitting:
android {
// Rest of Gradle file
splits {
abi {
enable true
reset()
include 'armeabi', 'armeabi-v7a', 'arm64_v8a', 'mips', 'x86'
universalApk true
}
}
}
//Ensures architecture specific APKs have a higher version code
//(otherwise an x86 build would end up using the arm build, which x86 devices can run)
ext.versionCodes = [armeabi:1, 'armeabi-v7a':2, 'arm64-v8a':3, 'mips':4, x86:5]
android.applicationVariants.all { variant ->
// assign different version code for each output
variant.outputs.each { output ->
int abiVersionCode = project.ext.versionCodes.get(output.getFilter(OutputFile.ABI)) ?: 0
output.versionCodeOverride = (abiVersionCode * 10000) + android.defaultConfig.versionCode
}
}
I want use "splits" by "abi", but only for release build. Is this possible? I try use ext variable and variable by "def" also which is set to false by default. This variable is set to true in buildTypes for releaseWithLog (and release).
But I don't know how Gradle work, because when I add writeln() with test message to "debug", "releaseWithLog" and "release" and run build, all messages are in output, so this confirms me that variable "splitsEnabled" is set to true though I build for debug - and I expect value "false" for debug (and not using splits for debug therefore).
apply plugin: 'com.android.application'
android {
compileSdkVersion 19
buildToolsVersion '20.0.0'
ext {
splitsEnabled = false
}
defaultConfig {
...
}
buildTypes {
debug {
...
}
releaseWithLog {
...
splitsEnabled = true
}
release.initWith(releaseWithLog)
release {
...
}
}
...
splits {
abi {
println(splitsEnabled)
enable splitsEnabled
reset()
include 'x86', 'armeabi-v7a', 'armeabi'
exclude 'x86_64', 'mips64', 'arm64-v8a', 'mips'
universalApk true
}
}
...
You can solve this easily with a command line argument to Gradle, or the "Script parameters:" field for a Gradle task in Android Studio. I used -P to define 'dbgBld' symbol and used it for debug builds, e.g.:
gradle -PdbgBld installDebug
My build.gradle file has the following splits command:
splits {
abi {
enable !project.hasProperty('dbgBld')
reset()
include 'armeabi', 'armeabi-v7a', 'x86', 'mips'
universalApk true
}
}
Now to build release I use:
gradle assembleRelease
The 'dbgBld' symbol is not defined, so the splits enable field resolves to true and I get 5 APK files. When building for debugging, the -PdbgBld is already saved in my Android Studio configuration and I get only one "fat" APK for debugging, which results in much faster debug builds.
Greg