[K/N][build] Move nativeLibs to configurations

^KT-71270
diff --git a/kotlin-native/Interop/Indexer/build.gradle.kts b/kotlin-native/Interop/Indexer/build.gradle.kts
index 9acac45..beaea31 100644
--- a/kotlin-native/Interop/Indexer/build.gradle.kts
+++ b/kotlin-native/Interop/Indexer/build.gradle.kts
@@ -3,6 +3,8 @@
  * that can be found in the LICENSE file.
  */
 
+import org.jetbrains.kotlin.cpp.CppConsumerPlugin
+import org.jetbrains.kotlin.cpp.CppUsage
 import org.jetbrains.kotlin.gradle.tasks.KotlinJvmCompile
 import org.jetbrains.kotlin.konan.target.*
 
@@ -11,6 +13,17 @@
     id("native-dependencies")
 }
 
+apply<CppConsumerPlugin>()
+
+val cppRuntimeOnly by configurations.creating {
+    isCanBeConsumed = false
+    isCanBeResolved = true
+    attributes {
+        attribute(CppUsage.USAGE_ATTRIBUTE, objects.named(CppUsage.LIBRARY_RUNTIME))
+        attribute(TargetWithSanitizer.TARGET_ATTRIBUTE, TargetWithSanitizer.host)
+    }
+}
+
 dependencies {
     api(project(":kotlin-stdlib"))
     api(project(":kotlin-native:Interop:Runtime"))
@@ -19,6 +32,9 @@
 
     testImplementation(kotlin("test-junit"))
     testImplementation(project(":compiler:util"))
+
+    cppRuntimeOnly(project(":kotlin-native:libclangInterop"))
+    cppRuntimeOnly(project(":kotlin-native:Interop:Runtime"))
 }
 
 tasks.withType<KotlinJvmCompile>().configureEach {
@@ -40,14 +56,10 @@
 }
 
 tasks.withType<Test>().configureEach {
-    val projectsWithNativeLibs = listOf(
-            project(":kotlin-native:libclangInterop"),
-            project(":kotlin-native:Interop:Runtime")
-    )
-    dependsOn(projectsWithNativeLibs.map { "${it.path}:nativelibs" })
+    inputs.files(cppRuntimeOnly)
     dependsOn(nativeDependencies.llvmDependency)
-    systemProperty("java.library.path", projectsWithNativeLibs.joinToString(File.pathSeparator) {
-        it.layout.buildDirectory.dir("nativelibs").get().asFile.absolutePath
+    systemProperty("java.library.path", cppRuntimeOnly.elements.map { elements ->
+        elements.joinToString(File.pathSeparator) { it.asFile.parentFile.absolutePath }
     })
 
     systemProperty("kotlin.native.llvm.libclang", "${nativeDependencies.llvmPath}/" + if (HostManager.hostIsMingw) {
diff --git a/kotlin-native/Interop/Runtime/build.gradle.kts b/kotlin-native/Interop/Runtime/build.gradle.kts
index b50a9f7..5046dbf 100644
--- a/kotlin-native/Interop/Runtime/build.gradle.kts
+++ b/kotlin-native/Interop/Runtime/build.gradle.kts
@@ -3,10 +3,12 @@
  * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
  */
 
-import org.jetbrains.kotlin.tools.lib
+import org.gradle.kotlin.dsl.named
 import org.jetbrains.kotlin.tools.solib
 import org.jetbrains.kotlin.*
+import org.jetbrains.kotlin.cpp.CppUsage
 import org.jetbrains.kotlin.konan.target.TargetWithSanitizer
+import org.jetbrains.kotlin.tools.ToolExecutionTask
 
 plugins {
     id("org.jetbrains.kotlin.jvm")
@@ -14,6 +16,21 @@
     id("native-dependencies")
 }
 
+val library = solib("callbacks")
+
+val cppLink by configurations.creating {
+    isCanBeConsumed = false
+    isCanBeResolved = true
+    attributes {
+        attribute(CppUsage.USAGE_ATTRIBUTE, objects.named(CppUsage.LIBRARY_LINK))
+        attribute(TargetWithSanitizer.TARGET_ATTRIBUTE, TargetWithSanitizer.host)
+    }
+}
+
+dependencies {
+    cppLink(project(":kotlin-native:libclangext"))
+}
+
 native {
     val isWindows = PlatformInfo.isWindows()
     val obj = if (isWindows) "obj" else "o"
@@ -33,7 +50,7 @@
     }
     val objSet = sourceSets["callbacks"]!!.transform(".c" to ".$obj")
 
-    target(solib("callbacks"), objSet) {
+    target(library, objSet) {
         tool(*hostPlatform.clangForJni.clangCXX("").toTypedArray())
         flags("-shared",
               "-o",ruleOut(), *ruleInAll(),
@@ -42,7 +59,7 @@
               "-lclangext")
     }
     tasks.named(solib("callbacks")).configure {
-        dependsOn(":kotlin-native:libclangext:${lib("clangext")}")
+        inputs.files(cppLink)
         dependsOn(nativeDependencies.libffiDependency)
     }
 }
@@ -81,23 +98,34 @@
     }
 }
 
-val nativelibs by tasks.registering(Sync::class) {
-    val callbacksSolib = solib("callbacks")
-    dependsOn(callbacksSolib)
-
-    from(layout.buildDirectory.dir(callbacksSolib))
-    into(layout.buildDirectory.dir("nativelibs"))
-}
-
-val nativeLibs by configurations.creating {
+val cppApiElements by configurations.creating {
     isCanBeConsumed = true
     isCanBeResolved = false
     attributes {
+        attribute(CppUsage.USAGE_ATTRIBUTE, objects.named(CppUsage.API))
         attribute(ArtifactTypeDefinition.ARTIFACT_TYPE_ATTRIBUTE, ArtifactTypeDefinition.DIRECTORY_TYPE)
+    }
+}
+
+val cppLinkElements by configurations.creating {
+    isCanBeConsumed = true
+    isCanBeResolved = false
+    attributes {
+        attribute(CppUsage.USAGE_ATTRIBUTE, objects.named(CppUsage.LIBRARY_LINK))
+        attribute(TargetWithSanitizer.TARGET_ATTRIBUTE, TargetWithSanitizer.host)
+    }
+}
+
+val cppRuntimeElements by configurations.creating {
+    isCanBeConsumed = true
+    isCanBeResolved = false
+    attributes {
+        attribute(CppUsage.USAGE_ATTRIBUTE, objects.named(CppUsage.LIBRARY_RUNTIME))
         attribute(TargetWithSanitizer.TARGET_ATTRIBUTE, TargetWithSanitizer.host)
     }
 }
 
 artifacts {
-    add(nativeLibs.name, nativelibs)
+    add(cppLinkElements.name, tasks.named<ToolExecutionTask>(library).map { it.output })
+    add(cppRuntimeElements.name, tasks.named<ToolExecutionTask>(library).map { it.output })
 }
\ No newline at end of file
diff --git a/kotlin-native/Interop/StubGenerator/build.gradle.kts b/kotlin-native/Interop/StubGenerator/build.gradle.kts
index e30131b..6f2132c 100644
--- a/kotlin-native/Interop/StubGenerator/build.gradle.kts
+++ b/kotlin-native/Interop/StubGenerator/build.gradle.kts
@@ -6,6 +6,17 @@
     id("native-dependencies")
 }
 
+apply<CppConsumerPlugin>()
+
+val cppRuntimeOnly by configurations.creating {
+    isCanBeConsumed = false
+    isCanBeResolved = true
+    attributes {
+        attribute(CppUsage.USAGE_ATTRIBUTE, objects.named(CppUsage.LIBRARY_RUNTIME))
+        attribute(TargetWithSanitizer.TARGET_ATTRIBUTE, TargetWithSanitizer.host)
+    }
+}
+
 application {
     mainClass.set("org.jetbrains.kotlin.native.interop.gen.jvm.MainKt")
 }
@@ -21,6 +32,9 @@
     implementation(project(":compiler:ir.serialization.common"))
 
     testImplementation(kotlinTest("junit"))
+
+    cppRuntimeOnly(project(":kotlin-native:libclangInterop"))
+    cppRuntimeOnly(project(":kotlin-native:Interop:Runtime"))
 }
 
 sourceSets {
@@ -31,14 +45,10 @@
 tasks {
     // Copy-pasted from Indexer build.gradle.kts.
     withType<Test>().configureEach {
-        val projectsWithNativeLibs = listOf(
-                project(":kotlin-native:libclangInterop"),
-                project(":kotlin-native:Interop:Runtime")
-        )
-        dependsOn(projectsWithNativeLibs.map { "${it.path}:nativelibs" })
+        inputs.files(cppRuntimeOnly)
         dependsOn(nativeDependencies.llvmDependency)
-        systemProperty("java.library.path", projectsWithNativeLibs.joinToString(File.pathSeparator) {
-            it.layout.buildDirectory.dir("nativelibs").get().asFile.absolutePath
+        systemProperty("java.library.path", cppRuntimeOnly.elements.map { elements ->
+            elements.joinToString(File.pathSeparator) { it.asFile.parentFile.absolutePath }
         })
         val libclangPath = "${nativeDependencies.llvmPath}/" + if (org.jetbrains.kotlin.konan.target.HostManager.hostIsMingw) {
             "bin/libclang.dll"
diff --git a/kotlin-native/build-tools/src/main/kotlin/org/jetbrains/kotlin/cpp/CppUsage.kt b/kotlin-native/build-tools/src/main/kotlin/org/jetbrains/kotlin/cpp/CppUsage.kt
index fd83be2..13514ee 100644
--- a/kotlin-native/build-tools/src/main/kotlin/org/jetbrains/kotlin/cpp/CppUsage.kt
+++ b/kotlin-native/build-tools/src/main/kotlin/org/jetbrains/kotlin/cpp/CppUsage.kt
@@ -25,6 +25,26 @@
     @JvmField
     val API = Usage.C_PLUS_PLUS_API
 
+    /**
+     * Shared or static library.
+     *
+     * Can be used during compilation to link against it.
+     *
+     * @see LIBRARY_RUNTIME
+     */
+    @JvmField
+    val LIBRARY_LINK = Usage.NATIVE_LINK
+
+    /**
+     * Shared library.
+     *
+     * Can be used for building distribution to package all shared libraries.
+     *
+     * @see LIBRARY_LINK
+     */
+    @JvmField
+    val LIBRARY_RUNTIME = Usage.NATIVE_RUNTIME
+
     @JvmField
     val USAGE_ATTRIBUTE: Attribute<Usage> = Usage.USAGE_ATTRIBUTE
 }
\ No newline at end of file
diff --git a/kotlin-native/build-tools/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/konan/tasks/KonanJvmInteropTask.kt b/kotlin-native/build-tools/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/konan/tasks/KonanJvmInteropTask.kt
index 1126af9..e87eacd 100644
--- a/kotlin-native/build-tools/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/konan/tasks/KonanJvmInteropTask.kt
+++ b/kotlin-native/build-tools/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/konan/tasks/KonanJvmInteropTask.kt
@@ -15,6 +15,7 @@
 import org.gradle.api.provider.ListProperty
 import org.gradle.api.provider.Property
 import org.gradle.api.provider.Provider
+import org.gradle.api.tasks.CacheableTask
 import org.gradle.api.tasks.Classpath
 import org.gradle.api.tasks.Input
 import org.gradle.api.tasks.InputFile
@@ -37,6 +38,7 @@
 import java.io.File
 import javax.inject.Inject
 
+@CacheableTask
 open class KonanJvmInteropTask @Inject constructor(
         objectFactory: ObjectFactory,
         layout: ProjectLayout,
@@ -49,6 +51,13 @@
     val interopStubGeneratorClasspath: ConfigurableFileCollection = objectFactory.fileCollection()
 
     /**
+     * Native libraries required for Interop Stub Generator CLI tool.
+     */
+    @get:InputFiles
+    @get:PathSensitive(PathSensitivity.NONE)
+    val interopStubGeneratorNativeLibs: ConfigurableFileCollection = objectFactory.fileCollection()
+
+    /**
      * `.def` file for which to generate bridges.
      */
     @get:InputFile
@@ -82,10 +91,6 @@
         }
     }
 
-    // TODO: Must depend on the libraries themselves.
-    @get:Input
-    val nativeLibrariesPaths: ListProperty<String> = objectFactory.listProperty()
-
     /**
      * Compiler options for `clang`.
      */
@@ -120,12 +125,16 @@
             addAll(compilerOptions.get())
         }
 
+        val nativeLibrariesPaths = interopStubGeneratorNativeLibs.files.joinToString(separator = File.pathSeparator) {
+            it.parentFile.absolutePath
+        }
+
         execOperations.javaexec {
             classpath(interopStubGeneratorClasspath)
             mainClass.assign("org.jetbrains.kotlin.native.interop.gen.jvm.MainKt")
             jvmArgs("-ea")
             systemProperties(mapOf(
-                    "java.library.path" to nativeLibrariesPaths.get().joinToString(separator = File.pathSeparator),
+                    "java.library.path" to nativeLibrariesPaths,
                     // Set the konan.home property because we run the cinterop tool not from a distribution jar
                     // so it will not be able to determine this path by itself.
                     "konan.home" to platformManagerProvider.get().nativeProtoDistribution.root.asFile.absolutePath,
diff --git a/kotlin-native/build-tools/src/main/kotlin/org/jetbrains/kotlin/interop/NamedNativeInteropConfig.kt b/kotlin-native/build-tools/src/main/kotlin/org/jetbrains/kotlin/interop/NamedNativeInteropConfig.kt
index 55c845b..9bb27ad 100644
--- a/kotlin-native/build-tools/src/main/kotlin/org/jetbrains/kotlin/interop/NamedNativeInteropConfig.kt
+++ b/kotlin-native/build-tools/src/main/kotlin/org/jetbrains/kotlin/interop/NamedNativeInteropConfig.kt
@@ -14,34 +14,19 @@
 import org.jetbrains.kotlin.utils.capitalized
 
 class NamedNativeInteropConfig(
-        private val project: Project,
+        project: Project,
         private val _name: String,
 ) : Named {
     override fun getName(): String = _name
 
-    private val interopStubsName = name + "InteropStubs"
-
-    val genTask = project.tasks.register<KonanJvmInteropTask>("gen" + interopStubsName.capitalized)
-
-    init {
-        genTask.configure {
-            dependsOn(project.extensions.getByType<NativeDependenciesExtension>().hostPlatformDependency)
-            dependsOn(project.extensions.getByType<NativeDependenciesExtension>().llvmDependency)
-            interopStubGeneratorClasspath.from(project.configurations.getByName(NativeInteropPlugin.INTEROP_STUB_GENERATOR_CONFIGURATION))
-            kotlinBridges.set(project.layout.buildDirectory.dir("nativeInteropStubs/${this@NamedNativeInteropConfig.name}/kotlin"))
-            cBridge.set(project.layout.buildDirectory.file("nativeInteropStubs/${this@NamedNativeInteropConfig.name}/c/stubs.c"))
-            temporaryFilesDir.set(project.layout.buildDirectory.dir("interopTemp"))
-
-            nativeLibrariesPaths.addAll(
-                    project.project(":kotlin-native:libclangInterop").layout.buildDirectory.dir("nativelibs").get().asFile.absolutePath,
-                    project.project(":kotlin-native:Interop:Runtime").layout.buildDirectory.dir("nativelibs").get().asFile.absolutePath,
-            )
-            dependsOn(":kotlin-native:libclangInterop:nativelibs")
-            dependsOn(":kotlin-native:Interop:Runtime:nativelibs")
-            inputs.dir(project.project(":kotlin-native:libclangInterop").layout.buildDirectory.dir("nativelibs"))
-            inputs.dir(project.project(":kotlin-native:Interop:Runtime").layout.buildDirectory.dir("nativelibs"))
-
-            platformManagerProvider.set(project.extensions.getByType<PlatformManagerProvider>())
-        }
+    val genTask = project.tasks.register<KonanJvmInteropTask>("gen${name.capitalized}InteropStubs") {
+        dependsOn(project.extensions.getByType<NativeDependenciesExtension>().hostPlatformDependency)
+        dependsOn(project.extensions.getByType<NativeDependenciesExtension>().llvmDependency)
+        interopStubGeneratorClasspath.from(project.configurations.getByName(NativeInteropPlugin.INTEROP_STUB_GENERATOR_CONFIGURATION))
+        interopStubGeneratorNativeLibs.from(project.configurations.getByName(NativeInteropPlugin.INTEROP_STUB_GENERATOR_CPP_CONFIGURATION))
+        kotlinBridges.set(project.layout.buildDirectory.dir("nativeInteropStubs/${this@NamedNativeInteropConfig.name}/kotlin"))
+        cBridge.set(project.layout.buildDirectory.file("nativeInteropStubs/${this@NamedNativeInteropConfig.name}/c/stubs.c"))
+        temporaryFilesDir.set(project.layout.buildDirectory.dir("interopTemp"))
+        platformManagerProvider.set(project.extensions.getByType<PlatformManagerProvider>())
     }
 }
\ No newline at end of file
diff --git a/kotlin-native/build-tools/src/main/kotlin/org/jetbrains/kotlin/interop/NativeInteropPlugin.kt b/kotlin-native/build-tools/src/main/kotlin/org/jetbrains/kotlin/interop/NativeInteropPlugin.kt
index a03e134..140ab54 100644
--- a/kotlin-native/build-tools/src/main/kotlin/org/jetbrains/kotlin/interop/NativeInteropPlugin.kt
+++ b/kotlin-native/build-tools/src/main/kotlin/org/jetbrains/kotlin/interop/NativeInteropPlugin.kt
@@ -9,17 +9,30 @@
 import org.gradle.api.Project
 import org.gradle.kotlin.dsl.apply
 import org.gradle.kotlin.dsl.dependencies
+import org.gradle.kotlin.dsl.named
 import org.gradle.kotlin.dsl.project
+import org.jetbrains.kotlin.cpp.CppUsage
 import org.jetbrains.kotlin.dependencies.NativeDependenciesPlugin
+import org.jetbrains.kotlin.konan.target.TargetWithSanitizer
 
 open class NativeInteropPlugin : Plugin<Project> {
     override fun apply(target: Project) {
         target.apply<NativeDependenciesPlugin>()
 
         val interopStubGenerator = target.configurations.create(INTEROP_STUB_GENERATOR_CONFIGURATION)
+        val interopStubGeneratorCppRuntimeOnly = target.configurations.create(INTEROP_STUB_GENERATOR_CPP_CONFIGURATION) {
+            isCanBeConsumed = false
+            isCanBeResolved = true
+            attributes {
+                attribute(CppUsage.USAGE_ATTRIBUTE, target.objects.named(CppUsage.LIBRARY_RUNTIME))
+                attribute(TargetWithSanitizer.TARGET_ATTRIBUTE, TargetWithSanitizer.host)
+            }
+        }
         target.dependencies {
             interopStubGenerator(project(":kotlin-native:Interop:StubGenerator"))
             interopStubGenerator(project(":kotlin-native:endorsedLibraries:kotlinx.cli", "jvmRuntimeElements"))
+            interopStubGeneratorCppRuntimeOnly(project(":kotlin-native:libclangInterop"))
+            interopStubGeneratorCppRuntimeOnly(project(":kotlin-native:Interop:Runtime"))
         }
 
         target.extensions.add("kotlinNativeInterop", target.objects.domainObjectContainer(NamedNativeInteropConfig::class.java) {
@@ -29,5 +42,6 @@
 
     companion object {
         const val INTEROP_STUB_GENERATOR_CONFIGURATION = "interopStubGenerator"
+        const val INTEROP_STUB_GENERATOR_CPP_CONFIGURATION = "interopStubGeneratorCppRuntimeOnly"
     }
 }
\ No newline at end of file
diff --git a/kotlin-native/build-tools/src/main/kotlin/org/jetbrains/kotlin/tools/NativePlugin.kt b/kotlin-native/build-tools/src/main/kotlin/org/jetbrains/kotlin/tools/NativePlugin.kt
index d45497f..28d4a10 100644
--- a/kotlin-native/build-tools/src/main/kotlin/org/jetbrains/kotlin/tools/NativePlugin.kt
+++ b/kotlin-native/build-tools/src/main/kotlin/org/jetbrains/kotlin/tools/NativePlugin.kt
@@ -14,6 +14,7 @@
 import org.gradle.kotlin.dsl.*
 import org.gradle.language.base.plugins.LifecycleBasePlugin
 import org.gradle.process.ExecOperations
+import org.jetbrains.kotlin.cpp.CppConsumerPlugin
 import org.jetbrains.kotlin.dependencies.NativeDependenciesExtension
 import org.jetbrains.kotlin.dependencies.NativeDependenciesPlugin
 import org.jetbrains.kotlin.konan.target.HostManager.Companion.hostIsMac
@@ -39,6 +40,7 @@
     override fun apply(project: Project) {
         project.apply<BasePlugin>()
         project.apply<NativeDependenciesPlugin>()
+        project.apply<CppConsumerPlugin>()
         project.extensions.create("native", NativeToolsExtension::class.java, project)
     }
 }
diff --git a/kotlin-native/build.gradle b/kotlin-native/build.gradle
index 6588b50..a80e2d0 100644
--- a/kotlin-native/build.gradle
+++ b/kotlin-native/build.gradle
@@ -100,6 +100,9 @@
     nativeLibs {
         canBeConsumed = false
         canBeResolved = true
+        attributes {
+            attribute(Usage.USAGE_ATTRIBUTE, objects.named(Usage, CppUsage.LIBRARY_RUNTIME))
+        }
     }
 
     trove4j_jar {
@@ -121,10 +124,13 @@
     runtimeBitcode project(":kotlin-native:runtime")
     objcExportApi project(":kotlin-native:runtime")
     embeddableJar project(path: ':kotlin-native:prepare:kotlin-native-compiler-embeddable', configuration: 'runtimeElements')
-    nativeLibs project(path: ':kotlin-native:common:env', configuration: 'nativeLibs')
-    nativeLibs project(path: ':kotlin-native:common:files', configuration: 'nativeLibs')
-    nativeLibs project(path: ':kotlin-native:llvmInterop', configuration: 'nativeLibs')
-    nativeLibs project(path: ':kotlin-native:libclangInterop', configuration: 'nativeLibs')
+    nativeLibs project(':kotlin-native:Interop:Runtime')
+    nativeLibs project(':kotlin-native:common:env')
+    nativeLibs project(':kotlin-native:common:files')
+    nativeLibs project(':kotlin-native:libclangInterop')
+    nativeLibs project(':kotlin-native:libllvmext')
+    nativeLibs project(':kotlin-native:llvmDebugInfoC')
+    nativeLibs project(':kotlin-native:llvmInterop')
     nativeLibs project(path: ':kotlin-native:Interop:Indexer', configuration: 'nativeLibs')
     nativeLibs project(path: ':kotlin-native:Interop:Runtime', configuration: 'nativeLibs')
     use(RepoDependencies) {
diff --git a/kotlin-native/common/env/build.gradle.kts b/kotlin-native/common/env/build.gradle.kts
index a271e93..96dd9a0 100644
--- a/kotlin-native/common/env/build.gradle.kts
+++ b/kotlin-native/common/env/build.gradle.kts
@@ -1,6 +1,8 @@
+import org.gradle.kotlin.dsl.named
+import org.jetbrains.kotlin.cpp.CppUsage
 import org.jetbrains.kotlin.konan.target.HostManager
 import org.jetbrains.kotlin.konan.target.TargetWithSanitizer
-import org.jetbrains.kotlin.tools.lib
+import org.jetbrains.kotlin.tools.ToolExecutionTask
 import org.jetbrains.kotlin.tools.solib
 
 plugins {
@@ -11,6 +13,8 @@
     id("native-dependencies")
 }
 
+val library = solib("orgjetbrainskotlinbackendkonanenvstubs")
+
 bitcode {
     hostTarget {
         module("env") {
@@ -48,7 +52,7 @@
         }
     }
 
-    target(solib("orgjetbrainskotlinbackendkonanenvstubs"), sourceSets["main"]!!.transform(".c" to ".$obj")) {
+    target(library, sourceSets["main"]!!.transform(".c" to ".$obj")) {
         tool(*hostPlatform.clangForJni.clangCXX("").toTypedArray())
         flags(
                 "-shared",
@@ -57,20 +61,12 @@
     }
 }
 
-val nativelibs by project.tasks.registering(Sync::class) {
-    val lib = solib("orgjetbrainskotlinbackendkonanenvstubs")
-    dependsOn(lib)
-
-    from(layout.buildDirectory.dir(lib))
-    into(layout.buildDirectory.dir("nativelibs"))
-}
-
 kotlinNativeInterop.create("env").genTask.configure {
     defFile.set(layout.projectDirectory.file("env.konan.backend.kotlin.jetbrains.org.def"))
     headersDirs.from(layout.projectDirectory.dir("include"))
 }
 
-tasks.named(solib("orgjetbrainskotlinbackendkonanenvstubs")).configure {
+tasks.named(library).configure {
     dependsOn(bitcode.hostTarget.module("env").get().sourceSets.main.get().task.get())
 }
 
@@ -91,17 +87,35 @@
     }
 }
 
-val nativeLibs by configurations.creating {
+val cppApiElements by configurations.creating {
     isCanBeConsumed = true
     isCanBeResolved = false
     attributes {
+        attribute(CppUsage.USAGE_ATTRIBUTE, objects.named(CppUsage.API))
         attribute(ArtifactTypeDefinition.ARTIFACT_TYPE_ATTRIBUTE, ArtifactTypeDefinition.DIRECTORY_TYPE)
+    }
+}
+
+val cppLinkElements by configurations.creating {
+    isCanBeConsumed = true
+    isCanBeResolved = false
+    attributes {
+        attribute(CppUsage.USAGE_ATTRIBUTE, objects.named(CppUsage.LIBRARY_LINK))
+        attribute(TargetWithSanitizer.TARGET_ATTRIBUTE, TargetWithSanitizer.host)
+    }
+}
+
+val cppRuntimeElements by configurations.creating {
+    isCanBeConsumed = true
+    isCanBeResolved = false
+    attributes {
+        attribute(CppUsage.USAGE_ATTRIBUTE, objects.named(CppUsage.LIBRARY_RUNTIME))
         attribute(TargetWithSanitizer.TARGET_ATTRIBUTE, TargetWithSanitizer.host)
     }
 }
 
 artifacts {
-    add(nativeLibs.name, layout.buildDirectory.dir("nativelibs")) {
-        builtBy(nativelibs)
-    }
+    add(cppApiElements.name, layout.projectDirectory.dir("include"))
+    add(cppLinkElements.name, tasks.named<ToolExecutionTask>(library).map { it.output })
+    add(cppRuntimeElements.name, tasks.named<ToolExecutionTask>(library).map { it.output })
 }
\ No newline at end of file
diff --git a/kotlin-native/common/files/build.gradle.kts b/kotlin-native/common/files/build.gradle.kts
index 4017f47..b423fd5 100644
--- a/kotlin-native/common/files/build.gradle.kts
+++ b/kotlin-native/common/files/build.gradle.kts
@@ -1,5 +1,8 @@
+import org.gradle.kotlin.dsl.named
+import org.jetbrains.kotlin.cpp.CppUsage
 import org.jetbrains.kotlin.konan.target.HostManager
 import org.jetbrains.kotlin.konan.target.TargetWithSanitizer
+import org.jetbrains.kotlin.tools.ToolExecutionTask
 import org.jetbrains.kotlin.tools.solib
 
 plugins {
@@ -10,6 +13,8 @@
     id("native-dependencies")
 }
 
+val library = solib("orgjetbrainskotlinbackendkonanfilesstubs")
+
 bitcode {
     hostTarget {
         module("files") {
@@ -47,7 +52,7 @@
         }
     }
 
-    target(solib("orgjetbrainskotlinbackendkonanfilesstubs"), sourceSets["main"]!!.transform(".c" to ".$obj")) {
+    target(library, sourceSets["main"]!!.transform(".c" to ".$obj")) {
         tool(*hostPlatform.clangForJni.clangCXX("").toTypedArray())
         flags(
                 "-shared",
@@ -56,20 +61,12 @@
     }
 }
 
-val nativelibs by project.tasks.registering(Sync::class) {
-    val lib = solib("orgjetbrainskotlinbackendkonanfilesstubs")
-    dependsOn(lib)
-
-    from(layout.buildDirectory.dir(lib))
-    into(layout.buildDirectory.dir("nativelibs"))
-}
-
 kotlinNativeInterop.create("files").genTask.configure {
     defFile.set(layout.projectDirectory.file("files.konan.backend.kotlin.jetbrains.org.def"))
     headersDirs.from(layout.projectDirectory.dir("include"))
 }
 
-tasks.named(solib("orgjetbrainskotlinbackendkonanfilesstubs")).configure {
+tasks.named(library).configure {
     dependsOn(bitcode.hostTarget.module("files").get().sourceSets.main.get().task.get())
 }
 
@@ -78,7 +75,6 @@
     inputs.file(kotlinNativeInterop["files"].genTask.map { it.cBridge })
 }
 
-
 dependencies {
     implementation(kotlinStdlib())
     api(project(":kotlin-native:Interop:Runtime"))
@@ -90,17 +86,35 @@
     }
 }
 
-val nativeLibs by configurations.creating {
+val cppApiElements by configurations.creating {
     isCanBeConsumed = true
     isCanBeResolved = false
     attributes {
+        attribute(CppUsage.USAGE_ATTRIBUTE, objects.named(CppUsage.API))
         attribute(ArtifactTypeDefinition.ARTIFACT_TYPE_ATTRIBUTE, ArtifactTypeDefinition.DIRECTORY_TYPE)
+    }
+}
+
+val cppLinkElements by configurations.creating {
+    isCanBeConsumed = true
+    isCanBeResolved = false
+    attributes {
+        attribute(CppUsage.USAGE_ATTRIBUTE, objects.named(CppUsage.LIBRARY_LINK))
+        attribute(TargetWithSanitizer.TARGET_ATTRIBUTE, TargetWithSanitizer.host)
+    }
+}
+
+val cppRuntimeElements by configurations.creating {
+    isCanBeConsumed = true
+    isCanBeResolved = false
+    attributes {
+        attribute(CppUsage.USAGE_ATTRIBUTE, objects.named(CppUsage.LIBRARY_RUNTIME))
         attribute(TargetWithSanitizer.TARGET_ATTRIBUTE, TargetWithSanitizer.host)
     }
 }
 
 artifacts {
-    add(nativeLibs.name, layout.buildDirectory.dir("nativelibs")) {
-        builtBy(nativelibs)
-    }
+    add(cppApiElements.name, layout.projectDirectory.dir("include"))
+    add(cppLinkElements.name, tasks.named<ToolExecutionTask>(library).map { it.output })
+    add(cppRuntimeElements.name, tasks.named<ToolExecutionTask>(library).map { it.output })
 }
\ No newline at end of file
diff --git a/kotlin-native/libclangInterop/build.gradle.kts b/kotlin-native/libclangInterop/build.gradle.kts
index b156ff6..314e5b9 100644
--- a/kotlin-native/libclangInterop/build.gradle.kts
+++ b/kotlin-native/libclangInterop/build.gradle.kts
@@ -1,6 +1,8 @@
+import org.gradle.kotlin.dsl.named
+import org.jetbrains.kotlin.cpp.CppUsage
 import org.jetbrains.kotlin.konan.target.HostManager
 import org.jetbrains.kotlin.konan.target.TargetWithSanitizer
-import org.jetbrains.kotlin.tools.lib
+import org.jetbrains.kotlin.tools.ToolExecutionTask
 import org.jetbrains.kotlin.tools.solib
 
 plugins {
@@ -14,6 +16,29 @@
 val libclangextDir = libclangextProject.layout.buildDirectory.get().asFile
 val libclangextIsEnabled = libclangextProject.findProperty("isEnabled")!! as Boolean
 
+val library = solib("clangstubs")
+
+val cppLink by configurations.creating {
+    isCanBeConsumed = false
+    isCanBeResolved = true
+    attributes {
+        attribute(CppUsage.USAGE_ATTRIBUTE, objects.named(CppUsage.LIBRARY_LINK))
+        attribute(TargetWithSanitizer.TARGET_ATTRIBUTE, TargetWithSanitizer.host)
+    }
+}
+
+val cppApi by configurations.creating {
+    isCanBeConsumed = false
+    isCanBeResolved = true
+    attributes {
+        attribute(CppUsage.USAGE_ATTRIBUTE, objects.named(CppUsage.API))
+    }
+}
+
+dependencies {
+    cppApi(project(":kotlin-native:libclangext"))
+    cppLink(project(":kotlin-native:libclangext"))
+}
 
 val libclang =
         if (HostManager.hostIsMingw) {
@@ -106,7 +131,7 @@
     val objSet = arrayOf(sourceSets["main-c"]!!.transform(".c" to ".$obj"),
             sourceSets["main-cpp"]!!.transform(".cpp" to ".$obj"))
 
-    target(solib("clangstubs"), *objSet) {
+    target(library, *objSet) {
         tool(*hostPlatform.clangForJni.clangCXX("").toTypedArray())
         flags(
                 "-shared",
@@ -115,25 +140,15 @@
     }
 }
 
-tasks.named(solib("clangstubs")).configure {
-    dependsOn(":kotlin-native:libclangext:${lib("clangext")}")
-}
-
-val nativelibs by project.tasks.registering(Sync::class) {
-    val lib = solib("clangstubs")
-    dependsOn(lib)
-
-    from(layout.buildDirectory.dir(lib))
-    into(layout.buildDirectory.dir("nativelibs"))
+tasks.named(library).configure {
+    inputs.files(cppLink)
 }
 
 kotlinNativeInterop.create("clang").genTask.configure {
     defFile.set(layout.projectDirectory.file("clang.def"))
     compilerOptions.addAll(cflags)
-    headersDirs.from(
-            "${nativeDependencies.llvmPath}/include",
-            "${project(":kotlin-native:libclangext").projectDir.absolutePath}/src/main/include",
-    )
+    headersDirs.from("${nativeDependencies.llvmPath}/include")
+    headersDirs.from(cppApi)
 }
 
 dependencies {
@@ -147,19 +162,36 @@
     }
 }
 
-val nativeLibs by configurations.creating {
+val cppApiElements by configurations.creating {
     isCanBeConsumed = true
     isCanBeResolved = false
     attributes {
+        attribute(CppUsage.USAGE_ATTRIBUTE, objects.named(CppUsage.API))
         attribute(ArtifactTypeDefinition.ARTIFACT_TYPE_ATTRIBUTE, ArtifactTypeDefinition.DIRECTORY_TYPE)
+    }
+}
+
+val cppLinkElements by configurations.creating {
+    isCanBeConsumed = true
+    isCanBeResolved = false
+    attributes {
+        attribute(CppUsage.USAGE_ATTRIBUTE, objects.named(CppUsage.LIBRARY_LINK))
+        attribute(TargetWithSanitizer.TARGET_ATTRIBUTE, TargetWithSanitizer.host)
+    }
+}
+
+val cppRuntimeElements by configurations.creating {
+    isCanBeConsumed = true
+    isCanBeResolved = false
+    attributes {
+        attribute(CppUsage.USAGE_ATTRIBUTE, objects.named(CppUsage.LIBRARY_RUNTIME))
         attribute(TargetWithSanitizer.TARGET_ATTRIBUTE, TargetWithSanitizer.host)
     }
 }
 
 artifacts {
-    add(nativeLibs.name, layout.buildDirectory.dir("nativelibs")) {
-        builtBy(nativelibs)
-    }
+    add(cppLinkElements.name, tasks.named<ToolExecutionTask>(library).map { it.output })
+    add(cppRuntimeElements.name, tasks.named<ToolExecutionTask>(library).map { it.output })
 }
 
 // TODO: Replace with a common way to generate sources. Also add a test that generation didn't change checked-in sources.
diff --git a/kotlin-native/libclangext/build.gradle.kts b/kotlin-native/libclangext/build.gradle.kts
index f82c6b5..fd0430a 100644
--- a/kotlin-native/libclangext/build.gradle.kts
+++ b/kotlin-native/libclangext/build.gradle.kts
@@ -14,8 +14,12 @@
  * limitations under the License.
  */
 
+import org.gradle.kotlin.dsl.named
 import org.jetbrains.kotlin.tools.lib
 import org.jetbrains.kotlin.*
+import org.jetbrains.kotlin.cpp.CppUsage
+import org.jetbrains.kotlin.konan.target.TargetWithSanitizer
+import org.jetbrains.kotlin.tools.ToolExecutionTask
 
 plugins {
     id("kotlin.native.build-tools-conventions")
@@ -24,6 +28,8 @@
 val libclangextEnabled = org.jetbrains.kotlin.konan.target.HostManager.hostIsMac
 extra["isEnabled"] = libclangextEnabled
 
+val library = lib("clangext")
+
 native {
     val isWindows = PlatformInfo.isWindows()
     val obj = if (isWindows) "obj" else "o"
@@ -50,4 +56,37 @@
         tool(*hostPlatform.clangForJni.llvmAr("").toTypedArray())
         flags("-qcv", ruleOut(), *ruleInAll())
     }
+}
+
+val cppApiElements by configurations.creating {
+    isCanBeConsumed = true
+    isCanBeResolved = false
+    attributes {
+        attribute(CppUsage.USAGE_ATTRIBUTE, objects.named(CppUsage.API))
+        attribute(ArtifactTypeDefinition.ARTIFACT_TYPE_ATTRIBUTE, ArtifactTypeDefinition.DIRECTORY_TYPE)
+    }
+}
+
+val cppLinkElements by configurations.creating {
+    isCanBeConsumed = true
+    isCanBeResolved = false
+    attributes {
+        attribute(CppUsage.USAGE_ATTRIBUTE, objects.named(CppUsage.LIBRARY_LINK))
+        attribute(TargetWithSanitizer.TARGET_ATTRIBUTE, TargetWithSanitizer.host)
+    }
+}
+
+val cppRuntimeElements by configurations.creating {
+    isCanBeConsumed = true
+    isCanBeResolved = false
+    attributes {
+        attribute(CppUsage.USAGE_ATTRIBUTE, objects.named(CppUsage.LIBRARY_RUNTIME))
+        attribute(TargetWithSanitizer.TARGET_ATTRIBUTE, TargetWithSanitizer.host)
+    }
+}
+
+artifacts {
+    add(cppApiElements.name, layout.projectDirectory.dir("src/main/include"))
+    add(cppLinkElements.name, tasks.named<ToolExecutionTask>(library).map { it.output })
+    // Static library, nothing in cppRuntimeElements
 }
\ No newline at end of file
diff --git a/kotlin-native/libllvmext/build.gradle.kts b/kotlin-native/libllvmext/build.gradle.kts
index 5fed13e..269ab65 100644
--- a/kotlin-native/libllvmext/build.gradle.kts
+++ b/kotlin-native/libllvmext/build.gradle.kts
@@ -14,10 +14,14 @@
  * limitations under the License.
  */
 
+import org.gradle.kotlin.dsl.named
 import org.jetbrains.kotlin.tools.lib
 import org.jetbrains.kotlin.*
+import org.jetbrains.kotlin.cpp.CppUsage
 import org.jetbrains.kotlin.konan.target.Family.*
 import org.jetbrains.kotlin.konan.target.HostManager
+import org.jetbrains.kotlin.konan.target.TargetWithSanitizer
+import org.jetbrains.kotlin.tools.ToolExecutionTask
 
 plugins {
     id("kotlin.native.build-tools-conventions")
@@ -25,6 +29,8 @@
     id("native-dependencies")
 }
 
+val library = lib("llvmext")
+
 native {
     val obj = if (HostManager.hostIsMingw) "obj" else "o"
     val cxxflags = mutableListOf(
@@ -71,3 +77,36 @@
         println(nativeDependencies.llvmPath)
     }
 }
+
+val cppApiElements by configurations.creating {
+    isCanBeConsumed = true
+    isCanBeResolved = false
+    attributes {
+        attribute(CppUsage.USAGE_ATTRIBUTE, objects.named(CppUsage.API))
+        attribute(ArtifactTypeDefinition.ARTIFACT_TYPE_ATTRIBUTE, ArtifactTypeDefinition.DIRECTORY_TYPE)
+    }
+}
+
+val cppLinkElements by configurations.creating {
+    isCanBeConsumed = true
+    isCanBeResolved = false
+    attributes {
+        attribute(CppUsage.USAGE_ATTRIBUTE, objects.named(CppUsage.LIBRARY_LINK))
+        attribute(TargetWithSanitizer.TARGET_ATTRIBUTE, TargetWithSanitizer.host)
+    }
+}
+
+val cppRuntimeElements by configurations.creating {
+    isCanBeConsumed = true
+    isCanBeResolved = false
+    attributes {
+        attribute(CppUsage.USAGE_ATTRIBUTE, objects.named(CppUsage.LIBRARY_RUNTIME))
+        attribute(TargetWithSanitizer.TARGET_ATTRIBUTE, TargetWithSanitizer.host)
+    }
+}
+
+artifacts {
+    add(cppApiElements.name, layout.projectDirectory.dir("src/main/include"))
+    add(cppLinkElements.name, tasks.named<ToolExecutionTask>(library).map { it.output })
+    // Static library, nothing in cppRuntimeElements
+}
\ No newline at end of file
diff --git a/kotlin-native/llvmDebugInfoC/build.gradle.kts b/kotlin-native/llvmDebugInfoC/build.gradle.kts
index 1c4eed5..ed34837 100644
--- a/kotlin-native/llvmDebugInfoC/build.gradle.kts
+++ b/kotlin-native/llvmDebugInfoC/build.gradle.kts
@@ -14,13 +14,18 @@
  * limitations under the License.
  */
 
+import org.jetbrains.kotlin.cpp.CppUsage
 import org.jetbrains.kotlin.tools.lib
 import org.jetbrains.kotlin.konan.target.HostManager
+import org.jetbrains.kotlin.konan.target.TargetWithSanitizer
+import org.jetbrains.kotlin.tools.ToolExecutionTask
 
 plugins {
     id("native")
 }
 
+val library = lib("debugInfo")
+
 native {
     val obj = if (HostManager.hostIsMingw) "obj" else "o"
     val cxxStandard = 17
@@ -45,7 +50,7 @@
     }
     val objSet = sourceSets["main"]!!.transform(".cpp" to ".$obj")
 
-    target(lib("debugInfo"), objSet) {
+    target(library, objSet) {
         tool(*hostPlatform.clangForJni.llvmAr("").toTypedArray())
         flags("-qcv", ruleOut(), *ruleInAll())
     }
@@ -71,4 +76,37 @@
             )
         }
     }
+}
+
+val cppApiElements by configurations.creating {
+    isCanBeConsumed = true
+    isCanBeResolved = false
+    attributes {
+        attribute(CppUsage.USAGE_ATTRIBUTE, objects.named(CppUsage.API))
+        attribute(ArtifactTypeDefinition.ARTIFACT_TYPE_ATTRIBUTE, ArtifactTypeDefinition.DIRECTORY_TYPE)
+    }
+}
+
+val cppLinkElements by configurations.creating {
+    isCanBeConsumed = true
+    isCanBeResolved = false
+    attributes {
+        attribute(CppUsage.USAGE_ATTRIBUTE, objects.named(CppUsage.LIBRARY_LINK))
+        attribute(TargetWithSanitizer.TARGET_ATTRIBUTE, TargetWithSanitizer.host)
+    }
+}
+
+val cppRuntimeElements by configurations.creating {
+    isCanBeConsumed = true
+    isCanBeResolved = false
+    attributes {
+        attribute(CppUsage.USAGE_ATTRIBUTE, objects.named(CppUsage.LIBRARY_RUNTIME))
+        attribute(TargetWithSanitizer.TARGET_ATTRIBUTE, TargetWithSanitizer.host)
+    }
+}
+
+artifacts {
+    add(cppApiElements.name, layout.projectDirectory.dir("src/main/include"))
+    add(cppLinkElements.name, tasks.named<ToolExecutionTask>(library).map { it.output })
+    // Static library, nothing in cppRuntimeElements
 }
\ No newline at end of file
diff --git a/kotlin-native/llvmInterop/build.gradle.kts b/kotlin-native/llvmInterop/build.gradle.kts
index 79fcd31..86c0325 100644
--- a/kotlin-native/llvmInterop/build.gradle.kts
+++ b/kotlin-native/llvmInterop/build.gradle.kts
@@ -1,7 +1,9 @@
+import org.gradle.kotlin.dsl.named
 import org.jetbrains.kotlin.PlatformInfo
+import org.jetbrains.kotlin.cpp.CppUsage
 import org.jetbrains.kotlin.konan.target.HostManager
 import org.jetbrains.kotlin.konan.target.TargetWithSanitizer
-import org.jetbrains.kotlin.tools.lib
+import org.jetbrains.kotlin.tools.ToolExecutionTask
 import org.jetbrains.kotlin.tools.solib
 
 plugins {
@@ -11,6 +13,32 @@
     id("native-dependencies")
 }
 
+val library = solib("llvmstubs")
+
+val cppLink by configurations.creating {
+    isCanBeConsumed = false
+    isCanBeResolved = true
+    attributes {
+        attribute(CppUsage.USAGE_ATTRIBUTE, objects.named(CppUsage.LIBRARY_LINK))
+        attribute(TargetWithSanitizer.TARGET_ATTRIBUTE, TargetWithSanitizer.host)
+    }
+}
+
+val cppApi by configurations.creating {
+    isCanBeConsumed = false
+    isCanBeResolved = true
+    attributes {
+        attribute(CppUsage.USAGE_ATTRIBUTE, objects.named(CppUsage.API))
+    }
+}
+
+dependencies {
+    cppApi(project(":kotlin-native:llvmDebugInfoC"))
+    cppLink(project(":kotlin-native:llvmDebugInfoC"))
+    cppApi(project(":kotlin-native:libllvmext"))
+    cppLink(project(":kotlin-native:libllvmext"))
+}
+
 val includeFlags = listOf(
         "-I${nativeDependencies.llvmPath}/include",
         "-I${rootProject.project(":kotlin-native:llvmDebugInfoC").projectDir}/src/main/include",
@@ -117,7 +145,7 @@
         }
     }
 
-    target(solib("llvmstubs"), sourceSets["main"]!!.transform(".c" to ".$obj")) {
+    target(library, sourceSets["main"]!!.transform(".c" to ".$obj")) {
         tool(*hostPlatform.clangForJni.clangCXX("").toTypedArray())
         flags(
                 "-shared",
@@ -126,27 +154,15 @@
     }
 }
 
-tasks.named(solib("llvmstubs")).configure {
-    dependsOn(":kotlin-native:llvmDebugInfoC:${lib("debugInfo")}")
-    dependsOn(":kotlin-native:libllvmext:${lib("llvmext")}")
-}
-
-val nativelibs by project.tasks.registering(Sync::class) {
-    val lib = solib("llvmstubs")
-    dependsOn(lib)
-
-    from(layout.buildDirectory.dir(lib))
-    into(layout.buildDirectory.dir("nativelibs"))
+tasks.named(library).configure {
+    inputs.files(cppLink)
 }
 
 kotlinNativeInterop.create("llvm").genTask.configure {
     defFile.set(layout.projectDirectory.file("llvm.def"))
     compilerOptions.addAll(cflags)
-    headersDirs.from(
-            "${nativeDependencies.llvmPath}/include",
-            "${rootProject.project(":kotlin-native:llvmDebugInfoC").projectDir}/src/main/include",
-            "${rootProject.project(":kotlin-native:libllvmext").projectDir}/src/main/include",
-    )
+    headersDirs.from("${nativeDependencies.llvmPath}/include")
+    headersDirs.from(cppApi)
 }
 
 native.sourceSets["main"]!!.implicitTasks()
@@ -165,17 +181,34 @@
     }
 }
 
-val nativeLibs by configurations.creating {
+val cppApiElements by configurations.creating {
     isCanBeConsumed = true
     isCanBeResolved = false
     attributes {
+        attribute(CppUsage.USAGE_ATTRIBUTE, objects.named(CppUsage.API))
         attribute(ArtifactTypeDefinition.ARTIFACT_TYPE_ATTRIBUTE, ArtifactTypeDefinition.DIRECTORY_TYPE)
+    }
+}
+
+val cppLinkElements by configurations.creating {
+    isCanBeConsumed = true
+    isCanBeResolved = false
+    attributes {
+        attribute(CppUsage.USAGE_ATTRIBUTE, objects.named(CppUsage.LIBRARY_LINK))
+        attribute(TargetWithSanitizer.TARGET_ATTRIBUTE, TargetWithSanitizer.host)
+    }
+}
+
+val cppRuntimeElements by configurations.creating {
+    isCanBeConsumed = true
+    isCanBeResolved = false
+    attributes {
+        attribute(CppUsage.USAGE_ATTRIBUTE, objects.named(CppUsage.LIBRARY_RUNTIME))
         attribute(TargetWithSanitizer.TARGET_ATTRIBUTE, TargetWithSanitizer.host)
     }
 }
 
 artifacts {
-    add(nativeLibs.name, layout.buildDirectory.dir("nativelibs")) {
-        builtBy(nativelibs)
-    }
+    add(cppLinkElements.name, tasks.named<ToolExecutionTask>(library).map { it.output })
+    add(cppRuntimeElements.name, tasks.named<ToolExecutionTask>(library).map { it.output })
 }
\ No newline at end of file