Skip to content

Commit bd2b426

Browse files
adam-enkoSpace Team
authored andcommitted
[Gradle] Only register commonizeCInterop if there are native targets
^KT-81510
1 parent f66516e commit bd2b426

File tree

4 files changed

+105
-35
lines changed

4 files changed

+105
-35
lines changed

libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/internal/CommonizerTasks.kt

Lines changed: 46 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,10 @@ import org.jetbrains.kotlin.commonizer.CommonizerOutputFileLayout
1919
import org.jetbrains.kotlin.commonizer.SharedCommonizerTarget
2020
import org.jetbrains.kotlin.commonizer.konanTargets
2121
import org.jetbrains.kotlin.compilerRunner.maybeCreateCommonizerClasspathConfiguration
22+
import org.jetbrains.kotlin.gradle.dsl.multiplatformExtensionOrNull
2223
import org.jetbrains.kotlin.gradle.internal.isInIdeaSync
2324
import org.jetbrains.kotlin.gradle.internal.properties.nativeProperties
25+
import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
2426
import org.jetbrains.kotlin.gradle.plugin.KotlinPluginLifecycle
2527
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider
2628
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.Companion.kotlinPropertiesProvider
@@ -31,9 +33,9 @@ import org.jetbrains.kotlin.gradle.targets.native.toolchain.KotlinNativeBundleAr
3133
import org.jetbrains.kotlin.gradle.targets.native.toolchain.KotlinNativeBundleArtifactFormat.addKotlinNativeBundleConfiguration
3234
import org.jetbrains.kotlin.gradle.targets.native.toolchain.KotlinNativeBundleBuildService
3335
import org.jetbrains.kotlin.gradle.targets.native.toolchain.KotlinNativeFromToolchainProvider
34-
import org.jetbrains.kotlin.gradle.utils.whenEvaluated
3536
import org.jetbrains.kotlin.gradle.tasks.dependsOn
3637
import org.jetbrains.kotlin.gradle.tasks.locateOrRegisterTask
38+
import org.jetbrains.kotlin.gradle.utils.whenEvaluated
3739
import java.io.File
3840
import javax.inject.Inject
3941

@@ -84,33 +86,54 @@ internal val Project.runCommonizerTask: TaskProvider<Task>
8486
)
8587

