1+
2+ import com.android.build.gradle.internal.tasks.factory.dependsOn
13import org.gradle.api.Action
24import org.gradle.api.Project
5+ import org.gradle.api.tasks.testing.Test
36import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
7+ import org.jetbrains.kotlin.gradle.dsl.kotlinExtension
8+ import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget
49import org.jetbrains.kotlin.gradle.targets.js.ir.KotlinJsIrLink
10+ import org.jetbrains.kotlin.gradle.targets.jvm.KotlinJvmTarget
511import org.jetbrains.kotlin.gradle.tasks.KotlinNativeLink
12+ import org.jetbrains.kotlin.konan.target.Family
613
714private val allAppleTargets = setOf (
815 " macosX64" ,
@@ -19,23 +26,23 @@ private val allAppleTargets = setOf(
1926)
2027
2128// Try to guess the dev machine to make sure the tests are running smoothly
22- val hostTarget: String
29+ internal val hostTarget: String
2330 get() = if (System .getProperty(" os.arch" ) == " aarch64" ) {
2431 " macosArm64"
2532 } else {
2633 " macosX64"
2734 }
2835
29- val enabledAppleTargets = allAppleTargets
30- val enabledLinux = true
31- val enabledJs = true
36+ private val enableLinux = true
37+ private val enableJs = true
3238
3339fun Project.configureMppDefaults (withJs : Boolean , withLinux : Boolean , withAndroid : Boolean ) {
3440 configureMpp(
3541 withJvm = true ,
3642 withJs = withJs,
43+ browserTest = false ,
3744 withLinux = withLinux,
38- appleTargets = enabledAppleTargets ,
45+ appleTargets = allAppleTargets ,
3946 withAndroid = withAndroid,
4047 )
4148}
@@ -67,7 +74,7 @@ fun Project.configureMpp(
6774 withLinux : Boolean ,
6875 withAndroid : Boolean ,
6976 appleTargets : Collection <String >,
70- browserTest : Boolean = false ,
77+ browserTest : Boolean ,
7178) {
7279 val kotlinExtension = extensions.findByName(" kotlin" ) as ? KotlinMultiplatformExtension
7380 check(kotlinExtension != null ) {
@@ -78,7 +85,7 @@ fun Project.configureMpp(
7885 jvm()
7986 }
8087
81- if (enabledJs && withJs) {
88+ if (enableJs && withJs) {
8289 js(IR ) {
8390 if (browserTest) {
8491 browser {
@@ -101,7 +108,7 @@ fun Project.configureMpp(
101108 }
102109 }
103110
104- if (enabledLinux && withLinux) {
111+ if (enableLinux && withLinux) {
105112 linuxX64(" linux" )
106113 }
107114
@@ -111,8 +118,14 @@ fun Project.configureMpp(
111118 }
112119 }
113120
114- createAndConfigureAppleTargets(appleTargets.toSet().intersect(enabledAppleTargets))
121+ appleTargets.toSet().intersect(allAppleTargets).forEach { presetName ->
122+ targetFromPreset(
123+ presets.getByName(presetName),
124+ presetName,
125+ )
126+ }
115127
128+ configureSourceSetGraph()
116129 addTestDependencies()
117130
118131 tasks.withType(KotlinJsIrLink ::class .java).configureEach {
@@ -124,31 +137,65 @@ fun Project.configureMpp(
124137 }
125138}
126139
127- private fun KotlinMultiplatformExtension.createAndConfigureAppleTargets (presetNames : Collection <String >) {
128- if (presetNames.isEmpty()) {
129- return
140+ /* *
141+ * Current Graph is something like so
142+ *
143+ * graph TB
144+ * commonMain --> jvmMain
145+ * commonMain --> appleMain
146+ * commonMain --> linuxMain
147+ * commonMain --> jsMain
148+ * appleMain --> macosX64
149+ * appleMain --> macosArm64
150+ * appleMain --> iosArm64
151+ * appleMain --> iosX64
152+ * appleMain --> iosSimulatorArm64
153+ * appleMain --> watchosArm32
154+ * appleMain --> watchosArm64
155+ * appleMain --> watchosSimulatorArm64
156+ * appleMain --> tvosArm64
157+ * appleMain --> tvosX64
158+ * appleMain --> tvosSimulatorArm64
159+ *
160+ *
161+ * commonTest --> kotlinCodegenTest
162+ * commonTest --> jvmJavaCodeGen
163+ * kotlinCodegenTest --> macOsArm64Test
164+ * kotlinCodegenTest --> jvmTest
165+ * kotlinCodegenTest --> jsTest
166+ *
167+ *
168+ *
169+ * classDef kotlinPurple fill:#A97BFF,stroke:#333,stroke-width:2px,color:#333
170+ * classDef javaOrange fill:#b07289,stroke:#333,stroke-width:2px,color:#333
171+ * classDef gray fill:#AAA,stroke:#333,stroke-width:2px,color:#333
172+ * class kotlinCodegenTest gray
173+ * class jvmJavaCodeGen,macOsArm64Test,jvmTest,jsTest kotlinPurple
174+ * class commonTest javaOrange
175+ */
176+ private fun KotlinMultiplatformExtension.configureSourceSetGraph () {
177+ val hasAppleTarget = targets.any {
178+ it is KotlinNativeTarget && it.konanTarget.family in setOf (Family .IOS , Family .OSX , Family .WATCHOS , Family .TVOS )
130179 }
180+ if (hasAppleTarget) {
181+ val appleMain = sourceSets.create(" appleMain" )
182+ val appleTest = sourceSets.create(" appleTest" )
131183
132- if (System .getProperty(" idea.sync.active" ) != null ) {
133- // Early return. Inside intelliJ, only configure one target
134- targetFromPreset(presets.getByName(hostTarget), " apple" )
135- return
136- }
184+ appleMain.dependsOn(sourceSets.getByName(" commonMain" ))
185+ appleTest.dependsOn(sourceSets.getByName(" commonTest" ))
137186
138- val appleMain = sourceSets.create(" appleMain" )
139- val appleTest = sourceSets.create(" appleTest" )
187+ allAppleTargets.forEach {
188+ sourceSets.findByName(" ${it} Main" )?.dependsOn(appleMain)
189+ sourceSets.findByName(" ${it} Test" )?.dependsOn(appleTest)
190+ }
191+ }
140192
141- appleMain.dependsOn(sourceSets.getByName(" commonMain" ))
142- appleTest.dependsOn(sourceSets.getByName(" commonTest" ))
193+ val kotlinCodegentTest = sourceSets.create(" kotlinCodegenTest" )
143194
144- presetNames.forEach { presetName ->
145- targetFromPreset(
146- presets.getByName(presetName),
147- presetName,
148- )
195+ kotlinCodegentTest.dependsOn(sourceSets.getByName(" commonTest" ))
149196
150- sourceSets.getByName( " ${presetName} Main " ).dependsOn(appleMain)
151- sourceSets.getByName (" ${presetName } Test" ).dependsOn(appleTest )
197+ targets.forEach {
198+ sourceSets.findByName (" ${it.name } Test" )? .dependsOn(kotlinCodegentTest )
152199 }
153200}
154201
@@ -159,3 +206,38 @@ private fun KotlinMultiplatformExtension.addTestDependencies() {
159206 }
160207 }
161208}
209+
210+ fun Project.registerJavaCodegenTestTask () {
211+ val kotlin = kotlinExtension
212+ check(kotlin is KotlinMultiplatformExtension ) {
213+ " Only multiplatform projects can register a javaCodegenTest task"
214+ }
215+ val jvmTarget = kotlin.targets.getByName(" jvm" ) as KotlinJvmTarget
216+ jvmTarget.withJava()
217+
218+ val javaCodegenCompilation = jvmTarget.compilations.create(" javaCodegen" )
219+ javaCodegenCompilation.compileJavaTaskProvider?.configure {
220+ classpath + = configurations.getByName(" jvmTestCompileClasspath" )
221+ }
222+ javaCodegenCompilation.configurations.compileDependencyConfiguration.extendsFrom(configurations.getByName(" jvmTestCompileClasspath" ))
223+ javaCodegenCompilation.defaultSourceSet.dependsOn(kotlin.sourceSets.getByName(" commonTest" ))
224+ javaCodegenCompilation.defaultSourceSet.kotlin.apply {
225+ srcDir(" src/kotlinCodegenTest/kotlin" )
226+ }
227+
228+ val task = tasks.register(" javaCodegenTest" , Test ::class .java) {
229+ description = " Runs Java codegen tests."
230+ group = " verification"
231+
232+ testClassesDirs = javaCodegenCompilation.output.classesDirs
233+ classpath = configurations.getByName(" jvmTestRuntimeClasspath" ) + javaCodegenCompilation.output.classesDirs
234+
235+ useJUnit()
236+
237+ testLogging {
238+ events(" passed" )
239+ }
240+ }
241+
242+ tasks.named(" build" ).dependsOn(task)
243+ }
0 commit comments