From 42f6eb4eb44e24d7df03200da577de656dec15b4 Mon Sep 17 00:00:00 2001 From: Andrey Yastrebov Date: Tue, 27 Feb 2024 10:47:26 +0100 Subject: [PATCH] KT-66156 add KotlinRuntime to Swift Export Synthetic --- .../iosApp/iosApp/ContentView.swift | 2 +- .../iosApp/iosAppTests/iosAppTests.swift | 2 +- .../simpleSwiftExport/shared/build.gradle.kts | 2 +- ...CopySwiftExportIntermediatesForConsumer.kt | 23 +++++++++- .../GenerateSPMPackageFromSwiftExport.kt | 29 +++++++++++- .../mpp/apple/swiftexport/SwiftExport.kt | 44 +++++++++++-------- .../apple/swiftexport/SwiftExportAction.kt | 3 +- .../swiftexport/SwiftExportParameters.kt | 6 +-- 8 files changed, 81 insertions(+), 30 deletions(-) diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/simpleSwiftExport/iosApp/iosApp/ContentView.swift b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/simpleSwiftExport/iosApp/iosApp/ContentView.swift index 3814d425b59..41441fa77f0 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/simpleSwiftExport/iosApp/iosApp/ContentView.swift +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/simpleSwiftExport/iosApp/iosApp/ContentView.swift @@ -1,5 +1,5 @@ import SwiftUI -@testable import shared +@testable import Shared struct ContentView: View { var body: some View { diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/simpleSwiftExport/iosApp/iosAppTests/iosAppTests.swift b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/simpleSwiftExport/iosApp/iosAppTests/iosAppTests.swift index cb3665a9e6c..ed1906c3b81 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/simpleSwiftExport/iosApp/iosAppTests/iosAppTests.swift +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/simpleSwiftExport/iosApp/iosAppTests/iosAppTests.swift @@ -7,7 +7,7 @@ // import XCTest -@testable import shared +@testable import Shared final class iosAppTests: XCTestCase { diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/simpleSwiftExport/shared/build.gradle.kts b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/simpleSwiftExport/shared/build.gradle.kts index 1d76faa1af4..fa6adca3324 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/simpleSwiftExport/shared/build.gradle.kts +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/simpleSwiftExport/shared/build.gradle.kts @@ -9,7 +9,7 @@ kotlin { iosSimulatorArm64() ).forEach { it.binaries.framework { - baseName = "sdk" + baseName = "Shared" } } diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/apple/swiftexport/CopySwiftExportIntermediatesForConsumer.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/apple/swiftexport/CopySwiftExportIntermediatesForConsumer.kt index ed694c40e33..552c7beb88c 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/apple/swiftexport/CopySwiftExportIntermediatesForConsumer.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/apple/swiftexport/CopySwiftExportIntermediatesForConsumer.kt @@ -24,11 +24,19 @@ internal abstract class CopySwiftExportIntermediatesForConsumer @Inject construc providerFactory: ProviderFactory, private val fileSystem: FileSystemOperations ) : DefaultTask() { + companion object { + private const val KOTLIN_RUNTIME = "KotlinRuntime" + private const val KOTLIN_BRIDGE = "KotlinBridge" + } @get:InputDirectory @get:PathSensitive(PathSensitivity.RELATIVE) abstract val includeBridgeDirectory: RegularFileProperty + @get:InputDirectory + @get:PathSensitive(PathSensitivity.RELATIVE) + abstract val includeKotlinRuntimeDirectory: RegularFileProperty + @get:InputFile @get:PathSensitive(PathSensitivity.RELATIVE) abstract val kotlinLibraryPath: RegularFileProperty @@ -53,7 +61,16 @@ internal abstract class CopySwiftExportIntermediatesForConsumer @Inject construc val syntheticInterfacesDestinationPath: DirectoryProperty = objectFactory.directoryProperty().convention( builtProductsDirectory.flatMap { projectLayout.dir(providerFactory.provider { - it.asFile.resolve("KotlinBridge") + it.asFile.resolve(KOTLIN_BRIDGE) + }) + } + ) + + @get:OutputDirectory + val kotlinRuntimeDestinationPath: DirectoryProperty = objectFactory.directoryProperty().convention( + builtProductsDirectory.flatMap { + projectLayout.dir(providerFactory.provider { + it.asFile.resolve(KOTLIN_RUNTIME) }) } ) @@ -70,5 +87,9 @@ internal abstract class CopySwiftExportIntermediatesForConsumer @Inject construc it.from(includeBridgeDirectory) it.into(syntheticInterfacesDestinationPath) } + fileSystem.copy { + it.from(includeKotlinRuntimeDirectory) + it.into(kotlinRuntimeDestinationPath) + } } } \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/apple/swiftexport/GenerateSPMPackageFromSwiftExport.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/apple/swiftexport/GenerateSPMPackageFromSwiftExport.kt index 113d8596154..22bed6393f5 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/apple/swiftexport/GenerateSPMPackageFromSwiftExport.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/apple/swiftexport/GenerateSPMPackageFromSwiftExport.kt @@ -18,6 +18,9 @@ import org.jetbrains.kotlin.incremental.deleteRecursivelyOrThrow @DisableCachingByDefault(because = "Swift Export is experimental, so no caching for now") internal abstract class GenerateSPMPackageFromSwiftExport : DefaultTask() { + companion object { + private const val KOTLIN_RUNTIME = "KotlinRuntime" + } @get:Input abstract val swiftApiModuleName: Property @@ -31,6 +34,10 @@ internal abstract class GenerateSPMPackageFromSwiftExport : DefaultTask() { @get:Input abstract val kotlinLibraryName: Property + @get:InputDirectory + @get:PathSensitive(PathSensitivity.RELATIVE) + abstract val kotlinRuntime: DirectoryProperty + @get:InputFile @get:PathSensitive(PathSensitivity.RELATIVE) abstract val swiftApiPath: RegularFileProperty @@ -49,6 +56,9 @@ internal abstract class GenerateSPMPackageFromSwiftExport : DefaultTask() { @get:Internal val headerBridgeIncludePath get() = headerBridgeModulePath.resolve("include") + @get:Internal + val kotlinRuntimeIncludePath get() = kotlinRuntimeModulePath.resolve("include") + private val swiftApiModule get() = swiftApiModuleName.get() private val headerBridgeModule get() = headerBridgeModuleName.get() private val spmPackageRootPath get() = packagePath.getFile() @@ -56,6 +66,7 @@ internal abstract class GenerateSPMPackageFromSwiftExport : DefaultTask() { private val sourcesPath get() = spmPackageRootPath.resolve("Sources") private val swiftApiModulePath get() = sourcesPath.resolve(swiftApiModule) private val headerBridgeModulePath get() = sourcesPath.resolve(headerBridgeModule) + private val kotlinRuntimeModulePath get() = sourcesPath.resolve(KOTLIN_RUNTIME) @TaskAction fun generate() { @@ -63,6 +74,7 @@ internal abstract class GenerateSPMPackageFromSwiftExport : DefaultTask() { createHeaderTarget() createSwiftTarget() createPackageManifest() + createKotlinRuntimeTarget() } private fun preparePackageDirectory() { @@ -71,10 +83,11 @@ internal abstract class GenerateSPMPackageFromSwiftExport : DefaultTask() { } swiftApiModulePath.createDirectory() headerBridgeIncludePath.createDirectory() + kotlinRuntimeIncludePath.createDirectory() } private fun createHeaderTarget() { - headerBridgePath.get().asFile.copyTo( + headerBridgePath.getFile().copyTo( headerBridgeIncludePath.resolve("Kotlin.h") ) headerBridgeIncludePath.resolve("module.modulemap").writeText( @@ -91,6 +104,15 @@ internal abstract class GenerateSPMPackageFromSwiftExport : DefaultTask() { headerBridgeModulePath.resolve("linkingStub.c").writeText("\n") } + private fun createKotlinRuntimeTarget() { + kotlinRuntime.asFileTree.forEach { + it.copyTo( + kotlinRuntimeIncludePath.resolve(it.name) + ) + } + kotlinRuntimeModulePath.resolve("linkingStub.c").writeText("\n") + } + private fun createSwiftTarget() { swiftApiModulePath.resolve("Kotlin.swift").writer().use { kotlinApi -> swiftApiPath.get().asFile.reader().forEachLine { @@ -117,10 +139,13 @@ internal abstract class GenerateSPMPackageFromSwiftExport : DefaultTask() { targets: [ .target( name: "$swiftApiModule", - dependencies: ["$headerBridgeModule"] + dependencies: ["$headerBridgeModule", "$KOTLIN_RUNTIME"] ), .target( name: "$headerBridgeModule" + ), + .target( + name: "$KOTLIN_RUNTIME" ) ] ) diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/apple/swiftexport/SwiftExport.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/apple/swiftexport/SwiftExport.kt index 1d286acc450..ee9bcc7c05d 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/apple/swiftexport/SwiftExport.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/apple/swiftexport/SwiftExport.kt @@ -15,8 +15,6 @@ import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformSourceSetConventionsIm import org.jetbrains.kotlin.gradle.dsl.KotlinNativeBinaryContainer import org.jetbrains.kotlin.gradle.dsl.multiplatformExtension import org.jetbrains.kotlin.gradle.plugin.* -import org.jetbrains.kotlin.gradle.plugin.KotlinPluginLifecycle -import org.jetbrains.kotlin.gradle.plugin.kotlinPluginLifecycle import org.jetbrains.kotlin.gradle.plugin.mpp.* import org.jetbrains.kotlin.gradle.tasks.dependsOn import org.jetbrains.kotlin.gradle.tasks.locateOrRegisterTask @@ -26,12 +24,13 @@ import org.jetbrains.kotlin.gradle.utils.getOrCreate import org.jetbrains.kotlin.gradle.utils.konanDistribution import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName import org.jetbrains.kotlin.gradle.utils.mapToFile +import org.jetbrains.kotlin.konan.target.Distribution fun Project.registerSwiftExportTask( framework: Framework, ): TaskProvider<*> { return registerSwiftExportTask( - swiftApiModuleName = framework.baseNameProvider, + swiftApiModuleName = provider { framework.baseName }, target = framework.target, buildType = framework.buildType, ) @@ -112,16 +111,16 @@ private fun Project.registerSwiftExportRun( val kotlinIntermediates = outputs.map { it.dir("kotlinIntermediates") } // Input - task.swiftExportClasspath.from(project.maybeCreateSwiftExportClasspathResolvableConfiguration()) - task.parameters.sourceRoot.set(commonMainProvider.getOrThrow()) - task.parameters.bridgeModuleName.set(swiftApiModuleName.map { "${it}Bridge" }) - task.parameters.debugMode.set(true) - task.parameters.konanDistribution.set(konanDistribution.root) + task.swiftExportClasspath.from(maybeCreateSwiftExportClasspathResolvableConfiguration()) + task.parameters.sourceRoot.convention(commonMainProvider.map { objects.directoryProperty(it) }.getOrThrow()) + task.parameters.bridgeModuleName.convention(swiftApiModuleName.map { "${it}Bridge" }) + task.parameters.debugMode.convention(true) + task.parameters.konanDistribution.convention(Distribution(konanDistribution.root.absolutePath)) // Output - task.parameters.swiftApiPath.set(swiftIntermediates.map { it.file("KotlinAPI.swift") }) - task.parameters.headerBridgePath.set(swiftIntermediates.map { it.file("KotlinBridge.h") }) - task.parameters.kotlinBridgePath.set(kotlinIntermediates.map { it.file("KotlinBridge.kt") }) + task.parameters.swiftApiPath.convention(swiftIntermediates.map { it.file("KotlinAPI.swift") }) + task.parameters.headerBridgePath.convention(swiftIntermediates.map { it.file("KotlinBridge.h") }) + task.parameters.kotlinBridgePath.convention(kotlinIntermediates.map { it.file("KotlinBridge.kt") }) } } @@ -174,13 +173,19 @@ private fun Project.registerPackageGeneration( task.description = "Generates $taskNamePrefix SPM Package" // Input - task.swiftApiPath.set(swiftExportTask.map { it.parameters.swiftApiPath.get() }) - task.headerBridgePath.set(swiftExportTask.map { it.parameters.headerBridgePath.get() }) - task.headerBridgeModuleName.set(swiftExportTask.map { it.parameters.bridgeModuleName.get() }) - task.libraryPath.set { staticLibrary.linkTaskProvider.map { it.outputFile.get() }.get() } - task.swiftLibraryName.set(swiftApiLibraryName) - task.kotlinLibraryName.set(kotlinStaticLibraryName) - task.swiftApiModuleName.set(swiftApiModuleName) + task.kotlinRuntime.convention( + objects.directoryProperty( + file(Distribution(konanDistribution.root.absolutePath).kotlinRuntimeForSwiftHome) + ) + ) + + task.swiftApiPath.convention(swiftExportTask.flatMap { it.parameters.swiftApiPath }) + task.headerBridgePath.convention(swiftExportTask.flatMap { it.parameters.headerBridgePath }) + task.headerBridgeModuleName.convention(swiftExportTask.flatMap { it.parameters.bridgeModuleName }) + task.libraryPath.convention(staticLibrary.linkTaskProvider.flatMap { layout.file(it.outputFile) }) + task.swiftLibraryName.convention(swiftApiLibraryName) + task.kotlinLibraryName.convention(kotlinStaticLibraryName) + task.swiftApiModuleName.convention(swiftApiModuleName) // Output task.packagePath.set(syntheticBuildRoot.flatMap { root -> @@ -205,7 +210,7 @@ private fun Project.registerSyntheticProjectBuild( task.description = "Builds $taskNamePrefix synthetic project" task.swiftApiModuleName.set(swiftApiModuleName) task.swiftLibraryName.set(swiftApiLibraryName) - task.syntheticProjectDirectory.set(syntheticBuildRoot) + task.syntheticProjectDirectory.convention(syntheticBuildRoot) } syntheticProjectBuild.dependsOn(packageGenerationTask) return syntheticProjectBuild @@ -222,6 +227,7 @@ private fun Project.registerCopyTask( task.group = BasePlugin.BUILD_GROUP task.description = "Copy $taskNamePrefix synthetic project intermediates" task.includeBridgeDirectory.convention(layout.file(packageGenerationTask.map { it.headerBridgeIncludePath })) + task.includeKotlinRuntimeDirectory.convention(layout.file(packageGenerationTask.map { it.kotlinRuntimeIncludePath })) task.kotlinLibraryPath.convention(layout.file(staticLibrary.linkTaskProvider.flatMap { it.outputFile })) task.syntheticLibraryPath.convention(layout.file(syntheticProjectBuild.flatMap { it.syntheticLibraryPath.mapToFile() })) task.syntheticInterfacesPath.convention(layout.file(syntheticProjectBuild.flatMap { it.syntheticInterfacesPath.mapToFile() })) diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/apple/swiftexport/SwiftExportAction.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/apple/swiftexport/SwiftExportAction.kt index d56f49dead5..5e3f18b0b18 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/apple/swiftexport/SwiftExportAction.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/apple/swiftexport/SwiftExportAction.kt @@ -7,7 +7,6 @@ package org.jetbrains.kotlin.gradle.plugin.mpp.apple.swiftexport import org.gradle.workers.WorkAction import org.jetbrains.kotlin.gradle.utils.getFile -import org.jetbrains.kotlin.konan.target.Distribution import org.jetbrains.kotlin.swiftexport.standalone.* import java.util.logging.Level import java.util.logging.Logger @@ -40,7 +39,7 @@ internal abstract class SwiftExportAction : WorkAction { SwiftExportConfig.BRIDGE_MODULE_NAME to parameters.bridgeModuleName.getOrElse(SwiftExportConfig.DEFAULT_BRIDGE_MODULE_NAME), ), Companion, - distribution = Distribution(parameters.konanDistribution.getFile().absolutePath), + distribution = parameters.konanDistribution.get(), ), output = SwiftExportOutput( swiftApi = parameters.swiftApiPath.getFile().toPath(), diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/apple/swiftexport/SwiftExportParameters.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/apple/swiftexport/SwiftExportParameters.kt index 867da744bea..176dff98e7d 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/apple/swiftexport/SwiftExportParameters.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/apple/swiftexport/SwiftExportParameters.kt @@ -10,6 +10,7 @@ import org.gradle.api.file.RegularFileProperty import org.gradle.api.provider.Property import org.gradle.api.tasks.* import org.gradle.workers.WorkParameters +import org.jetbrains.kotlin.konan.target.Distribution internal interface SwiftExportParameters : WorkParameters { @@ -19,9 +20,8 @@ internal interface SwiftExportParameters : WorkParameters { @get:Input val debugMode: Property - @get:InputDirectory - @get:PathSensitive(PathSensitivity.RELATIVE) - val konanDistribution: DirectoryProperty + @get:Input + val konanDistribution: Property @get:InputDirectory @get:PathSensitive(PathSensitivity.RELATIVE)