From 86926a711ec1ba2ae2a94325779b338b0f4a7f12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vendula=20=C5=A0vastalov=C3=A1?= Date: Fri, 31 Jul 2026 11:57:18 +0200 Subject: [PATCH 1/6] Resolve Swift compatibility libraries at iOS link time --- .../org/jetbrains/compose/ComposePlugin.kt | 1 + .../compose/SwiftCompatibilityLinking.kt | 58 +++++++++++++++++++ 2 files changed, 59 insertions(+) create mode 100644 gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/SwiftCompatibilityLinking.kt diff --git a/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/ComposePlugin.kt b/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/ComposePlugin.kt index 852b846cc31..55bb1fda5cb 100644 --- a/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/ComposePlugin.kt +++ b/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/ComposePlugin.kt @@ -55,6 +55,7 @@ abstract class ComposePlugin : Plugin { project.configureWeb() project.configureRuntimeLibrariesCompatibilityCheck(dependencyCompatibilityExtension) + project.configureSwiftCompatibilityLinking() project.afterEvaluate { configureDesktop(project, desktopExtension) diff --git a/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/SwiftCompatibilityLinking.kt b/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/SwiftCompatibilityLinking.kt new file mode 100644 index 00000000000..2fc324ea725 --- /dev/null +++ b/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/SwiftCompatibilityLinking.kt @@ -0,0 +1,58 @@ +/* + * Copyright 2026 JetBrains s.r.o. and respective authors and developers. + * Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE.txt file. + */ + +package org.jetbrains.compose + +import org.gradle.api.Project +import org.jetbrains.compose.internal.KOTLIN_MPP_PLUGIN_ID +import org.jetbrains.compose.internal.mppExt +import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget +import org.jetbrains.kotlin.gradle.plugin.mpp.NativeBinary +import org.jetbrains.kotlin.konan.target.KonanTarget +import java.io.File + +/** Configures iOS linker tasks to resolve the active Xcode's Swift compatibility-library path at link time. */ +internal fun Project.configureSwiftCompatibilityLinking() { + plugins.withId(KOTLIN_MPP_PLUGIN_ID) { + mppExt.targets.withType(KotlinNativeTarget::class.java).all { target -> + target.configureSwiftCompatibilityLinking() + } + } +} + +private fun KotlinNativeTarget.configureSwiftCompatibilityLinking() { + if (System.getProperty("os.name") != "Mac OS X") return + + val sdkName = + when (konanTarget) { + KonanTarget.IOS_ARM64 -> "iphoneos" + KonanTarget.IOS_X64, + KonanTarget.IOS_SIMULATOR_ARM64 -> "iphonesimulator" + else -> return + } + val swiftCompatibilityLibraryDir = + project.providers + .exec { spec -> spec.commandLine("xcrun", "--find", "swiftc") } + .standardOutput + .asText + .map { swiftcPath -> + File(swiftcPath.trim()) + .parentFile + .parentFile + .parentFile + .resolve("usr/lib/swift/$sdkName") + .absolutePath + } + + binaries.withType(NativeBinary::class.java).all { binary -> + binary.linkTaskProvider.configure { linkTask -> + linkTask.toolOptions.freeCompilerArgs.addAll( + swiftCompatibilityLibraryDir.map { libraryDir -> + listOf("-linker-option", "-L$libraryDir") + } + ) + } + } +} From 18d1e7dcc49577c6290176d742c217fff0d55f47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vendula=20=C5=A0vastalov=C3=A1?= Date: Mon, 14 Sep 2026 18:43:23 +0200 Subject: [PATCH 2/6] Resolve Swift toolchain path by SDK --- .../org/jetbrains/compose/SwiftCompatibilityLinking.kt | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/SwiftCompatibilityLinking.kt b/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/SwiftCompatibilityLinking.kt index 2fc324ea725..21e2ffcd501 100644 --- a/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/SwiftCompatibilityLinking.kt +++ b/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/SwiftCompatibilityLinking.kt @@ -34,14 +34,11 @@ private fun KotlinNativeTarget.configureSwiftCompatibilityLinking() { } val swiftCompatibilityLibraryDir = project.providers - .exec { spec -> spec.commandLine("xcrun", "--find", "swiftc") } + .exec { spec -> spec.commandLine("xcrun", "--sdk", sdkName, "--show-toolchain-path") } .standardOutput .asText - .map { swiftcPath -> - File(swiftcPath.trim()) - .parentFile - .parentFile - .parentFile + .map { toolchainPath -> + File(toolchainPath.trim()) .resolve("usr/lib/swift/$sdkName") .absolutePath } From d2f9635a19463f9bcc76291ea6fbe5bf7442616f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vendula=20=C5=A0vastalov=C3=A1?= Date: Mon, 21 Sep 2026 13:49:38 +0200 Subject: [PATCH 3/6] Use Kotlin DSL Swift linker filtering --- gradle-plugins/compose/build.gradle.kts | 1 + .../org/jetbrains/compose/SwiftCompatibilityLinking.kt | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/gradle-plugins/compose/build.gradle.kts b/gradle-plugins/compose/build.gradle.kts index cef4ce87ef4..06c793d0afe 100644 --- a/gradle-plugins/compose/build.gradle.kts +++ b/gradle-plugins/compose/build.gradle.kts @@ -68,6 +68,7 @@ dependencies { } compileOnly(gradleApi()) + compileOnly(gradleKotlinDsl()) compileOnly(localGroovy()) compileOnly(kotlin("gradle-plugin")) compileOnly(kotlin("native-utils")) diff --git a/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/SwiftCompatibilityLinking.kt b/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/SwiftCompatibilityLinking.kt index 21e2ffcd501..1a647b8c2d4 100644 --- a/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/SwiftCompatibilityLinking.kt +++ b/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/SwiftCompatibilityLinking.kt @@ -6,6 +6,7 @@ package org.jetbrains.compose import org.gradle.api.Project +import org.gradle.kotlin.dsl.withType import org.jetbrains.compose.internal.KOTLIN_MPP_PLUGIN_ID import org.jetbrains.compose.internal.mppExt import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget @@ -16,7 +17,7 @@ import java.io.File /** Configures iOS linker tasks to resolve the active Xcode's Swift compatibility-library path at link time. */ internal fun Project.configureSwiftCompatibilityLinking() { plugins.withId(KOTLIN_MPP_PLUGIN_ID) { - mppExt.targets.withType(KotlinNativeTarget::class.java).all { target -> + mppExt.targets.withType().all { target -> target.configureSwiftCompatibilityLinking() } } @@ -43,7 +44,7 @@ private fun KotlinNativeTarget.configureSwiftCompatibilityLinking() { .absolutePath } - binaries.withType(NativeBinary::class.java).all { binary -> + binaries.withType().all { binary -> binary.linkTaskProvider.configure { linkTask -> linkTask.toolOptions.freeCompilerArgs.addAll( swiftCompatibilityLibraryDir.map { libraryDir -> From ce2f943b8ff8bb93c22bc9ac64acad0cd08d9f8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vendula=20=C5=A0vastalov=C3=A1?= Date: Mon, 21 Sep 2026 14:05:30 +0200 Subject: [PATCH 4/6] Use Gradle OS API for Swift linking --- .../kotlin/org/jetbrains/compose/SwiftCompatibilityLinking.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/SwiftCompatibilityLinking.kt b/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/SwiftCompatibilityLinking.kt index 1a647b8c2d4..b2168ebf3d1 100644 --- a/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/SwiftCompatibilityLinking.kt +++ b/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/SwiftCompatibilityLinking.kt @@ -6,6 +6,7 @@ package org.jetbrains.compose import org.gradle.api.Project +import org.gradle.internal.os.OperatingSystem import org.gradle.kotlin.dsl.withType import org.jetbrains.compose.internal.KOTLIN_MPP_PLUGIN_ID import org.jetbrains.compose.internal.mppExt @@ -24,7 +25,7 @@ internal fun Project.configureSwiftCompatibilityLinking() { } private fun KotlinNativeTarget.configureSwiftCompatibilityLinking() { - if (System.getProperty("os.name") != "Mac OS X") return + if (!OperatingSystem.current().isMacOsX) return val sdkName = when (konanTarget) { From 99c041347795379149b99a6cd26e8df9a35d30da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vendula=20=C5=A0vastalov=C3=A1?= Date: Tue, 22 Sep 2026 17:30:49 +0200 Subject: [PATCH 5/6] Document Swift compatibility linking workaround --- .../org/jetbrains/compose/SwiftCompatibilityLinking.kt | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/SwiftCompatibilityLinking.kt b/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/SwiftCompatibilityLinking.kt index b2168ebf3d1..3c5d4bb3b19 100644 --- a/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/SwiftCompatibilityLinking.kt +++ b/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/SwiftCompatibilityLinking.kt @@ -15,7 +15,13 @@ import org.jetbrains.kotlin.gradle.plugin.mpp.NativeBinary import org.jetbrains.kotlin.konan.target.KonanTarget import java.io.File -/** Configures iOS linker tasks to resolve the active Xcode's Swift compatibility-library path at link time. */ +/** + * Adds the active Xcode toolchain's Swift library directory to iOS native links. + * + * Kotlin/Native does not currently add this directory itself (KT-69793). Resolving it at final link time + * avoids publishing an absolute Xcode path in klib metadata; Swift auto-link metadata selects the needed + * runtime and compatibility libraries. + */ internal fun Project.configureSwiftCompatibilityLinking() { plugins.withId(KOTLIN_MPP_PLUGIN_ID) { mppExt.targets.withType().all { target -> From e206019ac4bb0b04f799965de5ff0926087911ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vendula=20=C5=A0vastalov=C3=A1?= Date: Tue, 22 Sep 2026 17:37:53 +0200 Subject: [PATCH 6/6] Clarify Swift linking workaround --- .../org/jetbrains/compose/SwiftCompatibilityLinking.kt | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/SwiftCompatibilityLinking.kt b/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/SwiftCompatibilityLinking.kt index 3c5d4bb3b19..8b86df9c3b2 100644 --- a/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/SwiftCompatibilityLinking.kt +++ b/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/SwiftCompatibilityLinking.kt @@ -18,9 +18,8 @@ import java.io.File /** * Adds the active Xcode toolchain's Swift library directory to iOS native links. * - * Kotlin/Native does not currently add this directory itself (KT-69793). Resolving it at final link time - * avoids publishing an absolute Xcode path in klib metadata; Swift auto-link metadata selects the needed - * runtime and compatibility libraries. + * Kotlin/Native does not currently add this directory itself (KT-69793). It is resolved from the active + * toolchain at final link time; Swift auto-link metadata selects the needed runtime and compatibility libraries. */ internal fun Project.configureSwiftCompatibilityLinking() { plugins.withId(KOTLIN_MPP_PLUGIN_ID) {