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/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..8b86df9c3b2 --- /dev/null +++ b/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/SwiftCompatibilityLinking.kt @@ -0,0 +1,62 @@ +/* + * 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.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 +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 + +/** + * Adds the active Xcode toolchain's Swift library directory to iOS native links. + * + * 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) { + mppExt.targets.withType().all { target -> + target.configureSwiftCompatibilityLinking() + } + } +} + +private fun KotlinNativeTarget.configureSwiftCompatibilityLinking() { + if (!OperatingSystem.current().isMacOsX) 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", "--sdk", sdkName, "--show-toolchain-path") } + .standardOutput + .asText + .map { toolchainPath -> + File(toolchainPath.trim()) + .resolve("usr/lib/swift/$sdkName") + .absolutePath + } + + binaries.withType().all { binary -> + binary.linkTaskProvider.configure { linkTask -> + linkTask.toolOptions.freeCompilerArgs.addAll( + swiftCompatibilityLibraryDir.map { libraryDir -> + listOf("-linker-option", "-L$libraryDir") + } + ) + } + } +}