diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/KlibBasedMppIT.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/KlibBasedMppIT.kt index ac330cb307b..d31233a5f1e 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/KlibBasedMppIT.kt +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/KlibBasedMppIT.kt @@ -9,8 +9,10 @@ import org.jetbrains.kotlin.gradle.util.modify import org.jetbrains.kotlin.konan.target.HostManager import org.junit.Assume import java.io.File +import java.util.zip.ZipFile import kotlin.test.Test import kotlin.test.assertFalse +import kotlin.test.assertTrue class KlibBasedMppIT : BaseGradleIT() { override val defaultGradleVersion = GradleVersionRequired.AtLeast("6.0") @@ -32,6 +34,7 @@ class KlibBasedMppIT : BaseGradleIT() { fun testBuildWithPublishedDependency() = testBuildWithDependency { build(":$dependencyModuleName:publish") { assertSuccessful() + checkPublishedHostSpecificMetadata(this@build) } gradleBuildScript().appendText("\n" + """ @@ -81,7 +84,8 @@ class KlibBasedMppIT : BaseGradleIT() { val tasksToExecute = listOf( ":compileJvmAndJsMainKotlinMetadata", - ":compileLinuxMainKotlinMetadata" + ":compileLinuxMainKotlinMetadata", + ":compile${hostSpecificSourceSet.capitalize()}KotlinMetadata" ) build("assemble") { @@ -109,6 +113,51 @@ class KlibBasedMppIT : BaseGradleIT() { } } + private val hostSpecificSourceSet = when { + HostManager.hostIsMac -> "iosMain" + HostManager.hostIsLinux -> "embeddedMain" + HostManager.hostIsMingw -> "windowsMain" + else -> error("unexpected host") + } + + private fun checkPublishedHostSpecificMetadata(compiledProject: CompiledProject) = with(compiledProject) { + val groupDir = project.projectDir.resolve("repo/com/example") + + assertTasksExecuted(":$dependencyModuleName:compile${hostSpecificSourceSet.capitalize()}KotlinMetadata") + + // Check that the metadata JAR doesn't contain the host-specific source set entries, but contains the shared-Native source set + // that can be built on every host: + + ZipFile(groupDir.resolve("$dependencyModuleName-metadata/1.0/$dependencyModuleName-metadata-1.0.jar")).use { metadataJar -> + assertTrue { metadataJar.entries().asSequence().none { it.name.startsWith(hostSpecificSourceSet) } } + assertTrue { metadataJar.entries().asSequence().any { it.name.startsWith("linuxMain") } } + } + + // Then check that in the host-specific modules, there's a metadata artifact that contains the host-specific source set but not the + // common source sets: + + val hostSpecificTargets = when { + HostManager.hostIsMac -> listOf("iosArm64", "iosX64") + HostManager.hostIsLinux -> listOf("linuxMips32", "linuxMipsel32") + HostManager.hostIsMingw -> listOf("mingwX64", "mingwX86") + else -> error("unexpected host") + } + + hostSpecificTargets.forEach { targetName -> + val moduleName = "$dependencyModuleName-${targetName.toLowerCase()}" + ZipFile(groupDir.resolve("$moduleName/1.0/$moduleName-1.0-metadata.jar")).use { metadataJar -> + assertTrue { metadataJar.entries().asSequence().any { it.name.startsWith(hostSpecificSourceSet) } } + assertTrue { metadataJar.entries().asSequence().none { it.name.startsWith("commonMain") } } + } + } + + // Also check that the targets that don't include any host-specific sources don't even have the metadata artifact: + + groupDir.resolve("$dependencyModuleName-linuxx64/1.0/$dependencyModuleName-linuxx64-1.0-metadata.jar").let { metadataJar -> + assertTrue { !metadataJar.exists() } + } + } + private val transitiveDepModuleName = "transitive-dep" @Test diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/common-klib-lib-and-app/build.gradle.kts b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/common-klib-lib-and-app/build.gradle.kts index 3cc6d5946c3..5ee52d57aee 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/common-klib-lib-and-app/build.gradle.kts +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/common-klib-lib-and-app/build.gradle.kts @@ -18,6 +18,17 @@ kotlin { linuxX64() linuxArm64() + // Linux-specific targets – embedded: + linuxMips32() + linuxMipsel32() + + // macOS-specific targets - created by the ios() shortcut: + ios() + + // Windows-specific targets: + mingwX64() + mingwX86() + sourceSets { val commonMain by getting { dependencies { @@ -29,6 +40,11 @@ kotlin { dependsOn(commonMain) } + + configure(listOf(linuxX64(), linuxArm64())) { + compilations["main"].defaultSourceSet.dependsOn(linuxMain) + } + val jvmAndJsMain by creating { dependsOn(commonMain) } @@ -47,8 +63,20 @@ kotlin { } } - configure(listOf(linuxX64(), linuxArm64())) { - compilations["main"].defaultSourceSet.dependsOn(linuxMain) + val embeddedMain by creating { + dependsOn(commonMain) + } + + configure(listOf(linuxMips32(), linuxMipsel32())) { + compilations["main"].defaultSourceSet.dependsOn(embeddedMain) + } + + val windowsMain by creating { + dependsOn(commonMain) + } + + configure(listOf(mingwX64(), mingwX86())) { + compilations["main"].defaultSourceSet.dependsOn(windowsMain) } } } @@ -60,10 +88,7 @@ publishing { } tasks { - val skipCompilationOfTargets = setOf( - "linuxX64", - "linuxArm64" - ) + val skipCompilationOfTargets = kotlin.targets.matching { it.platformType.toString() == "native" }.names all { val target = name.removePrefix("compileKotlin").decapitalize() if (target in skipCompilationOfTargets) { diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/common-klib-lib-and-app/src/embeddedMain/kotlin/LibEmbeddedMain.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/common-klib-lib-and-app/src/embeddedMain/kotlin/LibEmbeddedMain.kt new file mode 100644 index 00000000000..9a1c9681d01 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/common-klib-lib-and-app/src/embeddedMain/kotlin/LibEmbeddedMain.kt @@ -0,0 +1,22 @@ +/* + * 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 com.h0tk3y.hmpp.klib.demo + +import kotlinx.cinterop.CArrayPointer + +actual class LibCommonMainExpect : LibCommonMainIface { + actual fun libCommonMainExpectFun(): Unit { + println("actualized in embeddedMain") + libCommonMainTopLevelFun() + println(CArrayPointer::class) + } + + fun additionalFunInEmbeddedActual() { + println("additional fun in lib embeddedMain") + } +} + +fun libLinuxMainFun(): LibCommonMainIface = LibCommonMainExpect() \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/common-klib-lib-and-app/src/iosMain/kotlin/LibIosMain.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/common-klib-lib-and-app/src/iosMain/kotlin/LibIosMain.kt new file mode 100644 index 00000000000..0542f919c38 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/common-klib-lib-and-app/src/iosMain/kotlin/LibIosMain.kt @@ -0,0 +1,22 @@ +/* + * 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 com.h0tk3y.hmpp.klib.demo + +import kotlinx.cinterop.CArrayPointer + +actual class LibCommonMainExpect : LibCommonMainIface { + actual fun libCommonMainExpectFun(): Unit { + println("actualized in iosMain") + libCommonMainTopLevelFun() + println(CArrayPointer::class) + } + + fun additionalFunInIosActual() { + println("additional fun in lib iosMain") + } +} + +fun libLinuxMainFun(): LibCommonMainIface = LibCommonMainExpect() \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/common-klib-lib-and-app/src/linuxMain/kotlin/LibLinuxMain.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/common-klib-lib-and-app/src/linuxMain/kotlin/LibLinuxMain.kt index 372a5b21461..d079d996710 100755 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/common-klib-lib-and-app/src/linuxMain/kotlin/LibLinuxMain.kt +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/common-klib-lib-and-app/src/linuxMain/kotlin/LibLinuxMain.kt @@ -9,7 +9,7 @@ import kotlinx.cinterop.CArrayPointer actual class LibCommonMainExpect : LibCommonMainIface { actual fun libCommonMainExpectFun(): Unit { - println("actualized in iosMain") + println("actualized in linuxMain") libCommonMainTopLevelFun() println(CArrayPointer::class) libCommonMainInternalFun() diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/common-klib-lib-and-app/src/windowsMain/kotlin/LibWindowsMain.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/common-klib-lib-and-app/src/windowsMain/kotlin/LibWindowsMain.kt new file mode 100644 index 00000000000..421e4451702 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/common-klib-lib-and-app/src/windowsMain/kotlin/LibWindowsMain.kt @@ -0,0 +1,22 @@ +/* + * 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 com.h0tk3y.hmpp.klib.demo + +import kotlinx.cinterop.CArrayPointer + +actual class LibCommonMainExpect : LibCommonMainIface { + actual fun libCommonMainExpectFun(): Unit { + println("actualized in windowsMain") + libCommonMainTopLevelFun() + println(CArrayPointer::class) + } + + fun additionalFunInWindowsActual() { + println("additional fun in lib windowsMain") + } +} + +fun libLinuxMainFun(): LibCommonMainIface = LibCommonMainExpect() \ No newline at end of file