plugins { id("org.jetbrains.kotlin.plugin.compose") version "2.3.0" apply false } allprojects { repositories { google() mavenCentral() } } val newBuildDir: Directory = rootProject.layout.buildDirectory .dir("../../build") .get() rootProject.layout.buildDirectory.value(newBuildDir) subprojects { val newSubprojectBuildDir: Directory = newBuildDir.dir(project.name) project.layout.buildDirectory.value(newSubprojectBuildDir) } // home_widget and audioplayers_android still hardcode Java/Kotlin targets to // 1.8 in their own android/build.gradle, while the app compiles at 11 (see // app/build.gradle.kts) — Gradle requires a module's Java and Kotlin compile // tasks to agree, so this forces both to 11, but ONLY for these two known // modules. A blanket override across every subproject broke a third, // unrelated plugin's classpath, so this stays name-scoped on purpose. // gradle.projectsEvaluated (not subprojects { afterEvaluate {} }) is required: // AGP applies each plugin's own android.compileOptions via its own internal // afterEvaluate hook, registered during that subproject's own evaluation — // later than a hook registered from the root script. Only a callback that // fires after every project (and every one of their internal hooks) has // finished evaluating is guaranteed to win. val jvm8PluginsNeedingJvm11 = setOf("home_widget", "audioplayers_android") gradle.projectsEvaluated { subprojects { if (project.name !in jvm8PluginsNeedingJvm11) return@subprojects tasks.withType().configureEach { sourceCompatibility = JavaVersion.VERSION_11.toString() targetCompatibility = JavaVersion.VERSION_11.toString() } tasks.withType().configureEach { compilerOptions { jvmTarget.set(org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_11) } } } } subprojects { project.evaluationDependsOn(":app") } tasks.register("clean") { delete(rootProject.layout.buildDirectory) }