Skip to content

Commit 15bfba7

Browse files
committed
Merge remote-tracking branch 'origin/develop'
2 parents 0e12731 + 069759f commit 15bfba7

File tree

3 files changed

+90
-16
lines changed

3 files changed

+90
-16
lines changed

src/functionalTest/kotlin/kotlinx/validation/test/KlibVerificationTests.kt

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -852,7 +852,7 @@ internal class KlibVerificationTests : BaseKotlinGradleTest() {
852852
}
853853

854854
@Test
855-
fun `check cross compilation support`() {
855+
fun `check cross compilation support for apiDump`() {
856856
Assume.assumeFalse(HostManager().isEnabled(KonanTarget.MACOS_ARM64))
857857

858858
val runner = test {
@@ -868,7 +868,29 @@ internal class KlibVerificationTests : BaseKotlinGradleTest() {
868868
arguments.addAll(listOf(":apiDump", "-Pkotlin.native.enableKlibsCrossCompilation=true"))
869869
}
870870
}
871-
872871
checkKlibDump(runner.build(), "/examples/classes/TopLevelDeclarations.klib.all.dump")
873872
}
873+
874+
@Test
875+
fun `check cross compilation support for apiCheck`() {
876+
Assume.assumeFalse(HostManager().isEnabled(KonanTarget.MACOS_ARM64))
877+
878+
val runner = test {
879+
settingsGradleKts {
880+
resolve("/examples/gradle/settings/settings-name-testproject.gradle.kts")
881+
}
882+
buildGradleKts {
883+
resolve("/examples/gradle/base/withNativePluginAndCrossCompilation.gradle.kts")
884+
}
885+
additionalBuildConfig("/examples/gradle/configuration/appleTargets/targets.gradle.kts")
886+
addToSrcSet("/examples/classes/TopLevelDeclarations.kt")
887+
abiFile(projectName = "testproject") {
888+
resolve("/examples/classes/TopLevelDeclarations.klib.all.dump")
889+
}
890+
runner {
891+
arguments.addAll(listOf(":apiCheck", "-Pkotlin.native.enableKlibsCrossCompilation=true"))
892+
}
893+
}
894+
assertApiCheckPassed(runner.build())
895+
}
874896
}

src/main/kotlin/BinaryCompatibilityValidatorPlugin.kt

Lines changed: 27 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -494,6 +494,8 @@ private class KlibValidationPipelineBuilder(
494494
it.dumps.addAll(inferredDumps)
495495
}
496496

