From 5a9307d11c1643221bc2a280feb00024f8fa6030 Mon Sep 17 00:00:00 2001 From: Amr Bashir Date: Fri, 12 May 2023 14:06:50 +0300 Subject: [PATCH] feat(cli): update android template to gradle 8.0 (#6890) * feat(cli): update android template to gradle 8.0 * update java in CI to 17 * updat to latest tauri-mobile --- .changes/gradle-8.md | 6 ++ .github/workflows/test-android.yml | 2 +- tooling/cli/Cargo.lock | 4 +- tooling/cli/Cargo.toml | 2 +- tooling/cli/src/mobile/android/project.rs | 13 +++- .../mobile/android/app/build.gradle.kts | 70 ++++------------- .../android/app/src/main/AndroidManifest.xml | 1 - .../templates/mobile/android/build.gradle.kts | 7 +- .../mobile/android/buildSrc/build.gradle.kts | 6 +- .../buildSrc/src/main/kotlin/BuildTask.kt | 12 +-- .../buildSrc/src/main/kotlin/RustPlugin.kt | 76 +++++++++++++------ .../mobile/android/gradle.properties | 4 +- .../gradle/wrapper/gradle-wrapper.properties | 2 +- 13 files changed, 98 insertions(+), 107 deletions(-) create mode 100644 .changes/gradle-8.md diff --git a/.changes/gradle-8.md b/.changes/gradle-8.md new file mode 100644 index 000000000..b97aa28f5 --- /dev/null +++ b/.changes/gradle-8.md @@ -0,0 +1,6 @@ +--- +'cli.rs': 'patch' +'cli.js': 'patch' +--- + +Update android template to gradle 8.0 diff --git a/.github/workflows/test-android.yml b/.github/workflows/test-android.yml index fb2dccc68..ea54d2617 100644 --- a/.github/workflows/test-android.yml +++ b/.github/workflows/test-android.yml @@ -57,7 +57,7 @@ jobs: - uses: actions/setup-java@v3 with: distribution: temurin - java-version: 11 + java-version: 17 cache: gradle - name: Setup NDK diff --git a/tooling/cli/Cargo.lock b/tooling/cli/Cargo.lock index f9e912333..8f8ecdf3b 100644 --- a/tooling/cli/Cargo.lock +++ b/tooling/cli/Cargo.lock @@ -3938,9 +3938,9 @@ dependencies = [ [[package]] name = "tauri-mobile" -version = "0.4.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9734a0128db0a9729b5264dd0be546527c21555e7f05844226786d027b1b6aaa" +checksum = "596fa2cd0538f040eeb1485f74eb40052625dafd55cef4b3139e200763f6a988" dependencies = [ "cocoa", "colored 1.9.3", diff --git a/tooling/cli/Cargo.toml b/tooling/cli/Cargo.toml index 130b4a679..aab2831c5 100644 --- a/tooling/cli/Cargo.toml +++ b/tooling/cli/Cargo.toml @@ -39,7 +39,7 @@ name = "cargo-tauri" path = "src/main.rs" [dependencies] -tauri-mobile = { version = "0.4", default-features = false } +tauri-mobile = { version = "0.5", default-features = false } textwrap = { version = "0.11.0", features = [ "term_size" ] } jsonrpsee = { version = "0.16", features = [ "server" ] } jsonrpsee-core = "0.16" diff --git a/tooling/cli/src/mobile/android/project.rs b/tooling/cli/src/mobile/android/project.rs index c4bcbb546..62950088f 100644 --- a/tooling/cli/src/mobile/android/project.rs +++ b/tooling/cli/src/mobile/android/project.rs @@ -52,10 +52,16 @@ pub fn gen( )), ); map.insert("root-dir", config.app().root_dir()); - map.insert("targets", Target::all().values().collect::>()); - map.insert("target-names", Target::all().keys().collect::>()); map.insert( - "arches", + "abi-list", + Target::all() + .values() + .map(|target| target.abi) + .collect::>(), + ); + map.insert("target-list", Target::all().keys().collect::>()); + map.insert( + "arch-list", Target::all() .values() .map(|target| target.arch) @@ -77,6 +83,7 @@ pub fn gen( || metadata.app_dependencies().is_some() || metadata.app_dependencies_platform().is_some(), ); + map.insert("has-asset-packs", !asset_packs.is_empty()); map.insert( "asset-packs", asset_packs diff --git a/tooling/cli/templates/mobile/android/app/build.gradle.kts b/tooling/cli/templates/mobile/android/app/build.gradle.kts index f11d9430e..06870f32d 100644 --- a/tooling/cli/templates/mobile/android/app/build.gradle.kts +++ b/tooling/cli/templates/mobile/android/app/build.gradle.kts @@ -1,13 +1,14 @@ plugins { id("com.android.application") id("org.jetbrains.kotlin.android") - id("rustPlugin") + id("rust") {{~#each android-app-plugins}} id("{{this}}"){{/each}} } android { compileSdk = 33 + namespace = "{{reverse-domain app.domain}}.{{snake-case app.name}}" defaultConfig { manifestPlaceholders["usesCleartextTraffic"] = "false" applicationId = "{{reverse-domain app.domain}}.{{snake-case app.name}}" @@ -16,62 +17,34 @@ android { versionCode = 1 versionName = "1.0" } - sourceSets.getByName("main") { - {{#if android.vulkan-validation}}// Vulkan validation layers - val ndkHome = System.getenv("NDK_HOME") - jniLibs.srcDir("${ndkHome}/sources/third_party/vulkan/src/build-android/jniLibs") - {{/if}} - } buildTypes { getByName("debug") { manifestPlaceholders["usesCleartextTraffic"] = "true" isDebuggable = true isJniDebuggable = true isMinifyEnabled = false - packagingOptions { - {{~#each targets}} - jniLibs.keepDebugSymbols.add("*/{{this.abi}}/*.so") + packaging { + {{~#each abi-list}} + jniLibs.keepDebugSymbols.add("*/{{this}}/*.so") {{/each}} } } getByName("release") { isMinifyEnabled = true - val proguards = fileTree(".") { - include("**/*.pro") - } - proguardFiles(*proguards.toList().toTypedArray()) + proguardFiles( + *fileTree(".") { include("**/*.pro") } + .plus(getDefaultProguardFile("proguard-android-optimize.txt")) + .toList().toTypedArray() + ) } } - flavorDimensions.add("abi") - productFlavors { - create("universal") { - dimension = "abi" - ndk { - abiFilters += (findProperty("abiList") as? String)?.split(",") ?: listOf( - {{~#each targets}} - "{{this.abi}}",{{/each}} - ) - } - } - {{~#each targets}} - - create("{{this.arch}}") { - dimension = "abi" - ndk { - abiFilters += listOf("{{this.abi}}") - } - } - {{/each}} + kotlinOptions { + jvmTarget = "1.8" } - - assetPacks += mutableSetOf({{quote-and-join-colon-prefix asset-packs}}) - namespace = "{{reverse-domain app.domain}}.{{snake-case app.name}}" } rust { rootDirRel = "{{root-dir-rel}}" - targets = (findProperty("targetList") as? String)?.split(",") ?: listOf({{quote-and-join target-names}}) - arches = (findProperty("archList") as? String)?.split(",") ?: listOf({{quote-and-join arches}}) } dependencies { @@ -79,25 +52,12 @@ dependencies { implementation(platform("{{this}}")){{/each}} {{~#each android-app-dependencies}} implementation("{{this}}"){{/each}} - implementation("androidx.webkit:webkit:1.5.0") - implementation("androidx.appcompat:appcompat:1.5.1") - implementation("com.google.android.material:material:1.7.0") + 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") - -afterEvaluate { - android.applicationVariants.all { - tasks["mergeUniversalReleaseJniLibFolders"].dependsOn(tasks["rustBuildRelease"]) - tasks["mergeUniversalDebugJniLibFolders"].dependsOn(tasks["rustBuildDebug"]) - if (findProperty("targetList") == null) { - productFlavors.filter{ it.name != "universal" }.forEach { _ -> - val archAndBuildType = name.capitalize() - tasks["merge${archAndBuildType}JniLibFolders"].dependsOn(tasks["rustBuild${archAndBuildType}"]) - } - } - } -} diff --git a/tooling/cli/templates/mobile/android/app/src/main/AndroidManifest.xml b/tooling/cli/templates/mobile/android/app/src/main/AndroidManifest.xml index d8f1eb733..e681f2493 100644 --- a/tooling/cli/templates/mobile/android/app/src/main/AndroidManifest.xml +++ b/tooling/cli/templates/mobile/android/app/src/main/AndroidManifest.xml @@ -14,7 +14,6 @@ android:exported="true"> - diff --git a/tooling/cli/templates/mobile/android/build.gradle.kts b/tooling/cli/templates/mobile/android/build.gradle.kts index f7e5be878..ef0b4ee43 100644 --- a/tooling/cli/templates/mobile/android/build.gradle.kts +++ b/tooling/cli/templates/mobile/android/build.gradle.kts @@ -1,16 +1,13 @@ -// Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { repositories { google() mavenCentral() } dependencies { - classpath("com.android.tools.build:gradle:7.3.1") - classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.10") + classpath("com.android.tools.build:gradle:8.0.0") + classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.21") {{~#each android-project-dependencies}} classpath("{{this}}"){{/each}} - // NOTE: Do not place your application dependencies here; they belong - // in the individual module build.gradle files } } diff --git a/tooling/cli/templates/mobile/android/buildSrc/build.gradle.kts b/tooling/cli/templates/mobile/android/buildSrc/build.gradle.kts index 2670d5bb9..099feff75 100644 --- a/tooling/cli/templates/mobile/android/buildSrc/build.gradle.kts +++ b/tooling/cli/templates/mobile/android/buildSrc/build.gradle.kts @@ -5,8 +5,8 @@ plugins { gradlePlugin { plugins { create("pluginsForCoolKids") { - id = "rustPlugin" - implementationClass = "{{reverse-domain app.domain}}.RustPlugin" + id = "rust" + implementationClass = "RustPlugin" } } } @@ -18,6 +18,6 @@ repositories { dependencies { compileOnly(gradleApi()) - implementation("com.android.tools.build:gradle:7.3.1") + implementation("com.android.tools.build:gradle:8.0.0") } diff --git a/tooling/cli/templates/mobile/android/buildSrc/src/main/kotlin/BuildTask.kt b/tooling/cli/templates/mobile/android/buildSrc/src/main/kotlin/BuildTask.kt index 4dec3742c..8a0f065b7 100644 --- a/tooling/cli/templates/mobile/android/buildSrc/src/main/kotlin/BuildTask.kt +++ b/tooling/cli/templates/mobile/android/buildSrc/src/main/kotlin/BuildTask.kt @@ -1,20 +1,14 @@ -package {{reverse-domain app.domain}} - import java.io.File import org.apache.tools.ant.taskdefs.condition.Os import org.gradle.api.DefaultTask import org.gradle.api.GradleException import org.gradle.api.logging.LogLevel import org.gradle.api.tasks.Input -import org.gradle.api.tasks.InputDirectory -import org.gradle.api.tasks.PathSensitive -import org.gradle.api.tasks.PathSensitivity import org.gradle.api.tasks.TaskAction open class BuildTask : DefaultTask() { - @InputDirectory - @PathSensitive(PathSensitivity.RELATIVE) - var rootDirRel: File? = null + @Input + var rootDirRel: String? = null @Input var target: String? = null @Input @@ -41,7 +35,7 @@ open class BuildTask : DefaultTask() { val args = listOf({{quote-and-join tauri-binary-args}}); project.exec { - workingDir(File(project.projectDir, rootDirRel.path)) + workingDir(File(project.projectDir, rootDirRel)) executable(executable) args(args) if (project.logger.isEnabled(LogLevel.DEBUG)) { diff --git a/tooling/cli/templates/mobile/android/buildSrc/src/main/kotlin/RustPlugin.kt b/tooling/cli/templates/mobile/android/buildSrc/src/main/kotlin/RustPlugin.kt index 7028af56d..7186f9f7c 100644 --- a/tooling/cli/templates/mobile/android/buildSrc/src/main/kotlin/RustPlugin.kt +++ b/tooling/cli/templates/mobile/android/buildSrc/src/main/kotlin/RustPlugin.kt @@ -1,59 +1,85 @@ -package {{reverse-domain app.domain}} - +import com.android.build.api.dsl.ApplicationExtension import org.gradle.api.DefaultTask -import org.gradle.api.GradleException import org.gradle.api.Plugin import org.gradle.api.Project -import java.io.File -import java.util.* +import org.gradle.kotlin.dsl.configure +import org.gradle.kotlin.dsl.get const val TASK_GROUP = "rust" open class Config { - var rootDirRel: String? = null - var targets: List? = null - var arches: List? = null + lateinit var rootDirRel: String } open class RustPlugin : Plugin { private lateinit var config: Config - override fun apply(project: Project) { - config = project.extensions.create("rust", Config::class.java) - project.afterEvaluate { - if (config.targets == null) { - throw GradleException("targets cannot be null") - } - if (config.arches == null) { - throw GradleException("arches cannot be null") + override fun apply(project: Project) = with(project) { + config = extensions.create("rust", Config::class.java) + + val defaultAbiList = listOf({{quote-and-join abi-list}}); + val abiList = (findProperty("abiList") as? String)?.split(',') ?: defaultAbiList + + val defaultArchList = listOf({{quote-and-join arch-list}}); + val archList = (findProperty("archList") as? String)?.split(',') ?: listOf({{quote-and-join arch-list}}) + + val targetsList = (findProperty("targetList") as? String)?.split(',') ?: listOf({{quote-and-join target-list}}) + + extensions.configure { + @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.capitalize(Locale.ROOT) - val buildTask = project.tasks.maybeCreate( - "rustBuild$profileCapitalized", + 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" } - for (targetPair in config.targets!!.withIndex()) { + + tasks["mergeUniversal${profileCapitalized}JniLibFolders"].dependsOn(buildTask) + + for (targetPair in targetsList.withIndex()) { val targetName = targetPair.value - val targetArch = config.arches!![targetPair.index] - val targetArchCapitalized = targetArch.capitalize(Locale.ROOT) + 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?.let { File(it) } + rootDirRel = config.rootDirRel target = targetName release = profile == "release" } + buildTask.dependsOn(targetBuildTask) - project.tasks.findByName("preBuild")?.mustRunAfter(targetBuildTask) + tasks["merge$targetArchCapitalized${profileCapitalized}JniLibFolders"].dependsOn( + targetBuildTask + ) } } } } -} +} \ No newline at end of file diff --git a/tooling/cli/templates/mobile/android/gradle.properties b/tooling/cli/templates/mobile/android/gradle.properties index cd0519bb2..022338b78 100644 --- a/tooling/cli/templates/mobile/android/gradle.properties +++ b/tooling/cli/templates/mobile/android/gradle.properties @@ -20,4 +20,6 @@ kotlin.code.style=official # Enables namespacing of each library's R class so that its R class includes only the # resources declared in the library itself and none from the library's dependencies, # thereby reducing the size of the R class for that library -android.nonTransitiveRClass=true \ No newline at end of file +android.nonTransitiveRClass=true +android.defaults.buildfeatures.buildconfig=true +android.nonFinalResIds=false \ No newline at end of file diff --git a/tooling/cli/templates/mobile/android/gradle/wrapper/gradle-wrapper.properties b/tooling/cli/templates/mobile/android/gradle/wrapper/gradle-wrapper.properties index de8c362b6..40a435065 100644 --- a/tooling/cli/templates/mobile/android/gradle/wrapper/gradle-wrapper.properties +++ b/tooling/cli/templates/mobile/android/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ #Tue May 10 19:22:52 CST 2022 distributionBase=GRADLE_USER_HOME -distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.0-bin.zip distributionPath=wrapper/dists zipStorePath=wrapper/dists zipStoreBase=GRADLE_USER_HOME