8688
private const val commonizeCInteropTaskName = "commonizeCInterop"
89+
8790
internal suspend fun Project.commonizeCInteropTask(): TaskProvider<CInteropCommonizerTask>? {
88-
if (cInteropCommonizationEnabled()) {
89-
val nativeDownloadTask = getOrRegisterDownloadKotlinNativeDistributionTask()
91+
KotlinPluginLifecycle.Stage.AfterEvaluateBuildscript.await()
9092

91-
return locateOrRegisterTask(
92-
commonizeCInteropTaskName,
93-
invokeWhenRegistered = {
94-
val task = this
95-
commonizeTask.dependsOn(this)
96-
whenEvaluated {
97-
commonizeNativeDistributionTask?.let(task::dependsOn)
98-
}
99-
},
100-
configureTask = {
101-
group = "interop"
102-
description = "Invokes the commonizer on c-interop bindings of the project"
93+
if (!isCommonizeCInteropTaskRegistrationEnabled()) {
94+
return null
95+
}
10396

104-
commonizerClasspath.from(project.maybeCreateCommonizerClasspathConfiguration())
105-
customJvmArgs.set(PropertiesProvider(project).commonizerJvmArgs)
106-
kotlinCompilerArgumentsLogLevel
107-
.value(project.kotlinPropertiesProvider.kotlinCompilerArgumentsLogLevel)
108-
.finalizeValueOnRead()
109-
dependsOn(nativeDownloadTask)
97+
val nativeDownloadTask = getOrRegisterDownloadKotlinNativeDistributionTask()
98+
99+
return locateOrRegisterTask(
100+
commonizeCInteropTaskName,
101+
invokeWhenRegistered = {
102+
val task = this
103+
commonizeTask.dependsOn(this)
104+
whenEvaluated {
105+
commonizeNativeDistributionTask?.let(task::dependsOn)
110106
}
111-
)
107+
},
108+
configureTask = {
109+
group = "interop"
110+
description = "Invokes the commonizer on c-interop bindings of the project"
111+
112+
commonizerClasspath.from(project.maybeCreateCommonizerClasspathConfiguration())
113+
customJvmArgs.set(PropertiesProvider(project).commonizerJvmArgs)
114+
kotlinCompilerArgumentsLogLevel
115+
.value(project.kotlinPropertiesProvider.kotlinCompilerArgumentsLogLevel)
116+
.finalizeValueOnRead()
117+
118+
dependsOn(nativeDownloadTask)
119+
}
120+
)
121+
}
122+
123+
private suspend fun Project.isCommonizeCInteropTaskRegistrationEnabled(): Boolean {
124+
if (!cInteropCommonizationEnabled()) {
125+
logger.info("[${project.path}] $commonizeCInteropTaskName task registration disabled. cInteropCommonizationEnabled == false")
126+
return false
112127
}
113-
return null
128+
129+
val projectHasNativeTargets = multiplatformExtensionOrNull?.targets.orEmpty().any { it.platformType == KotlinPlatformType.native }
130+
if (!projectHasNativeTargets) {
131+
logger.info("[${project.path}] $commonizeCInteropTaskName task registration disabled. Project has no native Kotlin targets.")
132+
return false
133+
}
134+
135+
logger.info("[${project.path}] $commonizeCInteropTaskName task registration enabled.")
136+
return true
114137
}
115138

116139
internal suspend fun Project.copyCommonizeCInteropForIdeTask(): TaskProvider<CopyCommonizeCInteropForIdeTask>? {

libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/unitTests/CInteropCommonizerTaskTest.kt

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,13 @@ package org.jetbrains.kotlin.gradle.unitTests
99

1010
import org.jetbrains.kotlin.commonizer.CommonizerTarget
1111
import org.jetbrains.kotlin.commonizer.SharedCommonizerTarget
12-
import org.jetbrains.kotlin.gradle.util.MultiplatformExtensionTest
1312
import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
1413
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
15-
import org.jetbrains.kotlin.gradle.targets.native.internal.CInteropCommonizerTask
1614
import org.jetbrains.kotlin.gradle.targets.native.internal.CInteropCommonizerGroup
15+
import org.jetbrains.kotlin.gradle.targets.native.internal.CInteropCommonizerTask
1716
import org.jetbrains.kotlin.gradle.targets.native.internal.commonizeCInteropTask
1817
import org.jetbrains.kotlin.gradle.targets.native.internal.findCInteropCommonizerGroup
18+
import org.jetbrains.kotlin.gradle.util.MultiplatformExtensionTest
1919
import org.jetbrains.kotlin.gradle.util.enableCInteropCommonization
2020
import org.jetbrains.kotlin.gradle.util.main
2121
import org.jetbrains.kotlin.gradle.util.runLifecycleAwareTest
@@ -55,7 +55,6 @@ class CInteropCommonizerTaskTest : MultiplatformExtensionTest() {
5555

5656
@Test
5757
fun `nativeMain linux macos`() = project.runLifecycleAwareTest {
58-
val task = this@CInteropCommonizerTaskTest.task.await()
5958
val linuxInterop = kotlin.linuxX64("linux").compilations.getByName("main").cinterops.create("anyInteropName")
6059
val macosInterop = kotlin.macosX64("macos").compilations.getByName("main").cinterops.create("anyInteropName")
6160

@@ -68,7 +67,7 @@ class CInteropCommonizerTaskTest : MultiplatformExtensionTest() {
6867
linuxMain.dependsOn(nativeMain)
6968
macosMain.dependsOn(nativeMain)
7069

71-
70+
val task = this@CInteropCommonizerTaskTest.task.await()
7271
val groups = task.allInteropGroups.await()
7372
assertEquals(1, groups.size, "Expected only one InteropsGroup")
7473

@@ -110,7 +109,6 @@ class CInteropCommonizerTaskTest : MultiplatformExtensionTest() {
110109

111110
@Test
112111
fun `nativeMain iosMain linux macos iosX64 iosArm64`() = project.runLifecycleAwareTest {
113-
val task = this@CInteropCommonizerTaskTest.task.await()
114112
val linuxInterop = kotlin.linuxX64("linux").compilations.getByName("main").cinterops.create("anyInteropName").identifier
115113
val macosInterop = kotlin.macosX64("macos").compilations.getByName("main").cinterops.create("anyInteropName").identifier
116114
val iosX64Interop = kotlin.iosX64("iosX64").compilations.getByName("main").cinterops.create("anyInteropName").identifier
@@ -131,6 +129,7 @@ class CInteropCommonizerTaskTest : MultiplatformExtensionTest() {
131129
iosX64Main.dependsOn(iosMain)
132130
iosArm64Main.dependsOn(iosMain)
133131

132+
val task = this@CInteropCommonizerTaskTest.task.await()
134133
assertEquals(
135134
1, task.allInteropGroups.await().size,
136135
"Expected exactly one InteropsGroup for task"
@@ -166,7 +165,6 @@ class CInteropCommonizerTaskTest : MultiplatformExtensionTest() {
166165
private fun `nativeTest nativeMain linux macos`(
167166
nativeTestDependsOnNativeMain: Boolean,
168167
) = project.runLifecycleAwareTest {
169-
val task = this@CInteropCommonizerTaskTest.task.await()
170168
val linuxInterop = kotlin.linuxX64("linux").compilations.getByName("main").cinterops.create("anyInteropName").identifier
171169
val macosInterop = kotlin.macosX64("macos").compilations.getByName("main").cinterops.create("anyInteropName").identifier
172170

@@ -191,6 +189,7 @@ class CInteropCommonizerTaskTest : MultiplatformExtensionTest() {
191189
nativeTest.dependsOn(nativeMain)
192190
}
193191

192+
val task = this@CInteropCommonizerTaskTest.task.await()
194193
assertEquals(
195194
1, task.allInteropGroups.await().size,
196195
"Expected exactly 1 'SharedInteropsGroup' for task"
@@ -230,7 +229,6 @@ class CInteropCommonizerTaskTest : MultiplatformExtensionTest() {
230229
private fun `nativeTest nativeMain linux macos - test compilation defines custom cinterop`(
231230
nativeTestDependsOnNativeMain: Boolean,
232231
) = project.runLifecycleAwareTest {
233-
val task = this@CInteropCommonizerTaskTest.task.await()
234232
val linuxInterop = kotlin.linuxX64("linux").compilations.getByName("main").cinterops.create("anyInteropName").identifier
235233
val macosInterop = kotlin.macosX64("macos").compilations.getByName("main").cinterops.create("anyInteropName").identifier
236234
kotlin.linuxX64("linux").compilations.getByName("test").cinterops.create("anyOtherName").identifier
@@ -256,7 +254,7 @@ class CInteropCommonizerTaskTest : MultiplatformExtensionTest() {
256254
nativeTest.dependsOn(nativeMain)
257255
}
258256

259-
257+
val task = this@CInteropCommonizerTaskTest.task.await()
260258
assertEquals(
261259
1, task.allInteropGroups.await().size,
262260
"Expected exactly 1 'SharedInteropsGroup' for task"
@@ -292,7 +290,6 @@ class CInteropCommonizerTaskTest : MultiplatformExtensionTest() {
292290
}
293291

294292
private fun `hierarchical project`(testSourceSetsDependOnMainSourceSets: Boolean) = project.runLifecycleAwareTest {
295-
val task = this@CInteropCommonizerTaskTest.task.await()
296293
/* Define targets */
297294
val linux = kotlin.linuxX64("linux")
298295
val macos = kotlin.macosX64("macos")
@@ -395,6 +392,7 @@ class CInteropCommonizerTaskTest : MultiplatformExtensionTest() {
395392
assertCInteropDependentEqualsForSourceSetAndCompilation(appleMain)
396393
assertCInteropDependentEqualsForSourceSetAndCompilation(iosMain)
397394

395+
val task = this@CInteropCommonizerTaskTest.task.await()
398396
val groups = task.allInteropGroups.await()
399397
assertEquals(2, groups.size, "Expected exactly two interop groups: main and test")
400398

libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/unitTests/CommonizerTaskTests.kt

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,4 +229,53 @@ class CommonizerTaskTests {
229229
project.copyCommonizeCInteropForIdeTask()?.get()?.cInteropCommonizerTaskOutputDirectories
230230
}
231231
}
232+
233+
@Test
234+
fun `test multi-module project - when commonization is enabled - expect commonizeCInterop task only registered in subprojects with native targets`() {
235+
val project = ProjectBuilder.builder()
236+
.withName("root")
237+
.build()
238+
239+
with(project) {
240+
enableCInteropCommonization()
241+
(this as ProjectInternal).evaluate()
242+
}
243+
244+
val subprojectWithNativeTarget = ProjectBuilder
245+
.builder()
246+
.withName("subprojectWithNativeTarget")
247+
.withParent(project)
248+
.build()
249+
with(subprojectWithNativeTarget) {
250+
applyMultiplatformPlugin()
251+
kotlin {
252+
jvm()
253+
js()
254+
linuxX64()
255+
}
256+
enableCInteropCommonization()
257+
(this as ProjectInternal).evaluate()
258+
}
259+
260+
val subprojectWithoutNativeTarget = ProjectBuilder.builder()
261+
.withName("subprojectWithoutNativeTarget")
262+
.withParent(project)
263+
.build()
264+
with(subprojectWithoutNativeTarget) {
265+
applyMultiplatformPlugin()
266+
kotlin {
267+
jvm()
268+
js()
269+
}
270+
enableCInteropCommonization()
271+
(this as ProjectInternal).evaluate()
272+
}
273+
274+
subprojectWithNativeTarget.runLifecycleAwareTest {
275+
assertContainsTaskWithName("commonizeCInterop")
276+
}
277+
subprojectWithoutNativeTarget.runLifecycleAwareTest {
278+
assertContainsNoTaskWithName("commonizeCInterop")
279+
}
280+
}
232281
}

libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/util/assertions.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -100,12 +100,12 @@ fun Task.assertTaskDependenciesEquals(dependencies: Set<Task>) {
100100
fun Project.assertContainsTaskWithName(taskName: String): Task {
101101
this.getKotlinPluginVersion()
102102
return project.tasks.findByName(taskName)
103-
?: fail("Expected task with name $taskName in project ${this.path}")
103+
?: fail("Expected task with name $taskName in project ${this.path}. All tasks: ${project.tasks.names}")
104104
}
105105

106106
fun Project.assertContainsNoTaskWithName(taskName: String) {
107107
if (taskName in tasks.names) {
108-
fail("Expected *no* task with name $taskName in project ${this.path}")
108+
fail("Expected *no* task with name $taskName in project ${this.path}. All tasks: ${project.tasks.names}")
109109
}
110110
}
111111

@@ -209,4 +209,4 @@ inline fun <reified T : Throwable> assertFailsWithChainedCause(block: () -> Unit
209209
cause = cause.cause
210210
}
211211
fail("Expected to fail with ${T::class.java.name} but failed with ${throwable::class.java.name}")
212-
}
212+
}

0 commit comments

Comments
 (0)