497+
val kgpVersion = readVersion()
498+
497499
kotlin.targets.matching { it.emitsKlib }.configureEach { currentTarget ->
498500
val mainCompilation = currentTarget.mainCompilationOrNull ?: return@configureEach
499501

@@ -502,7 +504,7 @@ private class KlibValidationPipelineBuilder(
502504
val targetConfig = TargetConfig(project, extension, targetName, intermediateFilesConfig)
503505
val apiBuildDir =
504506
targetConfig.apiDir.flatMap { f -> project.layout.buildDirectory.asFile.map { it.resolve(f) } }
505-
val targetSupported = targetIsSupported(currentTarget)
507+
val targetSupported = targetIsSupported(currentTarget, kgpVersion)
506508
// If a target is supported, the workflow is simple: create a dump, then merge it along with other dumps.
507509
if (targetSupported) {
508510
val buildTargetAbi = configureKlibCompilation(
@@ -542,32 +544,32 @@ private class KlibValidationPipelineBuilder(
542544
}
543545
}
544546

545-
private fun Project.targetIsSupported(target: KotlinTarget): Boolean {
547+
private fun Project.targetIsSupported(target: KotlinTarget, kgpVersion: String?): Boolean {
546548
if (bannedTargets().contains(target.targetName)) return false
547549
if (target !is KotlinNativeTarget || HostManager().isEnabled(target.konanTarget)) {
548550
return true
549551
}
550552

553+
if (kgpVersion == null) return false
554+
551555
// Starting from Kotlin 2.1.0, cross compilation could be enabled via property
552-
if (!isKgpVersionAtLeast2_1(getKotlinPluginVersion())) return false
556+
if (!isKgpVersionAtLeast2_1(kgpVersion)) return false
553557

554-
return (project.findProperty(ENABLE_CROSS_COMPILATION_PROPERTY_NAME) as String?).toBoolean()
558+
val propertyValue = project.findProperty(ENABLE_CROSS_COMPILATION_PROPERTY_NAME) as String?
559+
if (propertyValue == null) {
560+
// Starting from Kotlin 2.2.20, cross compilation is enabled by default (KT-76421)
561+
if (isKgpVersionAtLeast2_2_20(kgpVersion)) return true
562+
}
563+
return propertyValue.toBoolean()
555564
}
556565

557566
// Compilable targets not supported by the host compiler
558567
private fun Project.unsupportedTargets(): Provider<Set<KlibTarget>> {
559-
val banned = bannedTargets() // for testing only
560568
return project.provider {
561-
val hm = HostManager()
569+
val kgpVersion = readVersion()
562570
project.kotlinMultiplatform.targets.matching { it.emitsKlib }
563571
.asSequence()
564-
.filter {
565-
if (it is KotlinNativeTarget) {
566-
!hm.isEnabled(it.konanTarget) || it.targetName in banned
567-
} else {
568-
false
569-
}
570-
}
572+
.filterNot { targetIsSupported(it, kgpVersion) }
571573
.map { it.toKlibTarget() }
572574
.toSet()
573575
}
@@ -775,10 +777,21 @@ private var Configuration.isCanBeDeclaredCompat: Boolean
775777
}
776778
}
777779

778-
private fun isKgpVersionAtLeast2_1(kgpVersion: String): Boolean {
780+
internal fun isKgpVersionAtLeast2_1(kgpVersion: String): Boolean {
779781
val parts = kgpVersion.split('.')
780782
if (parts.size < 2) return false
781783
val major = parts[0].toIntOrNull() ?: return false
782784
val minor = parts[1].toIntOrNull() ?: return false
783785
return major > 2 || (major == 2 && minor >= 1)
784786
}
787+
788+
internal fun isKgpVersionAtLeast2_2_20(kgpVersion: String): Boolean {
789+
val parts = kgpVersion.split('.')
790+
if (parts.size < 3) return false
791+
val major = parts[0].toIntOrNull() ?: return false
792+
val minor = parts[1].toIntOrNull() ?: return false
793+
if (major > 2 || (major == 2 && minor > 2)) return true
794+
795+
val patch = parts[2].split('-')[0].toIntOrNull() ?: return false
796+
return major == 2 && minor == 2 && patch >= 20
797+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/*
2+
* Copyright 2016-2025 JetBrains s.r.o.
3+
* Use of this source code is governed by the Apache 2.0 License that can be found in the LICENSE.txt file.
4+
*/
5+
6+
package tests
7+
8+
import kotlinx.validation.*
9+
import kotlin.test.Test
10+
import kotlin.test.assertFalse
11+
import kotlin.test.assertTrue
12+
13+
class KgpVersionParsingTest {
14+
@Test
15+
fun isKgpVersionAtLeast2_1() {
16+
assertFalse(isKgpVersionAtLeast2_1(""))
17+
assertFalse(isKgpVersionAtLeast2_1("3"))
18+
assertFalse(isKgpVersionAtLeast2_1("1.9.20"))
19+
assertTrue(isKgpVersionAtLeast2_1("2.1"))
20+
assertTrue(isKgpVersionAtLeast2_1("2.1.0"))
21+
assertTrue(isKgpVersionAtLeast2_1("2.2.0-RC3"))
22+
assertTrue(isKgpVersionAtLeast2_1("2.2.20"))
23+
}
24+
25+
@Test
26+
fun isKgpVersionAtLeast2_2_20() {
27+
assertFalse(isKgpVersionAtLeast2_2_20(""))
28+
assertFalse(isKgpVersionAtLeast2_2_20("3"))
29+
assertFalse(isKgpVersionAtLeast2_2_20("1.9.20"))
30+
assertFalse(isKgpVersionAtLeast2_2_20("2.1"))
31+
assertFalse(isKgpVersionAtLeast2_2_20("2.1.0"))
32+
assertFalse(isKgpVersionAtLeast2_2_20("2.2.0-RC3"))
33+
assertTrue(isKgpVersionAtLeast2_2_20("2.2.20"))
34+
assertTrue(isKgpVersionAtLeast2_2_20("2.2.20-Beta2"))
35+
assertTrue(isKgpVersionAtLeast2_2_20("2.2.21"))
36+
assertTrue(isKgpVersionAtLeast2_2_20("2.3.0"))
37+
assertTrue(isKgpVersionAtLeast2_2_20("3.0.0"))
38+
}
39+
}

0 commit comments

Comments
 (0)