diff --git a/build.gradle b/build.gradle index 3882b4de..02d12e97 100644 --- a/build.gradle +++ b/build.gradle @@ -2,8 +2,10 @@ buildscript { Properties versionProperties = new Properties() versionProperties.load(new FileInputStream("$project.rootDir/version.properties")) - ext.kotlin_version = '1.3.50' - ext.agp_version = '4.0.1' + // Kotlin 1.9.22: Required for Gradle 8.5+ (old Kotlin Gradle plugin uses removed APIs) + ext.kotlin_version = '1.9.22' + // AGP 8.2.0: Required for Gradle 8.5+ compatibility + ext.agp_version = '8.2.0' ext.plugin_version = versionProperties.getProperty("version") repositories { diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 05679dc3..a5952066 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.1.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/plugin/build.gradle b/plugin/build.gradle index 2251d37e..ee80bbb7 100644 --- a/plugin/build.gradle +++ b/plugin/build.gradle @@ -2,8 +2,9 @@ import groovy.json.JsonBuilder import org.gradle.util.VersionNumber plugins { - id 'com.gradle.plugin-publish' version '0.14.0' - id "org.gradle.test-retry" version "1.2.0" + // plugin-publish 1.2.1: Required for Gradle 8.5+ (old version uses removed pluginBundle API) + id 'com.gradle.plugin-publish' version '1.2.1' + id "org.gradle.test-retry" version "1.5.8" } apply plugin: "java-gradle-plugin" @@ -12,12 +13,16 @@ apply plugin: "groovy" apply plugin: "kotlin" gradlePlugin { + // website/vcsUrl/tags moved here from pluginBundle (removed in plugin-publish 1.0+) + website = 'https://github.com/mozilla/rust-android-gradle' + vcsUrl = 'https://github.com/mozilla/rust-android-gradle.git' plugins { rustAndroidGradlePlugin { id = 'org.mozilla.rust-android-gradle.rust-android' implementationClass = 'com.nishtahir.RustAndroidPlugin' displayName = 'Plugin for building Rust with Cargo in Android projects' description = 'A plugin that helps build Rust JNI libraries with Cargo for use in Android projects.' + tags.set(['rust', 'cargo', 'android']) } } } @@ -28,14 +33,13 @@ version "$plugin_version" def isCI = (System.getenv('CI') ?: 'false').toBoolean() // Maps supported Android plugin versions to the versions of Gradle that support it +// Updated for Gradle 8.5+ compatibility (required for Gradle 9 support) def supportedVersions = [ - "7.0.0": ["7.1.1"], - "4.2.2": ["6.8.3", "7.1.1"], - "4.1.3": ["6.5.1", "6.8.3"], - "4.0.2": ["6.1.1", "6.8.3"], - "3.6.4": ["5.6.4", "6.8.3"], - "3.5.4": ["5.4.1", "5.6.4", "6.8.3"], - "3.1.2": ["4.10.2"] + "8.2.0": ["8.5"], + "8.3.0": ["8.5"], + "8.4.0": ["8.6"], + "8.5.0": ["8.7"], + "8.6.0": ["8.7"], ] // A local repo we publish our library to for testing in order to workaround limitations @@ -51,6 +55,8 @@ publishing { dependencies { implementation gradleApi() + // Guava: Required for Versions.groovy (was transitively provided by old AGP) + implementation "com.google.guava:guava:32.1.3-jre" compileOnly "com.android.tools.build:gradle:${agp_version}" testImplementation gradleTestKit() @@ -61,17 +67,17 @@ dependencies { testImplementation "org.junit.jupiter:junit-jupiter-api" } +// Java 17: Required for Gradle 8.5+ and AGP 8.x +java { + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 +} + compileKotlin { - kotlinOptions.jvmTarget = "1.8" + kotlinOptions.jvmTarget = "17" } compileTestKotlin { - kotlinOptions.jvmTarget = "1.8" -} - -pluginBundle { - website = 'https://github.com/mozilla/rust-android-gradle' - vcsUrl = 'https://github.com/mozilla/rust-android-gradle.git' - tags = ['rust', 'cargo', 'android'] + kotlinOptions.jvmTarget = "17" } @@ -152,7 +158,9 @@ static def normalizeVersion(String version) { } static def jdkVersionFor(String version) { - def jdkVersion = VersionNumber.parse(version) > VersionNumber.parse("7.0.0-alpha01") ? 11 : 8 - + // AGP 8.x requires Java 17 + def jdkVersion = VersionNumber.parse(version) >= VersionNumber.parse("8.0.0") ? 17 : + VersionNumber.parse(version) > VersionNumber.parse("7.0.0-alpha01") ? 11 : 8 + return JavaLanguageVersion.of(jdkVersion) } diff --git a/plugin/src/main/kotlin/com/nishtahir/CargoBuildTask.kt b/plugin/src/main/kotlin/com/nishtahir/CargoBuildTask.kt index 363f0ec4..4831a2e8 100644 --- a/plugin/src/main/kotlin/com/nishtahir/CargoBuildTask.kt +++ b/plugin/src/main/kotlin/com/nishtahir/CargoBuildTask.kt @@ -8,10 +8,14 @@ import org.gradle.api.Project import org.gradle.api.logging.LogLevel import org.gradle.api.tasks.Input import org.gradle.api.tasks.TaskAction +import org.gradle.process.ExecOperations import java.io.ByteArrayOutputStream import java.io.File +import javax.inject.Inject -open class CargoBuildTask : DefaultTask() { +abstract class CargoBuildTask : DefaultTask() { + @get:Inject + abstract val execOperations: ExecOperations @Input var toolchain: Toolchain? = null @@ -48,7 +52,7 @@ open class CargoBuildTask : DefaultTask() { ?: targetDirectory ?: "${module!!}/target" - val defaultTargetTriple = getDefaultTargetTriple(project, rustcCommand) + val defaultTargetTriple = getDefaultTargetTriple(execOperations, project, rustcCommand) var cargoOutputDir = File(if (toolchain.target == defaultTargetTriple) { "${target}/${profile}" @@ -84,9 +88,9 @@ open class CargoBuildTask : DefaultTask() { inline fun buildProjectForTarget(project: Project, toolchain: Toolchain, ndk: Ndk, cargoExtension: CargoExtension) { val apiLevel = cargoExtension.apiLevels[toolchain.platform]!! - val defaultTargetTriple = getDefaultTargetTriple(project, cargoExtension.rustcCommand) + val defaultTargetTriple = getDefaultTargetTriple(execOperations, project, cargoExtension.rustcCommand) - project.exec { spec -> + execOperations.exec { spec -> with(spec) { standardOutput = System.out val module = File(cargoExtension.module!!) @@ -120,6 +124,7 @@ open class CargoBuildTask : DefaultTask() { // there's a way to specify them in the cargo command line -- rustc accepts // them if passed in directly with `--cfg`, and cargo will pass them to rustc // if you use them as default featureSpec. + // Kotlin 1.9+ requires exhaustive when for sealed classes with nullable types when (features) { is Features.All -> { theCommandLine.add("--all-features") @@ -137,6 +142,7 @@ open class CargoBuildTask : DefaultTask() { theCommandLine.add(features.featureSet.joinToString(" ")) } } + null -> { /* Use default features */ } } if (cargoExtension.profile != "debug") { @@ -249,9 +255,9 @@ open class CargoBuildTask : DefaultTask() { } // This can't be private/internal as it's called from `buildProjectForTarget`. -fun getDefaultTargetTriple(project: Project, rustc: String): String? { +fun getDefaultTargetTriple(execOperations: ExecOperations, project: Project, rustc: String): String? { val stdout = ByteArrayOutputStream() - val result = project.exec { spec -> + val result = execOperations.exec { spec -> spec.standardOutput = stdout spec.commandLine = listOf(rustc, "--version", "--verbose") } diff --git a/plugin/src/main/kotlin/com/nishtahir/GenerateToolchainsTask.kt b/plugin/src/main/kotlin/com/nishtahir/GenerateToolchainsTask.kt index a8d3e7d5..0b088aa9 100644 --- a/plugin/src/main/kotlin/com/nishtahir/GenerateToolchainsTask.kt +++ b/plugin/src/main/kotlin/com/nishtahir/GenerateToolchainsTask.kt @@ -7,8 +7,12 @@ import org.gradle.api.DefaultTask import org.gradle.api.GradleException import org.gradle.api.Project import org.gradle.api.tasks.TaskAction +import org.gradle.process.ExecOperations +import javax.inject.Inject -open class GenerateToolchainsTask : DefaultTask() { +abstract class GenerateToolchainsTask : DefaultTask() { + @get:Inject + abstract val execOperations: ExecOperations @TaskAction @Suppress("unused") @@ -44,7 +48,7 @@ open class GenerateToolchainsTask : DefaultTask() { // already. It is fast to do so and fixes any issues // with partially reclaimed temporary files. val dir = File(cargoExtension.toolchainDirectory, arch + "-" + apiLevel) - project.exec { spec -> + execOperations.exec { spec -> spec.standardOutput = System.out spec.errorOutput = System.out spec.commandLine(cargoExtension.pythonCommand) diff --git a/plugin/src/main/kotlin/com/nishtahir/RustAndroidPlugin.kt b/plugin/src/main/kotlin/com/nishtahir/RustAndroidPlugin.kt index 51662749..23273543 100644 --- a/plugin/src/main/kotlin/com/nishtahir/RustAndroidPlugin.kt +++ b/plugin/src/main/kotlin/com/nishtahir/RustAndroidPlugin.kt @@ -276,7 +276,9 @@ open class RustAndroidPlugin : Plugin { eachFile { it.path = it.path.replaceFirst("com/nishtahir", "") } - fileMode = 493 // 0755 in decimal; Kotlin doesn't have octal literals (!). + filePermissions { permissions -> + permissions.unix("rwxr-xr-x") // 0755 + } includeEmptyDirs = false duplicatesStrategy = DuplicatesStrategy.EXCLUDE }