Эх сурвалжийг харах

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
Amr Bashir 2 жил өмнө
parent
commit
5a9307d11c

+ 6 - 0
.changes/gradle-8.md

@@ -0,0 +1,6 @@
+---
+'cli.rs': 'patch'
+'cli.js': 'patch'
+---
+
+Update android template to gradle 8.0

+ 1 - 1
.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

+ 2 - 2
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",

+ 1 - 1
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"

+ 10 - 3
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::<Vec<_>>());
-  map.insert("target-names", Target::all().keys().collect::<Vec<_>>());
   map.insert(
-    "arches",
+    "abi-list",
+    Target::all()
+      .values()
+      .map(|target| target.abi)
+      .collect::<Vec<_>>(),
+  );
+  map.insert("target-list", Target::all().keys().collect::<Vec<_>>());
+  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

+ 15 - 55
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}"])
-            }
-        }
-    }
-}

+ 0 - 1
tooling/cli/templates/mobile/android/app/src/main/AndroidManifest.xml

@@ -14,7 +14,6 @@
             android:exported="true">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
-
                 <category android:name="android.intent.category.LAUNCHER" />
             </intent-filter>
         </activity>

+ 2 - 5
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
     }
 }
 

+ 3 - 3
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")
 }
 

+ 3 - 9
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)) {

+ 51 - 25
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<String>? = null
-    var arches: List<String>? = null
+    lateinit var rootDirRel: String
 }
 
 open class RustPlugin : Plugin<Project> {
     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<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.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
+                    )
                 }
             }
         }
     }
-}
+}

+ 3 - 1
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
+android.nonTransitiveRClass=true
+android.defaults.buildfeatures.buildconfig=true
+android.nonFinalResIds=false

+ 1 - 1
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