diff --git a/.kotlin/sessions/kotlin-compiler-11924966291209495373.salive b/.kotlin/sessions/kotlin-compiler-11924966291209495373.salive new file mode 100644 index 0000000000..e69de29bb2 diff --git a/gradle-plugin/src/main/kotlin/com/google/devtools/ksp/gradle/AndroidPluginIntegration.kt b/gradle-plugin/src/main/kotlin/com/google/devtools/ksp/gradle/AndroidPluginIntegration.kt index 8c7a006c53..9647ce6eaa 100644 --- a/gradle-plugin/src/main/kotlin/com/google/devtools/ksp/gradle/AndroidPluginIntegration.kt +++ b/gradle-plugin/src/main/kotlin/com/google/devtools/ksp/gradle/AndroidPluginIntegration.kt @@ -53,7 +53,7 @@ object AndroidPluginIntegration { private fun decorateAndroidExtension(project: Project, onSourceSet: (String) -> Unit) { val sourceSets = when (val androidExt = project.extensions.getByName("android")) { is BaseExtension -> androidExt.sourceSets - is CommonExtension<*, *, *, *> -> androidExt.sourceSets + is CommonExtension<*, *, *, *, *, *> -> androidExt.sourceSets else -> throw RuntimeException("Unsupported Android Gradle plugin version.") } sourceSets.all { diff --git a/gradle-plugin/src/main/kotlin/com/google/devtools/ksp/gradle/KspConfigurations.kt b/gradle-plugin/src/main/kotlin/com/google/devtools/ksp/gradle/KspConfigurations.kt index 2d437af511..411c136ffb 100644 --- a/gradle-plugin/src/main/kotlin/com/google/devtools/ksp/gradle/KspConfigurations.kt +++ b/gradle-plugin/src/main/kotlin/com/google/devtools/ksp/gradle/KspConfigurations.kt @@ -35,11 +35,13 @@ class KspConfigurations(private val project: Project) { }.replaceFirstChar { it.lowercase() } } + /** + * Returns a new or existing [Configuration] with the given [name], with applied properties. + */ private fun createConfiguration( name: String, readableSetName: String, ): Configuration { - // maybeCreate to be future-proof, but we should never have a duplicate with current logic return project.configurations.maybeCreate(name).apply { description = "KSP dependencies for the '$readableSetName' source set." isCanBeResolved = false // we'll resolve the processor classpath config @@ -48,14 +50,19 @@ class KspConfigurations(private val project: Project) { } } - private fun getAndroidConfigurationName(target: KotlinTarget, sourceSet: String): String { + /** + * Returns the Android sourceSet-specific KSP configuration name given a [kotlinTarget] and [sourceSet]. + * + * For single-platform, [kotlinTarget] can be null. + */ + private fun getAndroidConfigurationName(kotlinTarget: KotlinTarget?, sourceSet: String): String { val isMain = sourceSet.endsWith("main", ignoreCase = true) val nameWithoutMain = when { isMain -> sourceSet.substring(0, sourceSet.length - 4) else -> sourceSet } // Note: on single-platform, target name is conveniently set to "". - return configurationNameOf(PREFIX, target.name, nameWithoutMain) + return configurationNameOf(PREFIX, kotlinTarget?.name ?: "", nameWithoutMain) } private fun getKotlinConfigurationName(compilation: KotlinCompilation<*>, sourceSet: KotlinSourceSet): String { @@ -86,6 +93,13 @@ class KspConfigurations(private val project: Project) { // 1.6.0: decorateKotlinProject(project.kotlinExtension)? decorateKotlinProject(project.extensions.getByName("kotlin") as KotlinProjectExtension, project) } + // Create sourceSet-specific KSP configurations for the case when the KotlinBaseApiPlugin is applied instead + // of the KotlinBasePluginWrapper (e.g., when AGP's built-in Kotlin support is enabled). + project.plugins.withType(KotlinBaseApiPlugin::class.java) { + // FIXME: After KT-70897 is fixed and AGP's built-in Kotlin support adds a `kotlin` extension, call + // decorateKotlinProject here instead. + createAndroidSourceSetConfigurations(project, kotlinTarget = null) + } } private fun decorateKotlinProject(kotlin: KotlinProjectExtension, project: Project) { @@ -125,12 +139,7 @@ class KspConfigurations(private val project: Project) { */ private fun decorateKotlinTarget(target: KotlinTarget) { if (target.platformType == KotlinPlatformType.androidJvm) { - AndroidPluginIntegration.forEachAndroidSourceSet(target.project) { sourceSet -> - createConfiguration( - name = getAndroidConfigurationName(target, sourceSet), - readableSetName = "$sourceSet (Android)" - ) - } + createAndroidSourceSetConfigurations(target.project, target) } else { target.compilations.configureEach { compilation -> compilation.kotlinSourceSetsObservable.forAll { sourceSet -> @@ -177,4 +186,19 @@ class KspConfigurations(private val project: Project) { compilation.target.project.configurations.findByName(it) }.toSet() } + + /** + * Creates the Android sourceSet-specific KSP configurations for the given [project] and [kotlinTarget] + * + * For single-platform, [kotlinTarget] can be null. + */ + private fun createAndroidSourceSetConfigurations(project: Project, kotlinTarget: KotlinTarget?) { + AndroidPluginIntegration.forEachAndroidSourceSet(project) { sourceSet -> + createConfiguration( + name = getAndroidConfigurationName(kotlinTarget, sourceSet), + readableSetName = "$sourceSet (Android)" + ) + } + } + } diff --git a/gradle-plugin/src/test/kotlin/com/google/devtools/ksp/gradle/GradleCompilationTest.kt b/gradle-plugin/src/test/kotlin/com/google/devtools/ksp/gradle/GradleCompilationTest.kt index acb7f411ce..63d63b9e0b 100644 --- a/gradle-plugin/src/test/kotlin/com/google/devtools/ksp/gradle/GradleCompilationTest.kt +++ b/gradle-plugin/src/test/kotlin/com/google/devtools/ksp/gradle/GradleCompilationTest.kt @@ -399,4 +399,19 @@ class GradleCompilationTest { testRule.runner().withArguments().build() } + + /** + * Regression test for b/362279380 + */ + @Test + fun androidGradlePluginBuiltInKotlin() { + testRule.setupAppAsAndroidApp(enableAgpBuiltInKotlinSupport = true) + testRule.appModule.dependencies.addAll( + listOf( + artifact(configuration = "ksp", "androidx.room:room-compiler:2.4.2"), + artifact(configuration = "kspTest", "androidx.room:room-compiler:2.4.2") + ) + ) + testRule.runner().withArguments(":app:assembleDebug").build() + } } diff --git a/gradle-plugin/src/test/kotlin/com/google/devtools/ksp/gradle/testing/KspIntegrationTestRule.kt b/gradle-plugin/src/test/kotlin/com/google/devtools/ksp/gradle/testing/KspIntegrationTestRule.kt index 2407eade0d..f4fff4c835 100644 --- a/gradle-plugin/src/test/kotlin/com/google/devtools/ksp/gradle/testing/KspIntegrationTestRule.kt +++ b/gradle-plugin/src/test/kotlin/com/google/devtools/ksp/gradle/testing/KspIntegrationTestRule.kt @@ -92,16 +92,23 @@ class KspIntegrationTestRule( /** * Sets up the app module as an android app, adding necessary plugin dependencies, a manifest - * file and necessary gradle configuration. + * file and necessary gradle configuration. If [enableAgpBuiltInKotlinSupport] is true, enable AGP's built-in Kotlin + * support instead of applying the Kotlin Android Gradle plugin. */ - fun setupAppAsAndroidApp() { + fun setupAppAsAndroidApp(enableAgpBuiltInKotlinSupport: Boolean = false) { testProject.appModule.plugins.addAll( listOf( PluginDeclaration.id("com.android.application", testConfig.androidBaseVersion), - PluginDeclaration.kotlin("android", testConfig.kotlinBaseVersion), PluginDeclaration.id("com.google.devtools.ksp", testConfig.kspVersion) ) ) + if (enableAgpBuiltInKotlinSupport) { + testProject.appModule + .plugins + .add(PluginDeclaration.id("com.android.experimental.built-in-kotlin", testConfig.androidBaseVersion)) + } else { + testProject.appModule.plugins.add(PluginDeclaration.kotlin("android", testConfig.kotlinBaseVersion)) + } addAndroidBoilerplate() } @@ -126,11 +133,15 @@ class KspIntegrationTestRule( """ android { namespace = "com.example.kspandroidtestapp" - compileSdkVersion(31) + compileSdk = 31 defaultConfig { - minSdkVersion(24) + minSdk = 24 } } + + dependencies { + implementation("org.jetbrains.kotlin:kotlin-stdlib:${testConfig.kotlinBaseVersion}") + } """.trimIndent() ) testProject.appModule.moduleRoot.resolve("src/main/AndroidManifest.xml") diff --git a/gradle.properties b/gradle.properties index d9c787f097..5708037571 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,7 +2,7 @@ org.gradle.jvmargs=-Duser.country=US -Dkotlin.daemon.jvm.options=-Xmx4096m -Dfile.encoding=UTF-8 kotlinBaseVersion=2.1.0-dev-5441 -agpBaseVersion=8.0.2 +agpBaseVersion=8.7.0 intellijVersion=233.13135.103 junitVersion=4.13.1 junit5Version=5.8.2 diff --git a/integration-tests/src/test/resources/android-view-binding/app/build.gradle.kts b/integration-tests/src/test/resources/android-view-binding/app/build.gradle.kts index 51b0630bd5..c3c6cd4f35 100644 --- a/integration-tests/src/test/resources/android-view-binding/app/build.gradle.kts +++ b/integration-tests/src/test/resources/android-view-binding/app/build.gradle.kts @@ -12,7 +12,7 @@ dependencies { android { namespace = "com.example.kspandroidtestapp" defaultConfig { - minSdkVersion(24) + minSdk = 24 } compileSdk = 34 buildFeatures { diff --git a/integration-tests/src/test/resources/playground-android-multi/application/build.gradle.kts b/integration-tests/src/test/resources/playground-android-multi/application/build.gradle.kts index 0616367a80..3db13abd95 100644 --- a/integration-tests/src/test/resources/playground-android-multi/application/build.gradle.kts +++ b/integration-tests/src/test/resources/playground-android-multi/application/build.gradle.kts @@ -20,11 +20,11 @@ dependencies { android { namespace = "com.example.myapplication" - compileSdkVersion(34) + compileSdk = 34 defaultConfig { applicationId = "org.gradle.kotlin.dsl.samples.androidstudio" - minSdkVersion(34) - targetSdkVersion(34) + minSdk = 34 + targetSdk = 34 versionCode = 1 versionName = "1.0" } diff --git a/integration-tests/src/test/resources/playground-android-multi/workload/build.gradle.kts b/integration-tests/src/test/resources/playground-android-multi/workload/build.gradle.kts index c57146de1a..f4d41f7198 100644 --- a/integration-tests/src/test/resources/playground-android-multi/workload/build.gradle.kts +++ b/integration-tests/src/test/resources/playground-android-multi/workload/build.gradle.kts @@ -23,10 +23,9 @@ dependencies { android { namespace = "com.example.mylibrary" - compileSdkVersion(34) + compileSdk = 34 defaultConfig { - minSdkVersion(34) - targetSdkVersion(34) + minSdk = 34 } } diff --git a/integration-tests/src/test/resources/playground-android/workload/build.gradle.kts b/integration-tests/src/test/resources/playground-android/workload/build.gradle.kts index 076e0f5816..f6874ac1e3 100644 --- a/integration-tests/src/test/resources/playground-android/workload/build.gradle.kts +++ b/integration-tests/src/test/resources/playground-android/workload/build.gradle.kts @@ -23,11 +23,11 @@ dependencies { android { namespace = "com.example.myapplication" - compileSdkVersion(34) + compileSdk = 34 defaultConfig { applicationId = "org.gradle.kotlin.dsl.samples.androidstudio" - minSdkVersion(34) - targetSdkVersion(34) + minSdk = 34 + targetSdk = 34 versionCode = 1 versionName = "1.0" }