DRAFT: rework unpacked klibs as secondary variant to use

KlibPackaging attribute. And simplify state to be only "default"
when klibs are always unpacked, and old way
when some klibs are packed and some unpacked.

^KT-65285
diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/artifacts/KlibPackaging.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/artifacts/KlibPackaging.kt
new file mode 100644
index 0000000..5a491a6
--- /dev/null
+++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/artifacts/KlibPackaging.kt
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2010-2024 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.artifacts
+
+import org.gradle.api.Named
+import org.gradle.api.Project
+import org.gradle.api.attributes.*
+import org.jetbrains.kotlin.gradle.plugin.KotlinNativeTargetConfigurator
+import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.Companion.kotlinPropertiesProvider
+import java.io.Serializable
+
+enum class KlibPackaging : Named, Serializable {
+    PACKED, UNPACKED;
+
+    override fun toString(): String = name
+    override fun getName(): String = name
+
+    internal class KotlinPackedKlibCompatibilityRule: AttributeCompatibilityRule<KlibPackaging> {
+        override fun execute(details: CompatibilityCheckDetails<KlibPackaging>) = details.compatible()
+    }
+
+    internal class KotlinUnpackedKlibDisambiguationRule: AttributeDisambiguationRule<KlibPackaging> {
+        override fun execute(details: MultipleCandidatesDetails<KlibPackaging>) {
+            val consumerValue = details.consumerValue
+            when {
+                consumerValue != null && consumerValue in details.candidateValues -> details.closestMatch(consumerValue)
+                UNPACKED in details.candidateValues -> details.closestMatch(UNPACKED)
+                PACKED in details.candidateValues -> details.closestMatch(PACKED)
+            }
+        }
+    }
+
+    companion object {
+        const val ATTRIBUTE_NAME = "org.jetbrains.kotlin.klib.packaging"
+
+        val attribute = Attribute.of(ATTRIBUTE_NAME, KlibPackaging::class.java)
+
+        internal fun setupAttributesMatchingStrategy(project: Project) {
+            val attributesSchema = project.dependencies.attributesSchema
+            attributesSchema.getMatchingStrategy(attribute).run {
+                compatibilityRules.add(KotlinPackedKlibCompatibilityRule::class.java)
+                disambiguationRules.add(KotlinUnpackedKlibDisambiguationRule::class.java)
+            }
+
+            // By default consider klib is packed
+            val artifactType = project.dependencies.artifactTypes.maybeCreate(KotlinNativeTargetConfigurator.NativeArtifactFormat.KLIB)
+            artifactType.attributes.attribute(attribute, PACKED)
+        }
+
+        internal fun setAttributeTo(project: Project, attributes: AttributeContainer) {
+            if (project.kotlinPropertiesProvider.enableUnpackedKlibs) {
+                attributes.attribute(attribute, UNPACKED)
+            } else {
+                attributes.attribute(attribute, PACKED)
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/artifacts/KotlinJsKlibArtifact.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/artifacts/KotlinJsKlibArtifact.kt
index d2cd2b54..9d96980 100644
--- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/artifacts/KotlinJsKlibArtifact.kt
+++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/artifacts/KotlinJsKlibArtifact.kt
@@ -7,11 +7,9 @@
 
 import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation
 import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
-import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.Companion.kotlinPropertiesProvider
 import org.jetbrains.kotlin.gradle.targets.js.ir.KLIB_TYPE
 import org.jetbrains.kotlin.gradle.targets.js.ir.KotlinJsIrTarget
 import org.jetbrains.kotlin.gradle.targets.js.ir.wasmDecamelizedDefaultNameOrNull
-import org.jetbrains.kotlin.gradle.utils.UNPACKED_KLIB_VARIANT_NAME
 import org.jetbrains.kotlin.gradle.utils.decamelize
 import org.jetbrains.kotlin.gradle.utils.libsDirectory
 
@@ -33,11 +31,4 @@
     }
 
     target.createPublishArtifact(jsKlibTask, KLIB_TYPE, apiElements, runtimeElements)
-
-    if (target.project.kotlinPropertiesProvider.enableUnpackedKlibs) {
-        apiElements.outgoing.variants.getByName(UNPACKED_KLIB_VARIANT_NAME)
-            .artifact(target.compilations.getByName(KotlinCompilation.MAIN_COMPILATION_NAME).compileTaskProvider.flatMap { it.destinationDirectory }) {
-                // ...
-            }
-    }
 }
diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/artifacts/KotlinNativeKlibArtifact.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/artifacts/KotlinNativeKlibArtifact.kt
index 17a8fac..cd5ef54 100644
--- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/artifacts/KotlinNativeKlibArtifact.kt
+++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/artifacts/KotlinNativeKlibArtifact.kt
@@ -25,7 +25,6 @@
 import org.jetbrains.kotlin.gradle.tasks.*
 import org.jetbrains.kotlin.gradle.tasks.dependsOn
 import org.jetbrains.kotlin.gradle.tasks.registerTask
-import org.jetbrains.kotlin.gradle.utils.UNPACKED_KLIB_VARIANT_NAME
 import org.jetbrains.kotlin.gradle.utils.libsDirectory
 import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName
 import org.jetbrains.kotlin.gradle.utils.setAttribute
@@ -108,13 +107,6 @@
         compilation.project.extensions.getByType(DefaultArtifactPublicationSet::class.java).addCandidate(klibArtifact)
         artifacts.add(klibArtifact)
         attributes.setAttribute(compilation.project.artifactTypeAttribute, NativeArtifactFormat.KLIB)
-
-        if (compilation.target.project.kotlinPropertiesProvider.enableUnpackedKlibs) {
-            outgoing.variants.getByName(UNPACKED_KLIB_VARIANT_NAME)
-                .artifact(klibProducingTask.flatMap { it.klibFile }) {
-                    it.builtBy(klibProducingTask)
-                }
-        }
     }
 }
 
diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/AbstractKotlinPlugin.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/AbstractKotlinPlugin.kt
index 1eb9c4f..591929a 100644
--- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/AbstractKotlinPlugin.kt
+++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/AbstractKotlinPlugin.kt
@@ -183,9 +183,10 @@
 
 
                 if (duplicateJavaSourceSetsAsKotlinSourceSets) {
-                    project.configurations
-                        .findByName(javaSourceSet.apiElementsConfigurationName)
-                        ?.addSecondaryOutgoingJvmClassesVariant(project, kotlinCompilation)
+// TODO(alakotka): verify if it is necessary
+//                    project.configurations
+//                        .findByName(javaSourceSet.apiElementsConfigurationName)
+//                        ?.addSecondaryOutgoingJvmClassesVariant(project, kotlinCompilation)
 
                     val kotlinSourceSet = project.kotlinExtension.sourceSets.maybeCreate(kotlinCompilation.name)
                     kotlinSourceSet.kotlin.source(javaSourceSet.java)
diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPluginWrapper.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPluginWrapper.kt
index 75fdd77..c0c5ceb 100644
--- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPluginWrapper.kt
+++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPluginWrapper.kt
@@ -49,8 +49,6 @@
 import org.jetbrains.kotlin.gradle.targets.metadata.isKotlinGranularMetadataEnabled
 import org.jetbrains.kotlin.gradle.targets.native.internal.CInteropCommonizerArtifactTypeAttribute
 import org.jetbrains.kotlin.gradle.targets.native.internal.CInteropKlibLibraryElements
-import org.jetbrains.kotlin.gradle.targets.native.internal.CInteropKlibLibraryElements.CINTEROP_KLIB
-import org.jetbrains.kotlin.gradle.targets.native.internal.CInteropKlibLibraryElements.UNPACKED_CINTEROP_KLIB
 import org.jetbrains.kotlin.gradle.targets.native.internal.CommonizerTargetAttribute
 import org.jetbrains.kotlin.gradle.targets.native.toolchain.KotlinNativeBundleArtifactFormat
 import org.jetbrains.kotlin.gradle.targets.native.toolchain.KotlinNativeBundleArtifactFormat.addKotlinNativeBundleConfiguration
@@ -59,7 +57,6 @@
 import org.jetbrains.kotlin.gradle.testing.internal.KotlinTestsRegistry
 import org.jetbrains.kotlin.gradle.utils.*
 import org.jetbrains.kotlin.tooling.core.KotlinToolingVersion
-import javax.inject.Inject
 import kotlin.reflect.KClass
 
 /**
@@ -216,45 +213,6 @@
         )
     }
 
-    private class KotlinUnpackedKlibCompatibilityRule : AttributeCompatibilityRule<LibraryElements> {
-        override fun execute(details: CompatibilityCheckDetails<LibraryElements>) = with(details) {
-            when {
-                consumerValue?.name == UNPACKED_KLIB_ATTRIBUTE && producerValue == null ->
-                    compatible()
-                (consumerValue?.name == UNPACKED_KLIB_ATTRIBUTE || consumerValue?.name == UNPACKED_CINTEROP_KLIB) && producerValue?.name == PACKED_KLIB_ATTRIBUTE ->
-                    compatible()
-                consumerValue?.name == UNPACKED_CINTEROP_KLIB && (producerValue?.name == CINTEROP_KLIB) ->
-                    compatible()
-                (consumerValue?.name == PACKED_KLIB_ATTRIBUTE || consumerValue?.name == UNPACKED_KLIB_ATTRIBUTE || consumerValue?.name == UNPACKED_CINTEROP_KLIB) && producerValue?.name == LibraryElements.JAR ->
-                    // metadata artifacts, like kotlin-stdlib-common
-                    compatible()
-                (consumerValue?.name == KotlinUsages.KOTLIN_RESOURCES_JS || consumerValue?.name == KotlinUsages.KOTLIN_RESOURCES) && (producerValue?.name == PACKED_KLIB_ATTRIBUTE || producerValue?.name == UNPACKED_KLIB_ATTRIBUTE) ->
-                    compatible()
-            }
-        }
-    }
-
-    private class KotlinUnpackedKlibDisambiguationRule @Inject constructor(
-        private val consumeUnpackedKlib: Boolean,
-    ) : AttributeDisambiguationRule<LibraryElements> {
-        override fun execute(details: MultipleCandidatesDetails<LibraryElements>) = with(details) {
-            val candidateNames = candidateValues.map { it?.name }.toSet()
-            when {
-                candidateNames.containsAll(setOf(UNPACKED_KLIB_ATTRIBUTE, PACKED_KLIB_ATTRIBUTE)) ->
-                    closestMatch(
-                        candidateValues.find { it.name == if (consumeUnpackedKlib) UNPACKED_KLIB_ATTRIBUTE else PACKED_KLIB_ATTRIBUTE }
-                            ?: error("Failed to find the proper candidate, seems like a bug")
-                    )
-                candidateNames.containsAll(setOf(UNPACKED_CINTEROP_KLIB, CINTEROP_KLIB)) ->
-                    closestMatch(
-                        candidateValues.find { it.name == if (consumeUnpackedKlib) UNPACKED_CINTEROP_KLIB else CINTEROP_KLIB }
-                            ?: error("Failed to find the proper candidate, seems like a bug")
-                    )
-            }
-        }
-
-    }
-
     protected fun setupAttributeMatchingStrategy(
         project: Project,
         isKotlinGranularMetadata: Boolean = project.isKotlinGranularMetadataEnabled,
@@ -270,12 +228,6 @@
         project.whenJsOrMppEnabled {
             KotlinJsCompilerAttribute.setupAttributesMatchingStrategy(project.dependencies.attributesSchema)
             KotlinWasmTargetAttribute.setupAttributesMatchingStrategy(project.dependencies.attributesSchema)
-            attribute(LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE).apply {
-                compatibilityRules.add(KotlinUnpackedKlibCompatibilityRule::class.java)
-                disambiguationRules.add(KotlinUnpackedKlibDisambiguationRule::class.java) {
-                    it.params(project.kotlinPropertiesProvider.enableUnpackedKlibs)
-                }
-            }
         }
 
         project.whenMppEnabled {
diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/ide/dependencyResolvers/IdePlatformCinteropDependencyResolver.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/ide/dependencyResolvers/IdePlatformCinteropDependencyResolver.kt
index 70eafbc..a8e82ae 100644
--- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/ide/dependencyResolvers/IdePlatformCinteropDependencyResolver.kt
+++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/ide/dependencyResolvers/IdePlatformCinteropDependencyResolver.kt
@@ -6,6 +6,7 @@
 package org.jetbrains.kotlin.gradle.plugin.ide.dependencyResolvers
 
 import org.gradle.api.Project
+import org.jetbrains.kotlin.backend.common.serialization.cityHash64String
 import org.jetbrains.kotlin.gradle.dsl.kotlinExtension
 import org.jetbrains.kotlin.gradle.idea.tcs.IdeaKotlinDependency
 import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
@@ -13,8 +14,9 @@
 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.CInteropOutput
 import org.jetbrains.kotlin.gradle.targets.native.internal.getPlatformCinteropDependenciesOrEmpty
-import org.jetbrains.kotlin.gradle.utils.crc32ChecksumString
+import org.jetbrains.kotlin.gradle.targets.native.internal.getPlatformCinteropOutputsOrEmpty
 import java.io.File
 
 internal object IdePlatformCinteropDependencyResolver : IdeDependencyResolver, IdeDependencyResolver.WithBuildDependencies {
@@ -22,8 +24,8 @@
         if (sourceSet !is DefaultKotlinSourceSet) return emptySet()
         val project = sourceSet.project
 
-        val cinteropFiles = project.getPlatformCinteropDependenciesOrEmpty(sourceSet).map { file ->
-            project.copyCInteropFileForIdeIfNecessary(file)
+        val cinteropFiles = project.getPlatformCinteropOutputsOrEmpty(sourceSet).map { cinteropOutput ->
+            project.copyCInteropFileForIdeIfNecessary(cinteropOutput)
         }
 
         return project.resolveCInteropDependencies(cinteropFiles)
@@ -32,14 +34,24 @@
     /**
      * 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)
+    private fun Project.copyCInteropFileForIdeIfNecessary(cinteropOutput: CInteropOutput): File {
+        val klibFile = cinteropOutput.klibLocation.singleFile
+        if (!klibFile.exists()) return klibFile
 
-        /* Copy only if really necessary */
-        if (!outputFile.exists()) {
-            file.copyTo(outputFile)
+        val relativeFilePath = with(cinteropOutput) {
+            val separator = File.separator
+            val projectDir = (buildPath + separator + projectPath).replace(":", separator).trimStart('/')
+            val hash = cinteropOutput.key.cityHash64String()
+            val relativeFilePath = "$projectDir$separator$targetName-$compilationName-$cinteropName-$hash"
+            if (klibFile.isFile) "$relativeFilePath.klib" else relativeFilePath
+        }
+
+        val outputFile = kotlinCInteropLibraryDirectoryForIde.resolve(relativeFilePath)
+        if (outputFile.exists()) project.delete(outputFile)
+
+        project.copy {
+            it.from(klibFile)
+            it.into(outputFile)
         }
 
         return outputFile
diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/CreateCInteropTasksSideEffect.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/CreateCInteropTasksSideEffect.kt
index 87da953..3f039e7 100644
--- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/CreateCInteropTasksSideEffect.kt
+++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/CreateCInteropTasksSideEffect.kt
@@ -16,6 +16,7 @@
 import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeCompilation
 import org.jetbrains.kotlin.gradle.plugin.mpp.enabledOnCurrentHostForBinariesCompilation
 import org.jetbrains.kotlin.gradle.plugin.mpp.isMain
+import org.jetbrains.kotlin.gradle.targets.UNPACKED_KLIB_VARIANT_NAME
 import org.jetbrains.kotlin.gradle.targets.native.internal.commonizeCInteropTask
 import org.jetbrains.kotlin.gradle.targets.native.internal.copyCommonizeCInteropForIdeTask
 import org.jetbrains.kotlin.gradle.targets.native.internal.createCInteropApiElementsKlibArtifact
@@ -67,12 +68,7 @@
             project.copyCommonizeCInteropForIdeTask()
         }
 
-        val interopOutput =
-            if (!project.kotlinPropertiesProvider.enableUnpackedKlibs) {
-                project.files(interopTask.map { it.outputFileProvider })
-            } else {
-                project.files(maybeCreateKlibPackingTask(compilation, interop.classifier, interopTask).map { it.archiveFile })
-            }
+        val interopOutput = project.files(interopTask.map { it.outputFileProvider })
         with(compilation) {
             compileDependencyFiles += interopOutput
             if (isMain()) {
@@ -86,6 +82,14 @@
                         classifier = interop.classifier,
                         klibProducingTask = interopTask,
                     )
+
+                    // TODO(alakotka): Add unpacked cinterop to secondary variant of KotlinNativeTarget.apiElements in [SecondaryVariantsForUnpackedCompilerOutputs]
+                    if (compilation.target.project.kotlinPropertiesProvider.enableUnpackedKlibs) {
+                        val apiElementsName = compilation.target.apiElementsConfigurationName
+                        val apiElements = project.configurations.getByName(apiElementsName)
+                        apiElements.outgoing.variants.getByName(UNPACKED_KLIB_VARIANT_NAME)
+                            .artifact(interopOutput) { it.builtBy(interopTask) }
+                    }
                 }
 
                 // We cannot add the interop library in an compilation output because in this case
diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/KotlinCreateNativeCompileTasksSideEffect.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/KotlinCreateNativeCompileTasksSideEffect.kt
index a9ba138..85c317a 100644
--- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/KotlinCreateNativeCompileTasksSideEffect.kt
+++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/KotlinCreateNativeCompileTasksSideEffect.kt
@@ -66,7 +66,7 @@
         task.enabledOnCurrentHostForKlibCompilationProperty.set(project.provider {
             task.konanTarget.enabledOnCurrentHostForKlibCompilation(project.kotlinPropertiesProvider)
         })
-        // for metadata tasks we should provide unpacked klib
+        // for metadata tasks we should always provide unpacked klib
         task.produceUnpackedKlib.set(isMetadataCompilation || project.kotlinPropertiesProvider.enableUnpackedKlibs)
     }
 
diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/factory/KotlinCompilationDependencyConfigurationsFactories.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/factory/KotlinCompilationDependencyConfigurationsFactories.kt
index 64515ab..a06b1f1 100644
--- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/factory/KotlinCompilationDependencyConfigurationsFactories.kt
+++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/factory/KotlinCompilationDependencyConfigurationsFactories.kt
@@ -7,7 +7,6 @@
 
 import org.gradle.api.artifacts.Configuration
 import org.gradle.api.attributes.Category
-import org.gradle.api.attributes.LibraryElements
 import org.gradle.api.attributes.Usage
 import org.jetbrains.kotlin.gradle.plugin.*
 import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.Companion.kotlinPropertiesProvider
@@ -19,6 +18,7 @@
 import org.jetbrains.kotlin.gradle.plugin.mpp.resources.KotlinTargetResourcesPublicationImpl.Companion.RESOURCES_PATH
 import org.jetbrains.kotlin.gradle.plugin.mpp.resources.resolve.KotlinTargetResourcesResolutionStrategy
 import org.jetbrains.kotlin.gradle.plugin.sources.METADATA_CONFIGURATION_NAME_SUFFIX
+import org.jetbrains.kotlin.gradle.artifacts.KlibPackaging
 import org.jetbrains.kotlin.gradle.utils.*
 
 internal sealed class DefaultKotlinCompilationDependencyConfigurationsFactory :
