[Gradle] IdePlatformCinteropDependencyResolver: Retain cinterops for IDE in .gradle

^KT-56337 Verification Pending
This commit is contained in:
Sebastian Sellmair
2023-02-01 10:32:29 +01:00
committed by Space Team
parent ead2354fb7
commit fec9f9fe62
5 changed files with 71 additions and 12 deletions
@@ -11,17 +11,40 @@ import org.jetbrains.kotlin.gradle.idea.tcs.IdeaKotlinDependency
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
import org.jetbrains.kotlin.gradle.plugin.ide.IdeDependencyResolver
import org.jetbrains.kotlin.gradle.plugin.ide.IdeMultiplatformImport
import org.jetbrains.kotlin.gradle.plugin.mpp.kotlinCInteropLibraryDirectoryForIde
import org.jetbrains.kotlin.gradle.plugin.sources.DefaultKotlinSourceSet
import org.jetbrains.kotlin.gradle.targets.native.internal.getPlatformCinteropDependenciesOrEmpty
import org.jetbrains.kotlin.gradle.utils.crc32ChecksumString
import java.io.File
internal object IdePlatformCinteropDependencyResolver : IdeDependencyResolver, IdeDependencyResolver.WithBuildDependencies {
override fun resolve(sourceSet: KotlinSourceSet): Set<IdeaKotlinDependency> {
if (sourceSet !is DefaultKotlinSourceSet) return emptySet()
val project = sourceSet.project
val cinteropFiles = project.getPlatformCinteropDependenciesOrEmpty(sourceSet)
val cinteropFiles = project.getPlatformCinteropDependenciesOrEmpty(sourceSet).map { file ->
project.copyCInteropFileForIdeIfNecessary(file)
}
return project.resolveCInteropDependencies(cinteropFiles)
}
/**
* Copies the file into a directory specifically for the IDE, so it survives ./gradlew clean
*/
private fun Project.copyCInteropFileForIdeIfNecessary(file: File): File {
if (!file.exists()) return file
val newFileName = "${file.nameWithoutExtension}-${file.crc32ChecksumString()}.${file.extension}"
val outputFile = kotlinCInteropLibraryDirectoryForIde.resolve(newFileName)
/* Copy only if really necessary */
if (!outputFile.exists()) {
file.copyTo(outputFile)
}
return outputFile
}
override fun dependencies(project: Project): Iterable<Any> {
return project.kotlinExtension.sourceSets.mapNotNull { sourceSet ->
if (sourceSet !is DefaultKotlinSourceSet) return@mapNotNull null
@@ -6,15 +6,14 @@
package org.jetbrains.kotlin.gradle.plugin.ide.dependencyResolvers
import org.gradle.api.Project
import org.gradle.api.file.FileCollection
import org.jetbrains.kotlin.gradle.idea.tcs.*
import org.jetbrains.kotlin.gradle.idea.tcs.extras.klibExtra
import org.jetbrains.kotlin.gradle.plugin.ide.KlibExtra
import org.jetbrains.kotlin.konan.file.File
import org.jetbrains.kotlin.library.*
internal fun Project.resolveCInteropDependencies(cinteropFiles: FileCollection): Set<IdeaKotlinDependency> {
return cinteropFiles.files
internal fun Project.resolveCInteropDependencies(cinteropFiles: Iterable<java.io.File>): Set<IdeaKotlinDependency> {
return cinteropFiles
.filter { it.isDirectory || it.extension == KLIB_FILE_EXTENSION }
.mapNotNull { libraryFile -> this.createCinteropLibraryDependency(libraryFile) }
.toSet()
@@ -5,15 +5,13 @@
package org.jetbrains.kotlin.gradle.plugin.mpp
import org.jetbrains.kotlin.gradle.utils.checksumString
import org.jetbrains.kotlin.gradle.utils.copyPartially
import org.jetbrains.kotlin.gradle.utils.ensureValidZipDirectoryPath
import org.jetbrains.kotlin.gradle.utils.listDescendants
import java.io.Closeable
import java.io.File
import java.io.IOException
import java.nio.ByteBuffer
import java.util.*
import java.util.Base64.Encoder
import java.util.zip.CRC32
import java.util.zip.ZipEntry
import java.util.zip.ZipFile
@@ -192,10 +190,6 @@ internal class CompositeMetadataArtifactImpl(
*/
private class ArtifactFile(private val file: File) : Closeable {
companion object {
val checksumStringEncoder: Encoder = Base64.getUrlEncoder().withoutPadding()
}
private var isClosed = false
private val lazyZip = lazy {
@@ -212,7 +206,7 @@ internal class CompositeMetadataArtifactImpl(
val checksum: String by lazy(LazyThreadSafetyMode.NONE) {
val crc32 = CRC32()
entries.forEach { entry -> crc32.update(entry.crc.toInt()) }
checksumStringEncoder.encodeToString(ByteBuffer.allocate(4).putInt(crc32.value.toInt()).array())
checksumString(crc32.value.toInt())
}
/**
@@ -11,6 +11,7 @@ import org.jetbrains.kotlin.gradle.utils.compositeBuildRootProject
import java.io.File
private const val kotlinTransformedMetadataLibraries = "kotlinTransformedMetadataLibraries"
private const val kotlinCInteropLibraries = "kotlinCInteropLibraries"
private const val kotlinTransformedCInteropMetadataLibraries = "kotlinTransformedCInteropMetadataLibraries"
internal fun ProjectLayout.kotlinTransformedMetadataLibraryDirectoryForBuild(sourceSetName: String): File =
@@ -22,5 +23,8 @@ internal val Project.kotlinTransformedMetadataLibraryDirectoryForIde: File
internal fun ProjectLayout.kotlinTransformedCInteropMetadataLibraryDirectoryForBuild(sourceSetName: String): File =
buildDirectory.get().asFile.resolve(kotlinTransformedCInteropMetadataLibraries).resolve(sourceSetName)
internal val Project.kotlinCInteropLibraryDirectoryForIde: File
get() = compositeBuildRootProject.rootDir.resolve(".gradle").resolve("kotlin").resolve(kotlinCInteropLibraries)
internal val Project.kotlinTransformedCInteropMetadataLibraryDirectoryForIde: File
get() = compositeBuildRootProject.rootDir.resolve(".gradle").resolve("kotlin").resolve(kotlinTransformedCInteropMetadataLibraries)
@@ -0,0 +1,39 @@
/*
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.gradle.utils
import java.io.BufferedInputStream
import java.io.File
import java.nio.ByteBuffer
import java.util.*
import java.util.zip.CRC32
private val checksumStringEncoder: Base64.Encoder = Base64.getUrlEncoder().withoutPadding()
internal fun File.crc32Checksum(): Int {
val crc32 = CRC32()
val buffer = ByteArray(2048)
BufferedInputStream(inputStream()).use { fileStream ->
while (true) {
val read = fileStream.read(buffer)
if (read < 0) break
crc32.update(buffer, 0, read)
}
}
return crc32.value.toInt()
}
internal fun File.crc32ChecksumString(): String {
return checksumString(crc32Checksum())
}
internal fun checksumString(checksum: Int): String {
return checksumString(ByteBuffer.allocate(4).putInt(checksum).array())
}
internal fun checksumString(checksum: ByteArray): String {
return checksumStringEncoder.encodeToString(checksum)
}