1+ /*
2+ * Copyright 2023-2025 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
3+ */
4+
5+ package util
6+
7+
8+ import org.gradle.kotlin.dsl.assign
9+ import org.gradle.kotlin.dsl.getValue
10+ import org.gradle.kotlin.dsl.provideDelegate
11+ import org.gradle.kotlin.dsl.withType
12+ import org.jetbrains.dokka.gradle.tasks.DokkaGeneratePublicationTask
13+ import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
14+ import org.jetbrains.kotlin.gradle.plugin.mpp.DefaultCInteropSettings
15+ import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget
16+ import org.jetbrains.kotlin.gradle.tasks.KotlinNativeCompile
17+
18+
19+ /* *
20+ * Creates a CInterop configuration for all Native targets using the given [sourceSet]
21+ * in a Kotlin Multiplatform project.
22+ *
23+ * The [name] defines the CInterop configuration name. Definition file is expected to be located
24+ * at `[sourceSet]/interop/[name].def` by default, but can be customized via [definitionFilePath].
25+ * Additional configuration can be provided through [configure] block.
26+ *
27+ * Simple usage:
28+ * ```
29+ * kotlin {
30+ * createCInterop("ssl", "posix")
31+ * }
32+ * ```
33+ *
34+ * Advanced usage with a separate definition for each target and additional configuration:
35+ * ```
36+ * kotlin {
37+ * createCInterop(
38+ * name = "ssl",
39+ * sourceSet = "posix",
40+ * definitionFilePath = { target -> "$target/interop/ssl.def" },
41+ * configure = { target ->
42+ * includeDirs("$target/interop/include")
43+ * compilerOpts("-DUSE_SSL")
44+ * }
45+ * )
46+ * }
47+ * ```
48+ */
49+ @Suppress(" UnstableApiUsage" )
50+ fun KotlinMultiplatformExtension.createCInterop (
51+ name : String ,
52+ sourceSet : String ,
53+ definitionFilePath : (String ) -> String = { "$sourceSet/interop/$name.def" },
54+ configure : DefaultCInteropSettings .(String ) -> Unit = {}
55+ ) {
56+
57+ val cinteropTargets = grpcNativeTargets().map { it.name }
58+ val projectDirectory = project.isolated.projectDirectory
59+
60+ targets.named { it in cinteropTargets }
61+ .all {
62+ check(this is KotlinNativeTarget ) { " Can't create cinterop for non-native target $targetName " }
63+
64+ val main by compilations
65+ main.cinterops.create(name) {
66+ definitionFile = projectDirectory.file(definitionFilePath(targetName))
67+ configure(targetName)
68+ }
69+ }
70+
71+ // Disable configuration cache for compile[target]MainKotlinMetadata tasks
72+ project.tasks.withType<KotlinNativeCompile >()
73+ .named { it.endsWith(" MainKotlinMetadata" ) }
74+ .configureEach { notCompatibleWithConfigurationCache(" Workaround for KT-76147" ) }
75+
76+ // The problem with compile*MainKotlinMetadata tasks also affects Dokka tasks
77+ project.tasks.withType<DokkaGeneratePublicationTask >()
78+ .named { it == " dokkaGeneratePublicationHtml" }
79+ .configureEach { notCompatibleWithConfigurationCache(" Workaround for KT-76147" ) }
80+ }
0 commit comments