Skip to content

Instantly share code, notes, and snippets.

@MasFana
Created November 15, 2024 04:18
Show Gist options
  • Save MasFana/a37cb632f063800866d46c7a5a25818e to your computer and use it in GitHub Desktop.
Save MasFana/a37cb632f063800866d46c7a5a25818e to your computer and use it in GitHub Desktop.
Splitting APK into Multiple abi Using Tauri and Gradle Kotlin DSL to Optimize File Size

On Main Path

src-tauri/gen/android/keystore.properties

Create the file with these content

keyAlias=upload
password=yourpass
storeFile=/TAURI/upload-keystore.jks
// src-tauri/gen/android/build.gradle.kts
import java.util.Properties
import java.io.FileInputStream
plugins {
id("com.android.application")
id("org.jetbrains.kotlin.android")
id("rust")
}
val tauriProperties = Properties().apply {
val propFile = file("tauri.properties")
if (propFile.exists()) {
propFile.inputStream().use { load(it) }
}
}
android {
compileSdk = 34
namespace = "com.firstapp.app"
defaultConfig {
manifestPlaceholders["usesCleartextTraffic"] = "true"
applicationId = "com.firstapp.app"
minSdk = 24
targetSdk = 34
versionCode = tauriProperties.getProperty("tauri.android.versionCode", "1").toInt()
versionName = tauriProperties.getProperty("tauri.android.versionName", "1.0")
ndk{
abiFilters.clear() // Clears all ABI filters
}
}
signingConfigs {
create("release") {
val keystorePropertiesFile = rootProject.file("keystore.properties")
val keystoreProperties = Properties()
if (keystorePropertiesFile.exists()) {
keystoreProperties.load(FileInputStream(keystorePropertiesFile))
}
keyAlias = keystoreProperties["keyAlias"] as String
keyPassword = keystoreProperties["password"] as String
storeFile = file(keystoreProperties["storeFile"])
storePassword = keystoreProperties["password"] as String
}
}
buildTypes {
getByName("debug") {
manifestPlaceholders["usesCleartextTraffic"] = "true"
isDebuggable = true
isJniDebuggable = true
isMinifyEnabled = false
packaging { jniLibs.keepDebugSymbols.add("*/arm64-v8a/*.so")
jniLibs.keepDebugSymbols.add("*/armeabi-v7a/*.so")
jniLibs.keepDebugSymbols.add("*/x86/*.so")
jniLibs.keepDebugSymbols.add("*/x86_64/*.so")
}
}
getByName("release") {
isMinifyEnabled = true
isShrinkResources = true
isDebuggable = false
signingConfig = signingConfigs.getByName("release")
proguardFiles(
*fileTree(".") { include("**/*.pro") }
.plus(getDefaultProguardFile("proguard-android-optimize.txt"))
.toList().toTypedArray()
)
}
}
splits {
abi {
isEnable = true // Enables ABI splits
reset() // Clears previous configuration
include("armeabi-v7a", "arm64-v8a", "x86", "x86_64") // Specifies ABIs that Gradle should create APKs for
isUniversalApk = false // Prevents generation of a universal APK
}
}
kotlinOptions {
jvmTarget = "1.8"
}
buildFeatures {
buildConfig = true
}
}
rust {
rootDirRel = "../../../"
}
dependencies {
implementation("androidx.webkit:webkit:1.6.1")
implementation("androidx.appcompat:appcompat:1.6.1")
implementation("com.google.android.material:material:1.8.0")
testImplementation("junit:junit:4.13.2")
androidTestImplementation("androidx.test.ext:junit:1.1.4")
androidTestImplementation("androidx.test.espresso:espresso-core:3.5.0")
}
apply(from = "tauri.build.gradle.kts")
// src-tauri/gen/android/buildSrc/src/main/java/com/firstapp/app/kotlin/RustPlugin.kt
// We need to Comment Out the Default ndk in this file
import com.android.build.api.dsl.ApplicationExtension
import org.gradle.api.DefaultTask
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.kotlin.dsl.configure
import org.gradle.kotlin.dsl.get
const val TASK_GROUP = "rust"
open class Config {
lateinit var rootDirRel: String
}
open class RustPlugin : Plugin<Project> {
private lateinit var config: Config
override fun apply(project: Project) = with(project) {
config = extensions.create("rust", Config::class.java)
val defaultAbiList = listOf("arm64-v8a", "armeabi-v7a", "x86", "x86_64");
val abiList = (findProperty("abiList") as? String)?.split(',') ?: defaultAbiList
val defaultArchList = listOf("arm64", "arm", "x86", "x86_64");
val archList = (findProperty("archList") as? String)?.split(',') ?: defaultArchList
val targetsList = (findProperty("targetList") as? String)?.split(',') ?: listOf("aarch64", "armv7", "i686", "x86_64")
extensions.configure<ApplicationExtension> {
@Suppress("UnstableApiUsage")
flavorDimensions.add("abi")
productFlavors {
create("universal") {
dimension = "abi"
ndk {
// abiFilters += abiList
}
}
defaultArchList.forEachIndexed { index, arch ->
create(arch) {
dimension = "abi"
ndk {
// abiFilters.add(defaultAbiList[index])
}
}
}
}
}
afterEvaluate {
for (profile in listOf("debug", "release")) {
val profileCapitalized = profile.replaceFirstChar { it.uppercase() }
val buildTask = tasks.maybeCreate(
"rustBuildUniversal$profileCapitalized",
DefaultTask::class.java
).apply {
group = TASK_GROUP
description = "Build dynamic library in $profile mode for all targets"
}
tasks["mergeUniversal${profileCapitalized}JniLibFolders"].dependsOn(buildTask)
for (targetPair in targetsList.withIndex()) {
val targetName = targetPair.value
val targetArch = archList[targetPair.index]
val targetArchCapitalized = targetArch.replaceFirstChar { it.uppercase() }
val targetBuildTask = project.tasks.maybeCreate(
"rustBuild$targetArchCapitalized$profileCapitalized",
BuildTask::class.java
).apply {
group = TASK_GROUP
description = "Build dynamic library in $profile mode for $targetArch"
rootDirRel = config.rootDirRel
target = targetName
release = profile == "release"
}
buildTask.dependsOn(targetBuildTask)
tasks["merge$targetArchCapitalized${profileCapitalized}JniLibFolders"].dependsOn(
targetBuildTask
)
}
}
}
}
}
@MasFana
Copy link
Author

MasFana commented Nov 15, 2024

These is Used To Fix ndk File Conflic

when setting the split file on the build.gradle.kts

FAILURE: Build failed with an exception.

* What went wrong:
A problem occurred configuring project ':app'.
> Failed to notify project evaluation listener.
   > Conflicting configuration : 'armeabi-v7a,x86_64,arm64-v8a,x86' in ndk abiFilters cannot be present when splits abi filters are set : armeabi-v7a,x86_64,x86,arm64-v8a
   > Task with name 'mergeUniversalDebugJniLibFolders' not found in project ':app'.

* Try:
> Run with --stacktrace option to get the stack trace.
> Run with --info or --debug option to get more log output.
> Run with --scan to get full insights.
> Get more help at https://help.gradle.org.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment