From edf2b18f4f282a573370b2548ea20574e78f8597 Mon Sep 17 00:00:00 2001 From: Ilya Matveev Date: Fri, 21 Feb 2020 19:18:13 +0700 Subject: [PATCH] [Gradle, Native/JS] Specify FQ module name for klibs By default, a unique name for a klibrary equals to a klib file name. In the MPP plugin, the file name equals to a Gradle project name. But the project name is not unique enough. E.g. there is a situation when there are several projects with the same simple name inside a single Gradle build. If one of these projects depends on another, the compiler will report a false cyclic dependency error. This patch partially fixes this problem by specifying a custom unique name for produced klibs based on project group and name. We still can get a unique name clash in a case of equal groups and project names. But in this case the cyclic dependency error looks much more logical for user. Also this patch specifies short names for native klibs to avoid long declaration prefixes in framework headers. Issue #KT-36721 Fixed Issue #KT-38220 Fixed --- .../kotlin/gradle/GeneralNativeIT.kt | 3 +- .../kotlin/gradle/NewMultiplatformIT.kt | 40 +++++++++++++++++++ .../build.gradle.kts | 28 +++++++++++++ .../foo/build.gradle.kts | 25 ++++++++++++ .../foo/foo/build.gradle.kts | 22 ++++++++++ .../foo/foo/src/jsMain/kotlin/foofoo.kt | 3 ++ .../foo/foo/src/linuxMain/kotlin/foofoo.kt | 5 +++ .../foo/src/nativeInterop/cinterop/bar.def | 8 ++++ .../foo/src/commonMain/kotlin/foo.kt | 1 + .../foo/src/jsMain/kotlin/foo.kt | 4 ++ .../foo/src/linuxMain/kotlin/foo.kt | 6 +++ .../foo/src/nativeInterop/cinterop/bar.def | 8 ++++ .../gradle.properties | 2 + .../settings.gradle.kts | 10 +++++ .../src/commonMain/kotlin/main.kt | 3 ++ .../gradle/targets/js/ir/CompilerFlags.kt | 4 +- .../js/ir/KotlinJsIrTargetConfigurator.kt | 17 ++++++-- .../targets/native/tasks/KotlinNativeTasks.kt | 34 +++++++++++++--- .../kotlin/gradle/utils/klibUtils.kt | 11 +++++ 19 files changed, 223 insertions(+), 11 deletions(-) create mode 100644 libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/new-mpp-klibs-with-same-name/build.gradle.kts create mode 100644 libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/new-mpp-klibs-with-same-name/foo/build.gradle.kts create mode 100644 libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/new-mpp-klibs-with-same-name/foo/foo/build.gradle.kts create mode 100644 libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/new-mpp-klibs-with-same-name/foo/foo/src/jsMain/kotlin/foofoo.kt create mode 100644 libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/new-mpp-klibs-with-same-name/foo/foo/src/linuxMain/kotlin/foofoo.kt create mode 100644 libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/new-mpp-klibs-with-same-name/foo/foo/src/nativeInterop/cinterop/bar.def create mode 100644 libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/new-mpp-klibs-with-same-name/foo/src/commonMain/kotlin/foo.kt create mode 100644 libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/new-mpp-klibs-with-same-name/foo/src/jsMain/kotlin/foo.kt create mode 100644 libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/new-mpp-klibs-with-same-name/foo/src/linuxMain/kotlin/foo.kt create mode 100644 libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/new-mpp-klibs-with-same-name/foo/src/nativeInterop/cinterop/bar.def create mode 100644 libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/new-mpp-klibs-with-same-name/gradle.properties create mode 100644 libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/new-mpp-klibs-with-same-name/settings.gradle.kts create mode 100644 libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/new-mpp-klibs-with-same-name/src/commonMain/kotlin/main.kt create mode 100644 libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/utils/klibUtils.kt diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/GeneralNativeIT.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/GeneralNativeIT.kt index d196b25d5da..259c7448f97 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/GeneralNativeIT.kt +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/GeneralNativeIT.kt @@ -51,6 +51,7 @@ class GeneralNativeIT : BaseGradleIT() { assertTasksExecuted(":two:compileKotlinLinux") assertNotContains("Parallel in-process execution of the Kotlin/Native compiler detected.") } - } + + // TODO: Move native specific tests from NewMultiplatformIT here. } \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/NewMultiplatformIT.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/NewMultiplatformIT.kt index e4a91267de7..b008be9a210 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/NewMultiplatformIT.kt +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/NewMultiplatformIT.kt @@ -21,10 +21,13 @@ import org.jetbrains.kotlin.gradle.targets.jvm.KotlinJvmTarget import org.jetbrains.kotlin.gradle.util.* import org.jetbrains.kotlin.konan.target.CompilerOutputKind import org.jetbrains.kotlin.konan.target.HostManager +import org.jetbrains.kotlin.library.KLIB_PROPERTY_SHORT_NAME +import org.jetbrains.kotlin.library.KLIB_PROPERTY_UNIQUE_NAME import org.junit.Assert import org.junit.Ignore import org.junit.Test import java.io.File +import java.util.* import java.util.jar.JarFile import java.util.zip.ZipFile import kotlin.test.assertEquals @@ -2530,4 +2533,41 @@ class NewMultiplatformIT : BaseGradleIT() { } } } + + @Test + fun testKlibsWithTheSameProjectName() = with(transformProjectWithPluginsDsl("new-mpp-klibs-with-same-name")) { + // KT-36721. + build("assemble") { + assertSuccessful() + assertTasksExecuted( + ":foo:foo:compileKotlinJs", + ":foo:foo:compileKotlinLinux", + ":foo:compileKotlinJs", + ":foo:compileKotlinLinux", + ":compileKotlinJs", + ":compileKotlinLinux" + ) + + fun getManifest(relativePath: String): Properties = + with(ZipFile(projectDir.resolve(relativePath))) { + return this.getInputStream(getEntry("default/manifest")).use { stream -> + Properties().apply { load(stream) } + } + } + + val interopManifest = getManifest("foo/build/classes/kotlin/linux/main/foo-cinterop-bar.klib") + assertEquals("org.sample.one.foo-cinterop-bar", interopManifest[KLIB_PROPERTY_UNIQUE_NAME]) + + val nativeManifest = getManifest("foo/build/classes/kotlin/linux/main/foo.klib") + assertEquals("org.sample.one.foo", nativeManifest[KLIB_PROPERTY_UNIQUE_NAME]) + // Check the short name that is used as a prefix in generated ObjC headers. + assertEquals("foo", nativeManifest[KLIB_PROPERTY_SHORT_NAME]) + + val jsManifest = projectDir.resolve("foo/build/classes/kotlin/js/main/default/manifest") + .inputStream().use { stream -> + Properties().apply { load(stream) } + } + assertEquals("org.sample.one.foo", jsManifest[KLIB_PROPERTY_UNIQUE_NAME]) + } + } } diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/new-mpp-klibs-with-same-name/build.gradle.kts b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/new-mpp-klibs-with-same-name/build.gradle.kts new file mode 100644 index 00000000000..8b2bdaa7f9f --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/new-mpp-klibs-with-same-name/build.gradle.kts @@ -0,0 +1,28 @@ +plugins { + kotlin("multiplatform").version("") +} + +group = "org.sample.root" + +allprojects { + repositories { + mavenLocal() + jcenter() + } +} + +kotlin { + linuxX64("linux") + js { + nodejs() + } + + sourceSets["commonMain"].dependencies { + implementation(kotlin("stdlib-common")) + implementation(project(":foo")) + } + + sourceSets["jsMain"].dependencies { + implementation(kotlin("stdlib-js")) + } +} diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/new-mpp-klibs-with-same-name/foo/build.gradle.kts b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/new-mpp-klibs-with-same-name/foo/build.gradle.kts new file mode 100644 index 00000000000..6833bfa723e --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/new-mpp-klibs-with-same-name/foo/build.gradle.kts @@ -0,0 +1,25 @@ +plugins { + kotlin("multiplatform") +} + +group="org.sample.one" + +kotlin { + linuxX64("linux") { + val bar by compilations["main"].cinterops.creating + } + js { + nodejs() + } + + sourceSets["commonMain"].dependencies { + implementation(kotlin("stdlib-common")) + implementation(project(":foo:foo")) + } + + sourceSets["jsMain"].dependencies { + implementation(kotlin("stdlib-js")) + } +} + + diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/new-mpp-klibs-with-same-name/foo/foo/build.gradle.kts b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/new-mpp-klibs-with-same-name/foo/foo/build.gradle.kts new file mode 100644 index 00000000000..fad615393a2 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/new-mpp-klibs-with-same-name/foo/foo/build.gradle.kts @@ -0,0 +1,22 @@ +plugins { + kotlin("multiplatform") +} + +group="org.sample.two" + +kotlin { + linuxX64("linux") { + val bar by compilations["main"].cinterops.creating + } + js { + nodejs() + } + + sourceSets["commonMain"].dependencies { + implementation(kotlin("stdlib-common")) + } + + sourceSets["jsMain"].dependencies { + implementation(kotlin("stdlib-js")) + } +} diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/new-mpp-klibs-with-same-name/foo/foo/src/jsMain/kotlin/foofoo.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/new-mpp-klibs-with-same-name/foo/foo/src/jsMain/kotlin/foofoo.kt new file mode 100644 index 00000000000..7c7f6a04fda --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/new-mpp-klibs-with-same-name/foo/foo/src/jsMain/kotlin/foofoo.kt @@ -0,0 +1,3 @@ +fun foofoo() { + println("foofoo") +} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/new-mpp-klibs-with-same-name/foo/foo/src/linuxMain/kotlin/foofoo.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/new-mpp-klibs-with-same-name/foo/foo/src/linuxMain/kotlin/foofoo.kt new file mode 100644 index 00000000000..2ade0e138ef --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/new-mpp-klibs-with-same-name/foo/foo/src/linuxMain/kotlin/foofoo.kt @@ -0,0 +1,5 @@ +import foo.* + +fun foofoo() { + println("foofoo: ${answer()}") +} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/new-mpp-klibs-with-same-name/foo/foo/src/nativeInterop/cinterop/bar.def b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/new-mpp-klibs-with-same-name/foo/foo/src/nativeInterop/cinterop/bar.def new file mode 100644 index 00000000000..841902a153d --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/new-mpp-klibs-with-same-name/foo/foo/src/nativeInterop/cinterop/bar.def @@ -0,0 +1,8 @@ +language = C +package = foo + +--- + +int answer() { + return 42; +} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/new-mpp-klibs-with-same-name/foo/src/commonMain/kotlin/foo.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/new-mpp-klibs-with-same-name/foo/src/commonMain/kotlin/foo.kt new file mode 100644 index 00000000000..ad824a81414 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/new-mpp-klibs-with-same-name/foo/src/commonMain/kotlin/foo.kt @@ -0,0 +1 @@ +expect fun foo() \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/new-mpp-klibs-with-same-name/foo/src/jsMain/kotlin/foo.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/new-mpp-klibs-with-same-name/foo/src/jsMain/kotlin/foo.kt new file mode 100644 index 00000000000..e35e9cd0d76 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/new-mpp-klibs-with-same-name/foo/src/jsMain/kotlin/foo.kt @@ -0,0 +1,4 @@ +actual fun foo() { + println("foo") + foofoo() +} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/new-mpp-klibs-with-same-name/foo/src/linuxMain/kotlin/foo.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/new-mpp-klibs-with-same-name/foo/src/linuxMain/kotlin/foo.kt new file mode 100644 index 00000000000..19eb42cfa83 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/new-mpp-klibs-with-same-name/foo/src/linuxMain/kotlin/foo.kt @@ -0,0 +1,6 @@ +import foo.* + +actual fun foo() { + println("foo: ${question()}") + foofoo() +} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/new-mpp-klibs-with-same-name/foo/src/nativeInterop/cinterop/bar.def b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/new-mpp-klibs-with-same-name/foo/src/nativeInterop/cinterop/bar.def new file mode 100644 index 00000000000..19c43e0959f --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/new-mpp-klibs-with-same-name/foo/src/nativeInterop/cinterop/bar.def @@ -0,0 +1,8 @@ +language = C +package = foo + +--- + +const char* question() { + return "To be, or not to be"; +} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/new-mpp-klibs-with-same-name/gradle.properties b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/new-mpp-klibs-with-same-name/gradle.properties new file mode 100644 index 00000000000..511353c7f9b --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/new-mpp-klibs-with-same-name/gradle.properties @@ -0,0 +1,2 @@ +kotlin.native.disableCompilerDaemon=true +kotlin.js.compiler=ir diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/new-mpp-klibs-with-same-name/settings.gradle.kts b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/new-mpp-klibs-with-same-name/settings.gradle.kts new file mode 100644 index 00000000000..1c2f6bede5d --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/new-mpp-klibs-with-same-name/settings.gradle.kts @@ -0,0 +1,10 @@ +pluginManagement { + repositories { + mavenLocal() + jcenter() + gradlePluginPortal() + } +} + +include("foo") +include("foo:foo") diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/new-mpp-klibs-with-same-name/src/commonMain/kotlin/main.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/new-mpp-klibs-with-same-name/src/commonMain/kotlin/main.kt new file mode 100644 index 00000000000..b585ff88912 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/new-mpp-klibs-with-same-name/src/commonMain/kotlin/main.kt @@ -0,0 +1,3 @@ +fun main() { + println("main") +} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/ir/CompilerFlags.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/ir/CompilerFlags.kt index 701ecec2ff9..fabca44594d 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/ir/CompilerFlags.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/ir/CompilerFlags.kt @@ -17,4 +17,6 @@ internal const val ENABLE_DCE = "-Xir-dce" internal const val GENERATE_D_TS = "-Xgenerate-dts" internal const val PRODUCE_JS = "-Xir-produce-js" -internal const val PRODUCE_UNZIPPED_KLIB = "-Xir-produce-klib-dir" \ No newline at end of file +internal const val PRODUCE_UNZIPPED_KLIB = "-Xir-produce-klib-dir" + +internal const val MODULE_NAME = "-Xir-module-name" \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/ir/KotlinJsIrTargetConfigurator.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/ir/KotlinJsIrTargetConfigurator.kt index 26bd552d7cd..8a89d395ae8 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/ir/KotlinJsIrTargetConfigurator.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/ir/KotlinJsIrTargetConfigurator.kt @@ -7,14 +7,15 @@ package org.jetbrains.kotlin.gradle.targets.js.ir import org.gradle.api.tasks.bundling.Zip import org.jetbrains.kotlin.gradle.dsl.KotlinJsOptions +import org.jetbrains.kotlin.gradle.plugin.* import org.jetbrains.kotlin.gradle.plugin.KotlinJsIrSourceSetProcessor -import org.jetbrains.kotlin.gradle.plugin.KotlinOnlyTargetConfigurator import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSetProcessor import org.jetbrains.kotlin.gradle.plugin.KotlinTargetWithTestsConfigurator import org.jetbrains.kotlin.gradle.targets.js.KotlinJsReportAggregatingTestRun import org.jetbrains.kotlin.gradle.tasks.KotlinTasksProvider import org.jetbrains.kotlin.gradle.testing.internal.kotlinTestRegistry import org.jetbrains.kotlin.gradle.testing.testTaskName +import org.jetbrains.kotlin.gradle.utils.klibModuleName open class KotlinJsIrTargetConfigurator(kotlinPluginVersion: String) : KotlinOnlyTargetConfigurator(true, true, kotlinPluginVersion), @@ -63,17 +64,25 @@ open class KotlinJsIrTargetConfigurator(kotlinPluginVersion: String) : override fun configureCompilations(target: KotlinJsIrTarget) { super.configureCompilations(target) - target.compilations.all { - it.compileKotlinTask.kotlinOptions { + target.compilations.all { compilation -> + compilation.compileKotlinTask.kotlinOptions { configureOptions() freeCompilerArgs += listOf( DISABLE_PRE_IR, PRODUCE_UNZIPPED_KLIB ) + + // Configure FQ module name to avoid cyclic dependencies in klib manifests (see KT-36721). + val baseName = if (compilation.name == KotlinCompilation.MAIN_COMPILATION_NAME) { + target.project.name + } else { + "${target.project.name}_${compilation.name}" + } + freeCompilerArgs += listOf("$MODULE_NAME=${target.project.klibModuleName(baseName)}") } - it.binaries + compilation.binaries .withType(JsIrBinary::class.java) .all { it.linkTask.configure { linkTask -> diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/tasks/KotlinNativeTasks.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/tasks/KotlinNativeTasks.kt index 83b1a2fe7df..8e8b427a843 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/tasks/KotlinNativeTasks.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/tasks/KotlinNativeTasks.kt @@ -24,6 +24,8 @@ import org.jetbrains.kotlin.gradle.plugin.LanguageSettingsBuilder import org.jetbrains.kotlin.gradle.plugin.cocoapods.asValidFrameworkName import org.jetbrains.kotlin.gradle.plugin.mpp.* import org.jetbrains.kotlin.gradle.plugin.sources.DefaultLanguageSettingsBuilder +import org.jetbrains.kotlin.gradle.utils.getValue +import org.jetbrains.kotlin.gradle.utils.klibModuleName import org.jetbrains.kotlin.konan.library.KLIB_INTEROP_IR_PROVIDER_IDENTIFIER import org.jetbrains.kotlin.konan.target.CompilerOutputKind import org.jetbrains.kotlin.konan.target.CompilerOutputKind.* @@ -297,6 +299,14 @@ open class KotlinNativeCompile : AbstractKotlinNativeCompile = mutableListOf().apply { addAll(super.buildCompilerArgs()) + // Configure FQ module name to avoid cyclic dependencies in klib manifests (see KT-36721). + addArg("-module-name", moduleName) + add("-Xshort-module-name=$shortModuleName") val friends = friendModule?.files if (friends != null && friends.isNotEmpty()) { addArg("-friend-modules", friends.map { it.absolutePath }.joinToString(File.pathSeparator)) @@ -885,15 +898,22 @@ open class CInteropProcess : DefaultTask() { val interopName: String @Internal get() = settings.name - val outputFileName: String - @Internal get() = with(CompilerOutputKind.LIBRARY) { - val baseName = settings.compilation.let { + val baseKlibName: String + @Internal get() { + val compilationPrefix = settings.compilation.let { if (it.isMainCompilation) project.name else it.name } - val suffix = suffix(konanTarget) - return "$baseName-cinterop-$interopName$suffix" + return "$compilationPrefix-cinterop-$interopName" } + val outputFileName: String + @Internal get() = with(CompilerOutputKind.LIBRARY) { + "$baseKlibName${suffix(konanTarget)}" + } + + val moduleName: String + @Input get() = project.klibModuleName(baseKlibName) + @get:Internal val outputFile: File get() = outputFileProvider.get() @@ -961,6 +981,10 @@ open class CInteropProcess : DefaultTask() { addArgs("-compiler-option", allHeadersDirs.map { "-I${it.absolutePath}" }) addArgs("-headerFilterAdditionalSearchPrefix", headerFilterDirs.map { it.absolutePath }) + if (project.konanVersion.isAtLeast(1, 4, 0)) { + addArg("-Xmodule-name", moduleName) + } + addAll(extraOpts) } diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/utils/klibUtils.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/utils/klibUtils.kt new file mode 100644 index 00000000000..d9b78b28228 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/utils/klibUtils.kt @@ -0,0 +1,11 @@ +/* + * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.gradle.utils + +import org.gradle.api.Project + +internal fun Project.klibModuleName(baseName: String = project.name): String = + if (group.toString().isNotEmpty()) "$group.$baseName" else baseName \ No newline at end of file