@@ -173,11 +173,7 @@
                 attributes.setAttribute(Category.CATEGORY_ATTRIBUTE, target.project.categoryByName(Category.LIBRARY))
             }
             if (target.producesPlatformKlib) {
-                if (target.project.kotlinPropertiesProvider.enableUnpackedKlibs) {
-                    attributes.setAttribute(LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, target.project.unpackedKlibLibraryElements())
-                } else {
-                    attributes.setAttribute(LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, target.project.packedKlibLibraryElements())
-                }
+                KlibPackaging.setAttributeTo(target.project, attributes)
             }
             description = "Compile classpath for $compilationCoordinates."
         }
diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/registerKotlinPluginExtensions.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/registerKotlinPluginExtensions.kt
index c3c460c..fece674 100644
--- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/registerKotlinPluginExtensions.kt
+++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/registerKotlinPluginExtensions.kt
@@ -102,7 +102,7 @@
         register(project, ConfigureFrameworkExportSideEffect)
         register(project, SetupCInteropApiElementsConfigurationSideEffect)
         register(project, SetupEmbedAndSignAppleFrameworkTaskSideEffect)
-        register(project, MaybeAddWorkaroundForSecondaryVariantsBug)
+        register(project, SecondaryVariantsForUnpackedCompilerOutputs)
     }
 
     KotlinCompilationSideEffect.extensionPoint.apply {
diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/CreateTargetConfigurationsSideEffect.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/CreateTargetConfigurationsSideEffect.kt
index 9d31ee7..a56dfba 100644
--- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/CreateTargetConfigurationsSideEffect.kt
+++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/CreateTargetConfigurationsSideEffect.kt
@@ -16,8 +16,6 @@
 import org.jetbrains.kotlin.gradle.plugin.mpp.isSourcesPublishableFuture
 import org.jetbrains.kotlin.gradle.plugin.mpp.resources.resourcesPublicationExtension
 import org.jetbrains.kotlin.gradle.targets.js.ir.KotlinJsIrTarget
-import org.jetbrains.kotlin.gradle.utils.*
-import org.jetbrains.kotlin.gradle.utils.addSecondaryOutgoingJvmClassesVariant
 import org.jetbrains.kotlin.gradle.utils.maybeCreateConsumable
 import org.jetbrains.kotlin.gradle.utils.maybeCreateDependencyScope
 import org.jetbrains.kotlin.gradle.utils.setAttribute
@@ -51,16 +49,6 @@
             runtimeConfiguration?.let { extendsFrom(it) }
         }
         usesPlatformOf(target)
-        if (target.platformType == KotlinPlatformType.jvm) {
-            addSecondaryOutgoingJvmClassesVariant(
-                project,
-                mainCompilation,
-                addArtifactsToVariantCreatedByJavaLibraryPlugin = true
-            )
-        }
-        if (target.producesPlatformKlib && target.project.kotlinPropertiesProvider.enableUnpackedKlibs) {
-            addUnpackedKlibSecondaryOutgoingVariant(project)
-        }
     }
 
     @Suppress("TYPEALIAS_EXPANSION_DEPRECATION")
diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/SecondaryVariantsForUnpackedCompilerOutputs.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/SecondaryVariantsForUnpackedCompilerOutputs.kt
new file mode 100644
index 0000000..227f7ef
--- /dev/null
+++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/SecondaryVariantsForUnpackedCompilerOutputs.kt
@@ -0,0 +1,91 @@
+/*
+ * Copyright 2010-2024 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.targets
+
+import org.gradle.api.artifacts.type.ArtifactTypeDefinition
+import org.gradle.api.attributes.LibraryElements
+import org.jetbrains.kotlin.gradle.artifacts.KlibPackaging
+import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation.Companion.MAIN_COMPILATION_NAME
+import org.jetbrains.kotlin.gradle.plugin.KotlinPluginLifecycle
+import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.Companion.kotlinPropertiesProvider
+import org.jetbrains.kotlin.gradle.plugin.launch
+import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget
+import org.jetbrains.kotlin.gradle.targets.js.ir.KotlinJsIrTarget
+import org.jetbrains.kotlin.gradle.targets.jvm.KotlinJvmTarget
+import org.jetbrains.kotlin.gradle.tasks.configuration.BaseKotlinCompileConfig.Companion.CLASSES_SECONDARY_VARIANT_NAME
+import org.jetbrains.kotlin.gradle.utils.copyAttributesTo
+import org.jetbrains.kotlin.gradle.utils.named
+import org.jetbrains.kotlin.gradle.utils.whenEvaluated
+
+internal val SecondaryVariantsForUnpackedCompilerOutputs = KotlinTargetSideEffect { target ->
+    when (target) {
+        is KotlinJvmTarget -> target.classesAsSecondaryVariant()
+        is KotlinNativeTarget -> target.nativeKlibsAsSecondaryVariants()
+        is KotlinJsIrTarget -> target.jsKlibsAsSecondaryVariants()
+    }
+}
+
+private fun KotlinJvmTarget.classesAsSecondaryVariant() {
+    if (!project.kotlinPropertiesProvider.addSecondaryClassesVariant) return
+
+    val configuration = project.configurations.getByName(apiElementsConfigurationName)
+    val mainCompilation = compilations.getByName(MAIN_COMPILATION_NAME)
+
+    val apiClassesVariant = configuration.outgoing.variants.maybeCreate(CLASSES_SECONDARY_VARIANT_NAME)
+    apiClassesVariant.attributes.attribute(
+        LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE,
+        project.objects.named(LibraryElements.CLASSES)
+    )
+
+    project.whenEvaluated {
+        // Java-library plugin already has done all required work here
+        if (project.plugins.hasPlugin("java-library")) return@whenEvaluated
+
+        mainCompilation.output.classesDirs.files.forEach { classesDir ->
+            apiClassesVariant.artifact(classesDir) {
+                it.type = ArtifactTypeDefinition.JVM_CLASS_DIRECTORY
+                it.builtBy(mainCompilation.output.classesDirs.buildDependencies)
+            }
+        }
+    }
+}
+
+private fun KotlinNativeTarget.nativeKlibsAsSecondaryVariants() {
+    if (!project.kotlinPropertiesProvider.enableUnpackedKlibs) return
+
+    val configuration = project.configurations.getByName(apiElementsConfigurationName)
+    val mainCompilation = compilations.getByName(MAIN_COMPILATION_NAME)
+
+    val unpackedKlibVariant = configuration.outgoing.variants.maybeCreate(UNPACKED_KLIB_VARIANT_NAME)
+    project.launch {
+        KotlinPluginLifecycle.Stage.AfterFinaliseDsl
+        unpackedKlibVariant.attributes {
+            configuration.copyAttributesTo(project, it)
+            it.attribute(KlibPackaging.attribute, KlibPackaging.UNPACKED)
+        }
+    }
+    unpackedKlibVariant.artifact(mainCompilation.compileTaskProvider.map { it.outputFile.get() })
+}
+
+private fun KotlinJsIrTarget.jsKlibsAsSecondaryVariants() {
+    if (!project.kotlinPropertiesProvider.enableUnpackedKlibs) return
+
+    val configuration = project.configurations.getByName(apiElementsConfigurationName)
+    val mainCompilation = compilations.getByName(MAIN_COMPILATION_NAME)
+
+    val unpackedKlibVariant = configuration.outgoing.variants.maybeCreate(UNPACKED_KLIB_VARIANT_NAME)
+    project.launch {
+        KotlinPluginLifecycle.Stage.AfterFinaliseDsl
+        unpackedKlibVariant.attributes {
+            configuration.copyAttributesTo(project, it)
+            it.attribute(KlibPackaging.attribute, KlibPackaging.UNPACKED)
+        }
+    }
+    unpackedKlibVariant.artifact(mainCompilation.compileTaskProvider.flatMap { it.destinationDirectory })
+}
+
+
+internal const val UNPACKED_KLIB_VARIANT_NAME = "unpacked-klib"
\ No newline at end of file
diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/internal/CInteropConfigurations.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/internal/CInteropConfigurations.kt
index c1679dd..d548566 100644
--- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/internal/CInteropConfigurations.kt
+++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/internal/CInteropConfigurations.kt
@@ -9,20 +9,18 @@
 import org.gradle.api.artifacts.Configuration
 import org.gradle.api.attributes.*
 import org.gradle.api.tasks.TaskProvider
-import org.jetbrains.kotlin.gradle.artifacts.maybeCreateKlibPackingTask
 import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation.Companion.MAIN_COMPILATION_NAME
 import org.jetbrains.kotlin.gradle.plugin.KotlinNativeTargetConfigurator.NativeArtifactFormat
 import org.jetbrains.kotlin.gradle.plugin.KotlinPluginLifecycle.Stage.AfterFinaliseDsl
 import org.jetbrains.kotlin.gradle.plugin.KotlinTarget
-import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.Companion.kotlinPropertiesProvider
 import org.jetbrains.kotlin.gradle.plugin.categoryByName
 import org.jetbrains.kotlin.gradle.plugin.internal.artifactTypeAttribute
 import org.jetbrains.kotlin.gradle.plugin.launchInStage
 import org.jetbrains.kotlin.gradle.plugin.mpp.*
 import org.jetbrains.kotlin.gradle.plugin.usesPlatformOf
+import org.jetbrains.kotlin.gradle.artifacts.KlibPackaging
 import org.jetbrains.kotlin.gradle.targets.KotlinTargetSideEffect
 import org.jetbrains.kotlin.gradle.targets.native.internal.CInteropKlibLibraryElements.cinteropKlibLibraryElements
-import org.jetbrains.kotlin.gradle.targets.native.internal.CInteropKlibLibraryElements.unpackedCinteropKlibLibraryElements
 import org.jetbrains.kotlin.gradle.tasks.CInteropProcess
 import org.jetbrains.kotlin.gradle.utils.*
 import org.jetbrains.kotlin.gradle.utils.createConsumable
@@ -34,25 +32,12 @@
     interopTask: TaskProvider<out CInteropProcess>,
 ) {
     val project = compilation.project
-    val configurationName = cInteropApiElementsConfigurationName(compilation.target)
-    val configuration = project.configurations.getByName(configurationName)
-    val (packTask, packedArtifactFile) = if (project.kotlinPropertiesProvider.enableUnpackedKlibs) {
-        val packTask = maybeCreateKlibPackingTask(compilation, settings.classifier, interopTask)
-        packTask to packTask.map { it.archiveFile.get().asFile }
-    } else {
-        interopTask to interopTask.flatMap { it.klibFile }
-    }
-    project.artifacts.add(configuration.name, packedArtifactFile) { artifact ->
+    val configuration = project.locateOrCreateCInteropApiElementsConfiguration(compilation.target)
+    project.artifacts.add(configuration.name, interopTask.flatMap { it.outputFileProvider }) { artifact ->
         artifact.extension = "klib"
-        artifact.type = "klib"
+        artifact.type = NativeArtifactFormat.KLIB
         artifact.classifier = settings.classifier
-        artifact.builtBy(packTask)
-    }
-    if (compilation.project.kotlinPropertiesProvider.enableUnpackedKlibs) {
-        configuration.outgoing.variants.getByName(UNPACKED_KLIB_VARIANT_NAME)
-            .artifact(interopTask.flatMap { it.klibFile }) {
-                it.builtBy(interopTask)
-            }
+        artifact.builtBy(interopTask)
     }
 }
 
@@ -70,17 +55,7 @@
 
         /* Deferring attributes to wait for compilation.attributes to be configured  by user*/
         launchInStage(AfterFinaliseDsl) {
-            usesPlatformOf(compilation.target)
-            compilation.copyAttributesTo(project, dest = attributes)
-            attributes.setAttribute(
-                LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, if (project.kotlinPropertiesProvider.enableUnpackedKlibs) {
-                    unpackedCinteropKlibLibraryElements()
-                } else {
-                    cinteropKlibLibraryElements()
-                }
-            )
-            attributes.setAttribute(Usage.USAGE_ATTRIBUTE, objects.named(KotlinUsages.KOTLIN_CINTEROP))
-            attributes.setAttribute(Category.CATEGORY_ATTRIBUTE, project.categoryByName(Category.LIBRARY))
+            configureCinteropAttributes(compilation.target)
             description = "CInterop dependencies for compilation '${compilation.name}')."
         }
     }
