diff --git a/idea/idea-gradle-native/tests/org/jetbrains/kotlin/ide/konan/gradle/GradleNativeLibrariesPropagationTest.kt b/idea/idea-gradle-native/tests/org/jetbrains/kotlin/ide/konan/gradle/GradleNativeLibrariesPropagationTest.kt index ccabb8017ac..b1b55cef64b 100644 --- a/idea/idea-gradle-native/tests/org/jetbrains/kotlin/ide/konan/gradle/GradleNativeLibrariesPropagationTest.kt +++ b/idea/idea-gradle-native/tests/org/jetbrains/kotlin/ide/konan/gradle/GradleNativeLibrariesPropagationTest.kt @@ -8,7 +8,6 @@ package org.jetbrains.kotlin.ide.konan.gradle import com.intellij.openapi.roots.DependencyScope import org.jetbrains.kotlin.gradle.ModuleInfo import org.jetbrains.kotlin.gradle.checkProjectStructure -import org.jetbrains.kotlin.idea.codeInsight.gradle.GradleImportingTestCase import org.jetbrains.kotlin.idea.configuration.externalCompilerVersion import org.jetbrains.plugins.gradle.util.GradleConstants import org.junit.Test @@ -63,12 +62,47 @@ class GradleNativeLibrariesPropagationTest : TestCaseWithFakeKotlinNative() { } } + @Test + fun testCommonIOSWithDisabledPropagation() { + configureProject() + importProject() + + // No dependencies should be propagated. + checkProjectStructure( + myProject, + projectPath, + exhaustiveModuleList = false, + exhaustiveSourceSourceRootList = false, + exhaustiveDependencyList = false, + exhaustiveTestsList = false + ) { + + module("project_commonMain") { + noPlatformLibrary("Foundation") + noPlatformLibrary("CFNetwork") + noPlatformLibrary("WatchKit") + } + + module("project_appleMain") { + noPlatformLibrary("Foundation") + noPlatformLibrary("CFNetwork") + noPlatformLibrary("WatchKit") + } + + module("project_iosMain") { + noPlatformLibrary("Foundation") + noPlatformLibrary("CFNetwork") + noPlatformLibrary("WatchKit") + } + } + } + private val ModuleInfo.kotlinVersion: String get() = requireNotNull(module.externalCompilerVersion) { "External compiler version should not be null" } private fun ModuleInfo.noPlatformLibrary(libraryName: String, targets: Collection = testedTargets) { targets.forEach { target -> - assertNoDepForModule(module.name,"Kotlin/Native $kotlinVersion - $libraryName [$target]") + assertNoLibraryDepForModule(module.name, "Kotlin/Native $kotlinVersion - $libraryName [$target]") } } diff --git a/idea/idea-gradle/src/org/jetbrains/kotlin/idea/configuration/KotlinMPPGradleProjectResolver.kt b/idea/idea-gradle/src/org/jetbrains/kotlin/idea/configuration/KotlinMPPGradleProjectResolver.kt index dec31508089..21b5fd63602 100644 --- a/idea/idea-gradle/src/org/jetbrains/kotlin/idea/configuration/KotlinMPPGradleProjectResolver.kt +++ b/idea/idea-gradle/src/org/jetbrains/kotlin/idea/configuration/KotlinMPPGradleProjectResolver.kt @@ -577,12 +577,13 @@ open class KotlinMPPGradleProjectResolver : AbstractProjectResolverExtension() { val mergedDependencies = LinkedHashSet().apply { addAll(sourceSet.dependencies.mapNotNull { mppModel.dependencyMap[it] }) dependeeSourceSets.flatMapTo(this) { it.dependencies.mapNotNull { mppModel.dependencyMap[it] } } - if (sourceSet.actualPlatforms.getSinglePlatform() == KotlinPlatform.NATIVE) { - sourceSetToCompilations[sourceSet.name] - ?.takeIf { it.size > 1 } - ?.let { compilations -> - addAll(propagatedDependencies(compilations)) - } + if (mppModel.extraFeatures.isNativeDependencyPropagationEnabled + && mppModel.extraFeatures.isHMPPEnabled + && sourceSet.actualPlatforms.getSinglePlatform() == KotlinPlatform.NATIVE + ) { + sourceSetToCompilations[sourceSet.name]?.let { compilations -> + addAll(propagatedNativeDependencies(compilations)) + } } } buildDependencies( @@ -609,8 +610,8 @@ open class KotlinMPPGradleProjectResolver : AbstractProjectResolverExtension() { // Currently such special casing is available for Apple platforms // (iOS, watchOS and tvOS) and native Android (ARM, X86). // TODO: Do we need to support user's interop libraries too? - private fun propagatedDependencies(compilations: List): List { - if (compilations.isEmpty()) { + private fun propagatedNativeDependencies(compilations: List): List { + if (compilations.size <= 1) { return emptyList() } diff --git a/idea/idea-gradle/tests/org/jetbrains/kotlin/gradle/MultiplatformProjectImportingTest.kt b/idea/idea-gradle/tests/org/jetbrains/kotlin/gradle/MultiplatformProjectImportingTest.kt index 0e66e260fdf..8330d34ee4c 100644 --- a/idea/idea-gradle/tests/org/jetbrains/kotlin/gradle/MultiplatformProjectImportingTest.kt +++ b/idea/idea-gradle/tests/org/jetbrains/kotlin/gradle/MultiplatformProjectImportingTest.kt @@ -86,8 +86,8 @@ class MultiplatformProjectImportingTest : MultiplePluginVersionGradleImportingTe assertModuleModuleDepScope("jvm_test", "common2_test", DependencyScope.COMPILE) assertModuleModuleDepScope("js_main", "common1_main", DependencyScope.COMPILE) assertModuleModuleDepScope("js_test", "common1_test", DependencyScope.COMPILE) - assertNoDepForModule("js_main", "common2_main") - assertNoDepForModule("js_test", "common2_test") + assertNoModuleDepForModule("js_main", "common2_main") + assertNoModuleDepForModule("js_test", "common2_test") } @Test @@ -190,7 +190,7 @@ class MultiplatformProjectImportingTest : MultiplePluginVersionGradleImportingTe assertModuleModuleDepScope("project2_main", "project1_main", DependencyScope.COMPILE) assertModuleModuleDepScope("project3_main", "project2_main", DependencyScope.COMPILE) - assertNoDepForModule("project3_main", "project1_main") + assertNoModuleDepForModule("project3_main", "project1_main") TestCase.assertEquals( listOf("jar:///project2/build/libs/project2-jar.jar!/"), diff --git a/idea/idea-gradle/tests/org/jetbrains/kotlin/idea/codeInsight/gradle/ExternalSystemImportingTestCase.java b/idea/idea-gradle/tests/org/jetbrains/kotlin/idea/codeInsight/gradle/ExternalSystemImportingTestCase.java index 403ad3e58aa..81a29bfca42 100644 --- a/idea/idea-gradle/tests/org/jetbrains/kotlin/idea/codeInsight/gradle/ExternalSystemImportingTestCase.java +++ b/idea/idea-gradle/tests/org/jetbrains/kotlin/idea/codeInsight/gradle/ExternalSystemImportingTestCase.java @@ -32,10 +32,7 @@ import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil; import com.intellij.openapi.externalSystem.util.ExternalSystemUtil; import com.intellij.openapi.module.Module; import com.intellij.openapi.module.ModuleManager; -import com.intellij.openapi.roots.DependencyScope; -import com.intellij.openapi.roots.ModuleOrderEntry; -import com.intellij.openapi.roots.ModuleRootManager; -import com.intellij.openapi.roots.OrderEntry; +import com.intellij.openapi.roots.*; import com.intellij.openapi.util.Couple; import com.intellij.openapi.util.Ref; import com.intellij.openapi.util.text.StringUtil; @@ -247,10 +244,14 @@ public abstract class ExternalSystemImportingTestCase extends ExternalSystemTest expectedScopes, actualScopes); } - protected void assertNoDepForModule(String moduleName, String depName) { + protected void assertNoModuleDepForModule(String moduleName, String depName) { assertEmpty("No dependency '" + depName + "' was expected", collectModuleDeps(moduleName, depName, ModuleOrderEntry.class)); } + protected void assertNoLibraryDepForModule(String moduleName, String depName) { + assertEmpty("No dependency '" + depName + "' was expected", collectModuleDeps(moduleName, depName, LibraryOrderEntry.class)); + } + @NotNull private List getModuleModuleDeps(@NotNull String moduleName, @NotNull String depName) { return getModuleDep(moduleName, depName, ModuleOrderEntry.class); diff --git a/idea/kotlin-gradle-tooling/src/KotlinMPPGradleModel.kt b/idea/kotlin-gradle-tooling/src/KotlinMPPGradleModel.kt index f38ba55f319..4df81f053e9 100644 --- a/idea/kotlin-gradle-tooling/src/KotlinMPPGradleModel.kt +++ b/idea/kotlin-gradle-tooling/src/KotlinMPPGradleModel.kt @@ -158,6 +158,7 @@ interface KotlinTestTask : Serializable { interface ExtraFeatures : Serializable { val coroutinesState: String? val isHMPPEnabled: Boolean + val isNativeDependencyPropagationEnabled: Boolean } interface KotlinMPPGradleModel : Serializable { diff --git a/idea/kotlin-gradle-tooling/src/KotlinMPPGradleModelBuilder.kt b/idea/kotlin-gradle-tooling/src/KotlinMPPGradleModelBuilder.kt index 3205cc83a11..e0325028bce 100644 --- a/idea/kotlin-gradle-tooling/src/KotlinMPPGradleModelBuilder.kt +++ b/idea/kotlin-gradle-tooling/src/KotlinMPPGradleModelBuilder.kt @@ -59,7 +59,7 @@ class KotlinMPPGradleModelBuilder : ModelBuilderService { return KotlinMPPGradleModelImpl( filterOrphanSourceSets(sourceSetMap, targets, project), targets, - ExtraFeaturesImpl(coroutinesState, isHMPPEnabled(project)), + ExtraFeaturesImpl(coroutinesState, isHMPPEnabled(project), isNativeDependencyPropagationEnabled(project)), kotlinNativeHome, dependencyMapper.toDependencyMap() ) @@ -83,6 +83,10 @@ class KotlinMPPGradleModelBuilder : ModelBuilderService { return (project.findProperty("kotlin.mpp.enableGranularSourceSetsMetadata") as? String)?.toBoolean() ?: false } + private fun isNativeDependencyPropagationEnabled(project: Project): Boolean { + return (project.findProperty("kotlin.native.enableDependencyPropagation") as? String)?.toBoolean() ?: true + } + private fun reportUnresolvedDependencies(targets: Collection) { targets .asSequence() diff --git a/idea/kotlin-gradle-tooling/src/KotlinMPPGradleModelImpl.kt b/idea/kotlin-gradle-tooling/src/KotlinMPPGradleModelImpl.kt index a208f5cccb8..3536b028cb0 100644 --- a/idea/kotlin-gradle-tooling/src/KotlinMPPGradleModelImpl.kt +++ b/idea/kotlin-gradle-tooling/src/KotlinMPPGradleModelImpl.kt @@ -168,7 +168,8 @@ data class KotlinTestTaskImpl( data class ExtraFeaturesImpl( override val coroutinesState: String?, - override val isHMPPEnabled: Boolean + override val isHMPPEnabled: Boolean, + override val isNativeDependencyPropagationEnabled: Boolean ) : ExtraFeatures data class KotlinMPPGradleModelImpl( @@ -191,7 +192,11 @@ data class KotlinMPPGradleModelImpl( cloningCache[initialTarget] = it } }.toList(), - ExtraFeaturesImpl(mppModel.extraFeatures.coroutinesState, mppModel.extraFeatures.isHMPPEnabled), + ExtraFeaturesImpl( + mppModel.extraFeatures.coroutinesState, + mppModel.extraFeatures.isHMPPEnabled, + mppModel.extraFeatures.isNativeDependencyPropagationEnabled + ), mppModel.kotlinNativeHome, mppModel.dependencyMap.map { it.key to it.value.deepCopy(cloningCache) }.toMap() ) diff --git a/idea/testData/gradle/nativeLibraries/commonIOSWithDisabledPropagation/build.gradle.kts b/idea/testData/gradle/nativeLibraries/commonIOSWithDisabledPropagation/build.gradle.kts new file mode 100644 index 00000000000..b06591d67db --- /dev/null +++ b/idea/testData/gradle/nativeLibraries/commonIOSWithDisabledPropagation/build.gradle.kts @@ -0,0 +1,35 @@ +plugins { + kotlin("multiplatform") version "1.3.60-dev-2515" +} + +repositories { + jcenter() + maven { setUrl("https://dl.bintray.com/kotlin/kotlin-dev") } +} + +kotlin { + val jvm = jvm() + val iosDev = iosArm64() + val iosSim = iosX64() + val watchDev = watchosArm32() + val watchSim = watchosX86() + + sourceSets { + val commonMain by getting + val appleMain by creating { + dependsOn(commonMain) + } + + val iosMain by creating { + dependsOn(appleMain) + } + + configure(listOf(watchDev, watchSim)) { + compilations["main"].defaultSourceSet.dependsOn(appleMain) + } + + configure(listOf(iosDev, iosSim)) { + compilations["main"].defaultSourceSet.dependsOn(iosMain) + } + } +} diff --git a/idea/testData/gradle/nativeLibraries/commonIOSWithDisabledPropagation/gradle.properties b/idea/testData/gradle/nativeLibraries/commonIOSWithDisabledPropagation/gradle.properties new file mode 100644 index 00000000000..49bc8781d3e --- /dev/null +++ b/idea/testData/gradle/nativeLibraries/commonIOSWithDisabledPropagation/gradle.properties @@ -0,0 +1,3 @@ +org.jetbrains.kotlin.native.home=../kotlin-native-data-dir/kotlin-native-PLATFORM-VERSION +kotlin.mpp.enableGranularSourceSetsMetadata=true +kotlin.native.enableDependencyPropagation=false \ No newline at end of file diff --git a/idea/testData/gradle/nativeLibraries/commonIOSWithDisabledPropagation/settings.gradle.kts b/idea/testData/gradle/nativeLibraries/commonIOSWithDisabledPropagation/settings.gradle.kts new file mode 100644 index 00000000000..891ddc4234b --- /dev/null +++ b/idea/testData/gradle/nativeLibraries/commonIOSWithDisabledPropagation/settings.gradle.kts @@ -0,0 +1,7 @@ +pluginManagement { + repositories { + jcenter() + gradlePluginPortal() + maven { setUrl("https://dl.bintray.com/kotlin/kotlin-dev") } + } +} \ No newline at end of file