@@ -93,37 +68,14 @@
     target.project.locateOrCreateCInteropApiElementsConfiguration(target)
 }
 
-// Workaround for https://github.com/gradle/gradle/issues/29630
-internal val MaybeAddWorkaroundForSecondaryVariantsBug = KotlinTargetSideEffect<KotlinNativeTarget> { target ->
-    // at this moment, there's no version with fix of the bug, so "maybe" refers to the future
-    target.project.artifacts.add(
-        cInteropApiElementsConfigurationName(target),
-        target.project.file("non-existing-file-workaround-for-gradle-29630.txt")
-    ) { fakeArtifact ->
-        fakeArtifact.extension = "txt"
-        fakeArtifact.type = "workaround-for-gradle-29630"
-    }
-}
-
 internal fun Project.locateOrCreateCInteropApiElementsConfiguration(target: KotlinTarget): Configuration {
     val configurationName = cInteropApiElementsConfigurationName(target)
     configurations.findConsumable(configurationName)?.let { return it }
 
     return configurations.createConsumable(configurationName).apply {
-        if (target.project.kotlinPropertiesProvider.enableUnpackedKlibs) {
-            addUnpackedKlibSecondaryOutgoingVariant(
-                project,
-                project.cinteropKlibLibraryElements(),
-                project.unpackedCinteropKlibLibraryElements()
-            )
-        }
         /* Deferring attributes to wait for target.attributes to be configured by user */
         launchInStage(AfterFinaliseDsl) {
-            usesPlatformOf(target)
-            target.copyAttributesTo(project, dest = attributes)
-            attributes.setAttribute(LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, cinteropKlibLibraryElements())
-            attributes.setAttribute(Usage.USAGE_ATTRIBUTE, objects.named(KotlinUsages.KOTLIN_CINTEROP))
-            attributes.setAttribute(Category.CATEGORY_ATTRIBUTE, project.categoryByName(Category.LIBRARY))
+            configureCinteropAttributes(target)
             attributes.setAttribute(artifactTypeAttribute, NativeArtifactFormat.KLIB)
 
             /* Expose api dependencies */
@@ -134,18 +86,25 @@
     }
 }
 
+private fun Configuration.configureCinteropAttributes(target: KotlinTarget) {
+    val project = target.project
+    usesPlatformOf(target)
+    target.copyAttributesTo(project, dest = attributes)
+    attributes.setAttribute(LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, project.cinteropKlibLibraryElements())
+    KlibPackaging.setAttributeTo(project, attributes)
+    attributes.setAttribute(Usage.USAGE_ATTRIBUTE, project.objects.named(KotlinUsages.KOTLIN_CINTEROP))
+    attributes.setAttribute(Category.CATEGORY_ATTRIBUTE, project.categoryByName(Category.LIBRARY))
+}
+
 private fun cInteropApiElementsConfigurationName(target: KotlinTarget): String {
     return target.name + "CInteropApiElements"
 }
 
 internal object CInteropKlibLibraryElements {
     const val CINTEROP_KLIB = "cinterop-klib"
-    const val UNPACKED_CINTEROP_KLIB = "unpacked-cinterop-klib"
 
     fun Project.cinteropKlibLibraryElements(): LibraryElements = objects.named(LibraryElements::class.java, CINTEROP_KLIB)
 
-    fun Project.unpackedCinteropKlibLibraryElements(): LibraryElements = objects.named(LibraryElements::class.java, UNPACKED_CINTEROP_KLIB)
-
     fun setupAttributesMatchingStrategy(schema: AttributesSchema) {
         schema.attribute(LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE) { strategy ->
             strategy.compatibilityRules.add(CInteropLibraryElementsCompatibilityRule::class.java)
diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/internal/CInteropPropagatedDependencies.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/internal/CInteropPropagatedDependencies.kt
index 800fa83..4b8b87a 100644
--- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/internal/CInteropPropagatedDependencies.kt
+++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/internal/CInteropPropagatedDependencies.kt
@@ -7,7 +7,8 @@
 
 import org.gradle.api.Project
 import org.gradle.api.file.FileCollection
-import org.jetbrains.kotlin.gradle.artifacts.maybeCreateKlibPackingTask
+import org.gradle.api.provider.Provider
+import org.gradle.api.tasks.TaskDependency
 import org.jetbrains.kotlin.gradle.dsl.multiplatformExtensionOrNull
 import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.Companion.kotlinPropertiesProvider
 import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinMetadataCompilation
@@ -17,6 +18,8 @@
 import org.jetbrains.kotlin.gradle.plugin.sources.DefaultKotlinSourceSet
 import org.jetbrains.kotlin.gradle.plugin.sources.internal
 import org.jetbrains.kotlin.gradle.tasks.CInteropProcess
+import org.jetbrains.kotlin.gradle.utils.buildPathCompat
+import org.jetbrains.kotlin.gradle.utils.currentBuildId
 import org.jetbrains.kotlin.gradle.utils.filesProvider
 import java.io.File
 
@@ -67,51 +70,65 @@
 internal fun Project.getPlatformCinteropDependenciesOrEmpty(
     sourceSet: DefaultKotlinSourceSet,
     compilationFilter: (KotlinNativeCompilation) -> Boolean = { true },
-): FileCollection {
-    return filesProvider files@{
-        /*
-        compatibility metadata variant will still register
-        a 'KotlinMetadataCompilation for 'commonMain' which is irrelevant here
-        */
-        val compilations = sourceSet.internal.compilations
-            .filter { compilation -> compilation !is KotlinMetadataCompilation }
+): FileCollection = getPlatformCinteropOutputsOrEmpty(sourceSet, compilationFilter).asFileCollection(this)
 
-        /* Participating in multiple compilations? -> can't propagate -> should be commonized */
-        val compilation = compilations.singleOrNull() as? KotlinNativeCompilation ?: return@files emptySet<File>()
+internal fun Project.getPlatformCinteropOutputsOrEmpty(
+    sourceSet: DefaultKotlinSourceSet,
+    compilationFilter: (KotlinNativeCompilation) -> Boolean = { true },
+): List<CInteropOutput> {
+    /*
+    compatibility metadata variant will still register
+    a 'KotlinMetadataCompilation for 'commonMain' which is irrelevant here
+    */
+    val compilations = sourceSet.internal.compilations
+        .filter { compilation -> compilation !is KotlinMetadataCompilation }
 
-        /* Apple-specific cinterops can't be produced on non-MacOs machines, so just return an empty dependencies collection */
-        if (!compilation.target.konanTarget.enabledOnCurrentHostForKlibCompilation(kotlinPropertiesProvider)) return@files emptySet<File>()
+    /* Participating in multiple compilations? -> can't propagate -> should be commonized */
+    val compilation = compilations.singleOrNull() as? KotlinNativeCompilation ?: return emptyList()
 
-        (compilation.associatedCompilations + compilation)
-            .filterIsInstance<KotlinNativeCompilation>()
-            .filter(compilationFilter)
-            .map { relevantCompilation -> getAllCInteropOutputFiles(relevantCompilation) }
-    }
+    /* Apple-specific cinterops can't be produced on non-MacOs machines, so just return an empty dependencies collection */
+    if (!compilation.target.konanTarget.enabledOnCurrentHostForKlibCompilation(kotlinPropertiesProvider)) return emptyList()
+
+    return (compilation.associatedCompilations + compilation)
+        .filterIsInstance<KotlinNativeCompilation>()
+        .filter(compilationFilter)
+        .flatMap { relevantCompilation -> getAllCInteropOutputs(relevantCompilation) }
+        .distinctBy { it.key }
 }
 
-private fun Project.getPropagatedCInteropDependenciesOrEmpty(compilation: KotlinSharedNativeCompilation) = filesProvider files@{
+internal fun Project.getPropagatedCInteropDependenciesOrEmpty(compilation: KotlinSharedNativeCompilation): FileCollection {
     val compilations = compilation.getImplicitlyDependingNativeCompilations()
-    val platformCompilation = compilations.singleOrNull() ?: return@files emptySet<File>()
-    getAllCInteropOutputFiles(platformCompilation)
+    val platformCompilation = compilations.singleOrNull() ?: return files()
+    return getAllCInteropOutputs(platformCompilation).asFileCollection(this)
 }
 
-private fun Project.getAllCInteropOutputFiles(compilation: KotlinNativeCompilation): FileCollection {
-    val cinteropTasks = compilation.cinterops.map { interop -> interop.interopProcessingTaskName }
-        .mapNotNull { taskName -> tasks.findByName(taskName) as? CInteropProcess }
+private fun Project.getAllCInteropOutputs(compilation: KotlinNativeCompilation): List<CInteropOutput> {
+    return compilation.cinterops.mapNotNull { interop ->
+        val interopTask = tasks.findByName(interop.interopProcessingTaskName)
+        if (interopTask !is CInteropProcess) return@mapNotNull null
 
-    if (project.kotlinPropertiesProvider.enableUnpackedKlibs) {
-        // this part of import isn't ready for working with unpacked klibs
-        return project.filesProvider {
-            cinteropTasks.map { interopTask ->
-                maybeCreateKlibPackingTask(
-                    compilation,
-                    interopTask.settings.classifier,
-                    interopTask.outputFileProvider,
-                    interopTask
-                )
-            }
-        }
+        CInteropOutput(
+            buildPath = compilation.project.currentBuildId().buildPathCompat,
+            projectPath = compilation.project.path,
+            targetName = compilation.target.name,
+            compilationName = compilation.name,
+            cinteropName = interop.name,
+            klibLocation = filesProvider(interopTask) { interopTask.outputFileProvider },
+        )
     }
-    return project.filesProvider { cinteropTasks.map { it.outputFileProvider } }
-        .builtBy(*cinteropTasks.toTypedArray())
 }
+
+internal class CInteropOutput(
+    val buildPath: String,
+    val projectPath: String,
+    val targetName: String,
+    val compilationName: String,
+    val cinteropName: String,
+    val klibLocation: FileCollection,
+) {
+    val key: String get() = "$buildPath/$projectPath/$targetName/$compilationName/$cinteropName"
+}
+
+private fun List<CInteropOutput>.asFileCollection(project: Project) = project.filesProvider {
+    map { it.klibLocation }
+}
\ No newline at end of file
diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/utils/configurations.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/utils/configurations.kt
index d2ae6fb..569e325 100644
--- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/utils/configurations.kt
+++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/utils/configurations.kt
@@ -15,6 +15,7 @@
 import org.gradle.util.GradleVersion
 import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation
 import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.Companion.kotlinPropertiesProvider
+import org.jetbrains.kotlin.gradle.plugin.launch
 import org.jetbrains.kotlin.gradle.tasks.configuration.BaseKotlinCompileConfig.Companion.CLASSES_SECONDARY_VARIANT_NAME
 
 const val COMPILE_ONLY = "compileOnly"
@@ -104,50 +105,4 @@
 internal fun ConfigurationContainer.maybeCreateDependencyScope(
     name: String,
     configurationOnCreate: Configuration.() -> Unit = {},
-): Configuration = findDependencyScope(name) ?: createDependencyScope(name, configurationOnCreate).get()
-
-internal fun Configuration.addSecondaryOutgoingJvmClassesVariant(
-    project: Project,
-    kotlinCompilation: KotlinCompilation<*>,
-    addArtifactsToVariantCreatedByJavaLibraryPlugin: Boolean = false,
-) {
-    if (!project.kotlinPropertiesProvider.addSecondaryClassesVariant) return
-
-    val apiClassesVariant = outgoing.variants.maybeCreate(CLASSES_SECONDARY_VARIANT_NAME)
-    apiClassesVariant.attributes.attribute(
-        LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE,
-        project.objects.named(LibraryElements.CLASSES)
-    )
-
-    project.whenEvaluated {
-        // Java-library plugin already has done all required work here
-        if (!addArtifactsToVariantCreatedByJavaLibraryPlugin && project.plugins.hasPlugin("java-library")) return@whenEvaluated
-
-        kotlinCompilation.output.classesDirs.files.forEach { classesDir ->
-            apiClassesVariant.artifact(classesDir) {
-                it.type = ArtifactTypeDefinition.JVM_CLASS_DIRECTORY
-                it.builtBy(kotlinCompilation.output.classesDirs.buildDependencies)
-            }
-        }
-    }
-}
-
-internal const val UNPACKED_KLIB_VARIANT_NAME = "unpacked-klib"
-
-internal const val PACKED_KLIB_ATTRIBUTE = "packed-klib"
-internal const val UNPACKED_KLIB_ATTRIBUTE = "unpacked-klib"
-
-internal fun Project.packedKlibLibraryElements() = objects.named(LibraryElements::class.java, PACKED_KLIB_ATTRIBUTE)
-
-internal fun Project.unpackedKlibLibraryElements() = objects.named(LibraryElements::class.java, UNPACKED_KLIB_ATTRIBUTE)
-
-internal fun Configuration.addUnpackedKlibSecondaryOutgoingVariant(
-    project: Project,
-    primaryVariantAttribute: LibraryElements = project.packedKlibLibraryElements(),
-    secondaryVariantAttribute: LibraryElements = project.unpackedKlibLibraryElements(),
-) {
-    attributes.setAttribute(LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, primaryVariantAttribute)
-    outgoing.variants.create(UNPACKED_KLIB_VARIANT_NAME) { variant ->
-        variant.attributes.setAttribute(LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, secondaryVariantAttribute)
-    }
-}
+): Configuration = findDependencyScope(name) ?: createDependencyScope(name, configurationOnCreate).get()
\ No newline at end of file