[MPP] Enable cinterop commonization if CocoaPods plugin is applied
^KT-58712
This commit is contained in:
committed by
Space Team
parent
caaade1f4f
commit
4695d9088a
+15
-2
@@ -515,7 +515,7 @@ class CocoaPodsIT : KGPBaseTest() {
|
||||
@GradleTest
|
||||
fun testCinteropCommonizationOff(gradleVersion: GradleVersion) {
|
||||
nativeProjectWithCocoapodsAndIosAppPodFile(cocoapodsCommonizationProjectName, gradleVersion) {
|
||||
buildWithCocoapodsWrapper(":commonize") {
|
||||
buildWithCocoapodsWrapper(":commonize", "-Pkotlin.mpp.enableCInteropCommonization=false") {
|
||||
assertTasksExecuted(":commonizeNativeDistribution")
|
||||
assertTasksNotExecuted(":cinteropAFNetworkingIosArm64")
|
||||
assertTasksNotExecuted(":cinteropAFNetworkingIosX64")
|
||||
@@ -527,8 +527,21 @@ class CocoaPodsIT : KGPBaseTest() {
|
||||
@DisplayName("Cinterop commonization on")
|
||||
@GradleTest
|
||||
fun testCinteropCommonizationOn(gradleVersion: GradleVersion) {
|
||||
testCinteropCommonizationExecutes(gradleVersion, buildArguments=arrayOf("-Pkotlin.mpp.enableCInteropCommonization=true"))
|
||||
}
|
||||
|
||||
@DisplayName("Cinterop commonization unspecified")
|
||||
@GradleTest
|
||||
fun testCinteropCommonizationUnspecified(gradleVersion: GradleVersion) {
|
||||
testCinteropCommonizationExecutes(gradleVersion, buildArguments=emptyArray())
|
||||
}
|
||||
|
||||
private fun testCinteropCommonizationExecutes(
|
||||
gradleVersion: GradleVersion,
|
||||
buildArguments: Array<String>
|
||||
) {
|
||||
nativeProjectWithCocoapodsAndIosAppPodFile(cocoapodsCommonizationProjectName, gradleVersion) {
|
||||
buildWithCocoapodsWrapper(":commonize", "-Pkotlin.mpp.enableCInteropCommonization=true") {
|
||||
buildWithCocoapodsWrapper(":commonize", *buildArguments) {
|
||||
assertTasksExecuted(":commonizeNativeDistribution")
|
||||
assertTasksExecuted(":cinteropAFNetworkingIosArm64")
|
||||
assertTasksExecuted(":cinteropAFNetworkingIosX64")
|
||||
|
||||
+9
-2
@@ -380,9 +380,16 @@ internal class PropertiesProvider private constructor(private val project: Proje
|
||||
/**
|
||||
* Enables experimental commonization of user defined c-interop libraries.
|
||||
*/
|
||||
val enableCInteropCommonization: Boolean
|
||||
get() = booleanProperty(KOTLIN_MPP_ENABLE_CINTEROP_COMMONIZATION) ?: false
|
||||
val enableCInteropCommonization: Boolean?
|
||||
get() = booleanProperty(KOTLIN_MPP_ENABLE_CINTEROP_COMMONIZATION)
|
||||
|
||||
private val enableCInteropCommonizationSetByExternalPluginKey = "kotlin.internal.mpp.enableCInteropCommonization.setByExternalPlugin"
|
||||
|
||||
internal var enableCInteropCommonizationSetByExternalPlugin: Boolean?
|
||||
get() = booleanProperty(enableCInteropCommonizationSetByExternalPluginKey)
|
||||
set(value) {
|
||||
project.extensions.extraProperties.set(enableCInteropCommonizationSetByExternalPluginKey, "$value")
|
||||
}
|
||||
|
||||
val commonizerLogLevel: String?
|
||||
get() = this.property("kotlin.mpp.commonizerLogLevel")
|
||||
|
||||
+2
-1
@@ -12,6 +12,7 @@ import org.jetbrains.kotlin.gradle.plugin.diagnostics.KotlinGradleProjectChecker
|
||||
import org.jetbrains.kotlin.gradle.plugin.diagnostics.KotlinToolingDiagnostics
|
||||
import org.jetbrains.kotlin.gradle.plugin.diagnostics.KotlinToolingDiagnosticsCollector
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinSharedNativeCompilation
|
||||
import org.jetbrains.kotlin.gradle.targets.native.internal.*
|
||||
import org.jetbrains.kotlin.gradle.targets.native.internal.CInteropCommonizerDependent
|
||||
import org.jetbrains.kotlin.gradle.targets.native.internal.from
|
||||
import org.jetbrains.kotlin.gradle.targets.native.internal.isAllowCommonizer
|
||||
@@ -23,7 +24,7 @@ internal object DisabledCinteropCommonizationInHmppProjectChecker : KotlinGradle
|
||||
|
||||
if (multiplatformExtension == null
|
||||
|| !project.isAllowCommonizer()
|
||||
|| kotlinPropertiesProvider.enableCInteropCommonization
|
||||
|| project.cInteropCommonizationEnabled()
|
||||
|| kotlinPropertiesProvider.ignoreDisabledCInteropCommonization
|
||||
) return
|
||||
|
||||
|
||||
+2
-1
@@ -18,6 +18,7 @@ import org.jetbrains.kotlin.gradle.targets.native.internal.cinteropMetadataDepen
|
||||
import org.jetbrains.kotlin.gradle.targets.native.internal.commonizerTarget
|
||||
import org.jetbrains.kotlin.gradle.targets.native.internal.createCInteropMetadataDependencyClasspathForIde
|
||||
import org.jetbrains.kotlin.gradle.tasks.locateTask
|
||||
import org.jetbrains.kotlin.gradle.utils.future
|
||||
|
||||
internal object IdeCInteropMetadataDependencyClasspathResolver : IdeDependencyResolver, IdeDependencyResolver.WithBuildDependencies {
|
||||
override fun resolve(sourceSet: KotlinSourceSet): Set<IdeaKotlinDependency> {
|
||||
@@ -26,7 +27,7 @@ internal object IdeCInteropMetadataDependencyClasspathResolver : IdeDependencyRe
|
||||
val project = sourceSet.project
|
||||
project.locateDependencyTask(sourceSet) ?: return emptySet()
|
||||
|
||||
val cinteropFiles = project.createCInteropMetadataDependencyClasspathForIde(sourceSet)
|
||||
val cinteropFiles = project.future { createCInteropMetadataDependencyClasspathForIde(sourceSet) }.getOrThrow()
|
||||
return project.resolveCInteropDependencies(cinteropFiles)
|
||||
}
|
||||
|
||||
|
||||
+3
-1
@@ -12,6 +12,8 @@ import org.jetbrains.kotlin.gradle.plugin.ide.IdeDependencyResolver
|
||||
import org.jetbrains.kotlin.gradle.plugin.sources.DefaultKotlinSourceSet
|
||||
import org.jetbrains.kotlin.gradle.targets.native.internal.cinteropCommonizerDependencies
|
||||
import org.jetbrains.kotlin.gradle.targets.native.internal.copyCommonizeCInteropForIdeTask
|
||||
import org.jetbrains.kotlin.gradle.utils.future
|
||||
import org.jetbrains.kotlin.gradle.utils.lenient
|
||||
|
||||
internal object IdeCommonizedCinteropDependencyResolver : IdeDependencyResolver, IdeDependencyResolver.WithBuildDependencies {
|
||||
override fun resolve(sourceSet: KotlinSourceSet): Set<IdeaKotlinDependency> {
|
||||
@@ -23,6 +25,6 @@ internal object IdeCommonizedCinteropDependencyResolver : IdeDependencyResolver,
|
||||
}
|
||||
|
||||
override fun dependencies(project: Project): Iterable<Any> {
|
||||
return listOfNotNull(project.copyCommonizeCInteropForIdeTask)
|
||||
return listOfNotNull(project.future { copyCommonizeCInteropForIdeTask() }.getOrThrow())
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -85,8 +85,8 @@ private suspend fun KotlinMultiplatformExtension.sourceSetsMetadataOutputs(): Ma
|
||||
private suspend fun KotlinMultiplatformExtension.cInteropMetadataOfSourceSets(
|
||||
sourceSets: Iterable<KotlinSourceSet>
|
||||
): Map<KotlinSourceSet, SourceSetMetadataOutputs.CInterop?> {
|
||||
val taskForCLI = project.commonizeCInteropTask ?: return emptyMap()
|
||||
val taskForIde = project.copyCommonizeCInteropForIdeTask ?: return emptyMap()
|
||||
val taskForCLI = project.commonizeCInteropTask() ?: return emptyMap()
|
||||
val taskForIde = project.copyCommonizeCInteropForIdeTask() ?: return emptyMap()
|
||||
|
||||
return sourceSets.associateWith { sourceSet ->
|
||||
val dependent = CInteropCommonizerDependent.from(sourceSet) ?: return@associateWith null
|
||||
|
||||
+7
-2
@@ -37,6 +37,7 @@ import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.copyAttributes
|
||||
import org.jetbrains.kotlin.gradle.plugin.sources.DefaultLanguageSettingsBuilder
|
||||
import org.jetbrains.kotlin.gradle.targets.metadata.isKotlinGranularMetadataEnabled
|
||||
import org.jetbrains.kotlin.gradle.targets.native.*
|
||||
import org.jetbrains.kotlin.gradle.targets.native.internal.*
|
||||
import org.jetbrains.kotlin.gradle.targets.native.internal.commonizeCInteropTask
|
||||
import org.jetbrains.kotlin.gradle.targets.native.internal.createCInteropApiElementsKlibArtifact
|
||||
import org.jetbrains.kotlin.gradle.targets.native.internal.locateOrCreateCInteropApiElementsConfiguration
|
||||
@@ -149,8 +150,12 @@ open class KotlinNativeTargetConfigurator<T : KotlinNativeTarget> : AbstractKotl
|
||||
it.enabled = compilation.konanTarget.enabledOnCurrentHost
|
||||
}
|
||||
|
||||
project.commonizeCInteropTask?.configure { commonizeCInteropTask ->
|
||||
commonizeCInteropTask.from(interopTask)
|
||||
|
||||
project.launch {
|
||||
project.commonizeCInteropTask()?.configure { commonizeCInteropTask ->
|
||||
commonizeCInteropTask.from(interopTask)
|
||||
}
|
||||
project.copyCommonizeCInteropForIdeTask()
|
||||
}
|
||||
|
||||
val interopOutput = project.files(interopTask.map { it.outputFileProvider })
|
||||
|
||||
+6
@@ -21,6 +21,7 @@ import org.gradle.api.tasks.wrapper.Wrapper
|
||||
import org.jetbrains.kotlin.daemon.common.trimQuotes
|
||||
import org.jetbrains.kotlin.gradle.dsl.*
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation
|
||||
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.Companion.kotlinPropertiesProvider
|
||||
import org.jetbrains.kotlin.gradle.plugin.addExtension
|
||||
import org.jetbrains.kotlin.gradle.plugin.cocoapods.CocoapodsExtension.CocoapodsDependency
|
||||
import org.jetbrains.kotlin.gradle.plugin.diagnostics.reportDiagnostic
|
||||
@@ -825,10 +826,15 @@ open class KotlinCocoapodsPlugin : Plugin<Project> {
|
||||
}
|
||||
}
|
||||
|
||||
// Enable cinterop commonization if it is not explicitly specified
|
||||
private fun Project.enableCInteropCommonizationSetByExternalPlugin() {
|
||||
kotlinPropertiesProvider.enableCInteropCommonizationSetByExternalPlugin = true
|
||||
}
|
||||
|
||||
override fun apply(project: Project): Unit = with(project) {
|
||||
|
||||
pluginManager.withPlugin("kotlin-multiplatform") {
|
||||
enableCInteropCommonizationSetByExternalPlugin()
|
||||
val kotlinExtension = project.multiplatformExtension
|
||||
val kotlinArtifactsExtension = project.kotlinArtifactsExtension
|
||||
val cocoapodsExtension = project.objects.newInstance(CocoapodsExtension::class.java, this)
|
||||
|
||||
+1
-1
@@ -22,7 +22,7 @@ internal fun Project.includeCommonizedCInteropMetadata(
|
||||
}
|
||||
|
||||
internal suspend fun Project.includeCommonizedCInteropMetadata(metadataKlib: Zip, compilation: KotlinSharedNativeCompilation) {
|
||||
val commonizerTask = commonizeCInteropTask?.get() ?: return
|
||||
val commonizerTask = commonizeCInteropTask()?.get() ?: return
|
||||
val commonizerDependencyToken = CInteropCommonizerDependent.from(compilation) ?: return
|
||||
val outputDirectory = commonizerTask.commonizedOutputDirectory(commonizerDependencyToken) ?: return
|
||||
|
||||
|
||||
+5
-5
@@ -30,8 +30,8 @@ internal fun Project.setupCInteropCommonizerDependencies() {
|
||||
}
|
||||
}
|
||||
|
||||
private fun Project.setupCInteropCommonizerDependenciesForCompilation(compilation: KotlinSharedNativeCompilation) {
|
||||
val cinteropCommonizerTask = project.commonizeCInteropTask ?: return
|
||||
private fun Project.setupCInteropCommonizerDependenciesForCompilation(compilation: KotlinSharedNativeCompilation) = launch {
|
||||
val cinteropCommonizerTask = project.commonizeCInteropTask() ?: return@launch
|
||||
|
||||
compilation.compileDependencyFiles += filesProvider {
|
||||
val cinteropCommonizerDependent = future { CInteropCommonizerDependent.from(compilation) }.getOrThrow()
|
||||
@@ -45,15 +45,15 @@ private fun Project.setupCInteropCommonizerDependenciesForCompilation(compilatio
|
||||
* This will use the [Project.copyCommonizeCInteropForIdeTask] over the regular cinterop commonization task.
|
||||
* The copying task prevent red code within the IDE after cleaning the build output.
|
||||
*/
|
||||
private fun Project.setupCInteropCommonizerDependenciesForIde(sourceSet: DefaultKotlinSourceSet) {
|
||||
private fun Project.setupCInteropCommonizerDependenciesForIde(sourceSet: DefaultKotlinSourceSet) = launch {
|
||||
addIntransitiveMetadataDependencyIfPossible(sourceSet, cinteropCommonizerDependencies(sourceSet))
|
||||
}
|
||||
|
||||
internal fun Project.cinteropCommonizerDependencies(sourceSet: DefaultKotlinSourceSet): FileCollection {
|
||||
val cinteropCommonizerTask = project.copyCommonizeCInteropForIdeTask ?: return project.files()
|
||||
|
||||
return filesProvider {
|
||||
future {
|
||||
val cinteropCommonizerTask = project.copyCommonizeCInteropForIdeTask() ?: return@future project.files()
|
||||
|
||||
val directlyDependent = CInteropCommonizerDependent.from(sourceSet)
|
||||
val associateDependent = CInteropCommonizerDependent.fromAssociateCompilations(sourceSet)
|
||||
|
||||
|
||||
+5
-4
@@ -16,13 +16,14 @@ import org.jetbrains.kotlin.gradle.plugin.mpp.metadataDependencyResolutionsOrEmp
|
||||
import org.jetbrains.kotlin.gradle.plugin.sources.DefaultKotlinSourceSet
|
||||
import org.jetbrains.kotlin.gradle.plugin.sources.metadataTransformation
|
||||
import org.jetbrains.kotlin.gradle.utils.filesProvider
|
||||
import org.jetbrains.kotlin.gradle.utils.future
|
||||
import java.io.File
|
||||
|
||||
internal fun Project.createCInteropMetadataDependencyClasspath(sourceSet: DefaultKotlinSourceSet): FileCollection {
|
||||
internal suspend fun Project.createCInteropMetadataDependencyClasspath(sourceSet: DefaultKotlinSourceSet): FileCollection {
|
||||
return createCInteropMetadataDependencyClasspath(sourceSet, forIde = false)
|
||||
}
|
||||
|
||||
internal fun Project.createCInteropMetadataDependencyClasspathForIde(sourceSet: DefaultKotlinSourceSet): FileCollection {
|
||||
internal suspend fun Project.createCInteropMetadataDependencyClasspathForIde(sourceSet: DefaultKotlinSourceSet): FileCollection {
|
||||
return createCInteropMetadataDependencyClasspath(sourceSet, forIde = true)
|
||||
}
|
||||
|
||||
@@ -30,7 +31,7 @@ internal fun Project.createCInteropMetadataDependencyClasspathForIde(sourceSet:
|
||||
* @param forIde: A different task for dependency transformation will be used. This task will not use the regular 'build' directory
|
||||
* as transformation output to ensure IDE still being able to resolve the dependencies even when the project is cleaned.
|
||||
*/
|
||||
internal fun Project.createCInteropMetadataDependencyClasspath(sourceSet: DefaultKotlinSourceSet, forIde: Boolean): FileCollection {
|
||||
internal suspend fun Project.createCInteropMetadataDependencyClasspath(sourceSet: DefaultKotlinSourceSet, forIde: Boolean): FileCollection {
|
||||
val dependencyTransformationTask = if (forIde) locateOrRegisterCInteropMetadataDependencyTransformationTaskForIde(sourceSet)
|
||||
else locateOrRegisterCInteropMetadataDependencyTransformationTask(sourceSet)
|
||||
if (dependencyTransformationTask == null) return project.files()
|
||||
@@ -99,7 +100,7 @@ private fun Project.createCInteropMetadataDependencyClasspathFromAssociatedCompi
|
||||
.filter { (_, otherCommonizerTarget) -> otherCommonizerTarget.targets.containsAll(commonizerTarget.targets) }
|
||||
.minByOrNull { (_, otherCommonizerTarget) -> otherCommonizerTarget.targets.size } ?: return@files emptySet<File>()
|
||||
|
||||
createCInteropMetadataDependencyClasspath(associatedSourceSet, forIde)
|
||||
project.future { createCInteropMetadataDependencyClasspath(associatedSourceSet, forIde) }.getOrThrow()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+4
-4
@@ -41,10 +41,10 @@ internal val KotlinSourceSet.cinteropMetadataDependencyTransformationTaskName: S
|
||||
internal val KotlinSourceSet.cinteropMetadataDependencyTransformationForIdeTaskName: String
|
||||
get() = lowerCamelCaseName("transform", name, "CInteropDependenciesMetadataForIde")
|
||||
|
||||
internal fun Project.locateOrRegisterCInteropMetadataDependencyTransformationTask(
|
||||
internal suspend fun Project.locateOrRegisterCInteropMetadataDependencyTransformationTask(
|
||||
sourceSet: DefaultKotlinSourceSet,
|
||||
): TaskProvider<CInteropMetadataDependencyTransformationTask>? {
|
||||
if (!kotlinPropertiesProvider.enableCInteropCommonization) return null
|
||||
if (!cInteropCommonizationEnabled()) return null
|
||||
|
||||
return locateOrRegisterTask(
|
||||
sourceSet.cinteropMetadataDependencyTransformationTaskName,
|
||||
@@ -61,10 +61,10 @@ internal fun Project.locateOrRegisterCInteropMetadataDependencyTransformationTas
|
||||
)
|
||||
}
|
||||
|
||||
internal fun Project.locateOrRegisterCInteropMetadataDependencyTransformationTaskForIde(
|
||||
internal suspend fun Project.locateOrRegisterCInteropMetadataDependencyTransformationTaskForIde(
|
||||
sourceSet: DefaultKotlinSourceSet,
|
||||
): TaskProvider<CInteropMetadataDependencyTransformationTask>? {
|
||||
if (!kotlinPropertiesProvider.enableCInteropCommonization) return null
|
||||
if (!cInteropCommonizationEnabled()) return null
|
||||
|
||||
return locateOrRegisterTask(
|
||||
sourceSet.cinteropMetadataDependencyTransformationForIdeTaskName,
|
||||
|
||||
+56
-48
@@ -16,8 +16,11 @@ import org.gradle.api.tasks.TaskProvider
|
||||
import org.gradle.work.DisableCachingByDefault
|
||||
import org.jetbrains.kotlin.compilerRunner.maybeCreateCommonizerClasspathConfiguration
|
||||
import org.jetbrains.kotlin.gradle.internal.isInIdeaSync
|
||||
import org.jetbrains.kotlin.gradle.plugin.*
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinPluginLifecycle
|
||||
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider
|
||||
import org.jetbrains.kotlin.gradle.plugin.getKotlinPluginVersion
|
||||
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.Companion.kotlinPropertiesProvider
|
||||
import org.jetbrains.kotlin.gradle.plugin.await
|
||||
import org.jetbrains.kotlin.gradle.plugin.ide.Idea222Api
|
||||
import org.jetbrains.kotlin.gradle.plugin.ide.ideaImportDependsOn
|
||||
import org.jetbrains.kotlin.gradle.plugin.whenEvaluated
|
||||
@@ -26,7 +29,12 @@ import org.jetbrains.kotlin.gradle.tasks.locateOrRegisterTask
|
||||
import java.io.File
|
||||
import javax.inject.Inject
|
||||
|
||||
internal val Project.isCInteropCommonizationEnabled: Boolean get() = PropertiesProvider(this).enableCInteropCommonization
|
||||
internal suspend fun Project.cInteropCommonizationEnabled(): Boolean {
|
||||
KotlinPluginLifecycle.Stage.AfterEvaluateBuildscript.await()
|
||||
return kotlinPropertiesProvider.enableCInteropCommonization
|
||||
?: kotlinPropertiesProvider.enableCInteropCommonizationSetByExternalPlugin
|
||||
?: false
|
||||
}
|
||||
|
||||
internal val Project.isIntransitiveMetadataConfigurationEnabled: Boolean
|
||||
get() = PropertiesProvider(this).enableIntransitiveMetadataConfiguration
|
||||
@@ -67,55 +75,55 @@ internal val Project.runCommonizerTask: TaskProvider<Task>
|
||||
}
|
||||
)
|
||||
|
||||
internal val Project.commonizeCInteropTask: TaskProvider<CInteropCommonizerTask>?
|
||||
get() {
|
||||
if (isCInteropCommonizationEnabled) {
|
||||
return locateOrRegisterTask(
|
||||
"commonizeCInterop",
|
||||
invokeWhenRegistered = {
|
||||
val task = this
|
||||
private const val commonizeCInteropTaskName = "commonizeCInterop"
|
||||
|
||||
internal suspend fun Project.commonizeCInteropTask(): TaskProvider<CInteropCommonizerTask>? {
|
||||
if (cInteropCommonizationEnabled()) {
|
||||
return locateOrRegisterTask(
|
||||
commonizeCInteropTaskName,
|
||||
invokeWhenRegistered = {
|
||||
val task = this
|
||||
commonizeTask.dependsOn(this)
|
||||
whenEvaluated {
|
||||
commonizeNativeDistributionTask?.let(task::dependsOn)
|
||||
}
|
||||
},
|
||||
configureTask = {
|
||||
group = "interop"
|
||||
description = "Invokes the commonizer on c-interop bindings of the project"
|
||||
|
||||
kotlinPluginVersion.set(getKotlinPluginVersion())
|
||||
commonizerClasspath.from(project.maybeCreateCommonizerClasspathConfiguration())
|
||||
customJvmArgs.set(PropertiesProvider(project).commonizerJvmArgs)
|
||||
}
|
||||
)
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
internal suspend fun Project.copyCommonizeCInteropForIdeTask(): TaskProvider<CopyCommonizeCInteropForIdeTask>? {
|
||||
val commonizeCInteropTask = commonizeCInteropTask()
|
||||
if (commonizeCInteropTask != null) {
|
||||
return locateOrRegisterTask(
|
||||
"copyCommonizeCInteropForIde",
|
||||
invokeWhenRegistered = {
|
||||
@OptIn(Idea222Api::class)
|
||||
ideaImportDependsOn(this)
|
||||
|
||||
/* Older IDEs will still call 'runCommonizer' -> 'commonize' tasks */
|
||||
if (isInIdeaSync) {
|
||||
commonizeTask.dependsOn(this)
|
||||
whenEvaluated {
|
||||
commonizeNativeDistributionTask?.let(task::dependsOn)
|
||||
}
|
||||
},
|
||||
configureTask = {
|
||||
group = "interop"
|
||||
description = "Invokes the commonizer on c-interop bindings of the project"
|
||||
|
||||
kotlinPluginVersion.set(getKotlinPluginVersion())
|
||||
commonizerClasspath.from(project.maybeCreateCommonizerClasspathConfiguration())
|
||||
customJvmArgs.set(PropertiesProvider(project).commonizerJvmArgs)
|
||||
}
|
||||
)
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
internal val Project.copyCommonizeCInteropForIdeTask: TaskProvider<CopyCommonizeCInteropForIdeTask>?
|
||||
get() {
|
||||
val commonizeCInteropTask = commonizeCInteropTask
|
||||
if (commonizeCInteropTask != null) {
|
||||
return locateOrRegisterTask(
|
||||
"copyCommonizeCInteropForIde",
|
||||
invokeWhenRegistered = {
|
||||
@OptIn(Idea222Api::class)
|
||||
ideaImportDependsOn(this)
|
||||
|
||||
/* Older IDEs will still call 'runCommonizer' -> 'commonize' tasks */
|
||||
if (isInIdeaSync) {
|
||||
commonizeTask.dependsOn(this)
|
||||
}
|
||||
},
|
||||
configureTask = {
|
||||
group = "interop"
|
||||
description = "Copies the output of ${commonizeCInteropTask.get().name} into " +
|
||||
"the root projects .gradle folder for the IDE"
|
||||
}
|
||||
)
|
||||
}
|
||||
return null
|
||||
},
|
||||
configureTask = {
|
||||
group = "interop"
|
||||
description = "Copies the output of $commonizeCInteropTaskName into " +
|
||||
"the root projects .gradle folder for the IDE"
|
||||
}
|
||||
)
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
internal val Project.commonizeNativeDistributionTask: TaskProvider<NativeDistributionCommonizerTask>?
|
||||
get() {
|
||||
|
||||
+2
-1
@@ -9,13 +9,14 @@ import org.gradle.api.provider.Provider
|
||||
import org.gradle.api.tasks.*
|
||||
import org.gradle.work.DisableCachingByDefault
|
||||
import org.gradle.work.NormalizeLineEndings
|
||||
import org.jetbrains.kotlin.gradle.utils.future
|
||||
import java.io.File
|
||||
|
||||
@DisableCachingByDefault
|
||||
internal open class CopyCommonizeCInteropForIdeTask : AbstractCInteropCommonizerTask() {
|
||||
|
||||
private val commonizeCInteropTask: TaskProvider<CInteropCommonizerTask>
|
||||
get() = project.commonizeCInteropTask ?: throw IllegalStateException("Missing commonizeCInteropTask")
|
||||
get() = project.future { project.commonizeCInteropTask() }.getOrThrow() ?: throw IllegalStateException("Missing commonizeCInteropTask")
|
||||
|
||||
@get:IgnoreEmptyDirectories
|
||||
@get:InputFiles
|
||||
|
||||
+15
-7
@@ -7,7 +7,6 @@
|
||||
|
||||
package org.jetbrains.kotlin.gradle.unitTests
|
||||
|
||||
import org.gradle.api.GradleException
|
||||
import org.jetbrains.kotlin.commonizer.CommonizerTarget
|
||||
import org.jetbrains.kotlin.commonizer.SharedCommonizerTarget
|
||||
import org.jetbrains.kotlin.gradle.util.MultiplatformExtensionTest
|
||||
@@ -19,12 +18,17 @@ import org.jetbrains.kotlin.gradle.targets.native.internal.commonizeCInteropTask
|
||||
import org.jetbrains.kotlin.gradle.util.enableCInteropCommonization
|
||||
import org.jetbrains.kotlin.gradle.util.main
|
||||
import org.jetbrains.kotlin.gradle.util.runLifecycleAwareTest
|
||||
import org.jetbrains.kotlin.gradle.utils.Future
|
||||
import org.jetbrains.kotlin.gradle.utils.future
|
||||
import org.jetbrains.kotlin.konan.target.KonanTarget.*
|
||||
import kotlin.test.*
|
||||
|
||||
class CInteropCommonizerTaskTest : MultiplatformExtensionTest() {
|
||||
|
||||
private val task: CInteropCommonizerTask get() = project.commonizeCInteropTask?.get() ?: fail("Missing commonizeCInteropTask")
|
||||
private val task: Future<CInteropCommonizerTask>
|
||||
get() = project.future {
|
||||
project.commonizeCInteropTask()?.get() ?: fail("Missing commonizeCInteropTask")
|
||||
}
|
||||
|
||||
@BeforeTest
|
||||
override fun setup() {
|
||||
@@ -34,7 +38,7 @@ class CInteropCommonizerTaskTest : MultiplatformExtensionTest() {
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `commonizeCInteropTask configuration - avoids cinterop task configuration`() {
|
||||
fun `commonizeCInteropTask configuration - avoids cinterop task configuration`() = project.runLifecycleAwareTest {
|
||||
project.enableCInteropCommonization(true)
|
||||
|
||||
listOf(
|
||||
@@ -46,12 +50,12 @@ class CInteropCommonizerTaskTest : MultiplatformExtensionTest() {
|
||||
}
|
||||
}
|
||||
|
||||
project.commonizeCInteropTask?.get() ?: fail("Expected commonizeCInteropTask to be present")
|
||||
project.evaluate()
|
||||
project.commonizeCInteropTask()?.get() ?: fail("Expected commonizeCInteropTask to be present")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `nativeMain linux macos`() = project.runLifecycleAwareTest {
|
||||
val task = this@CInteropCommonizerTaskTest.task.await()
|
||||
val linuxInterop = kotlin.linuxX64("linux").compilations.getByName("main").cinterops.create("anyInteropName")
|
||||
val macosInterop = kotlin.macosX64("macos").compilations.getByName("main").cinterops.create("anyInteropName")
|
||||
|
||||
@@ -106,6 +110,7 @@ class CInteropCommonizerTaskTest : MultiplatformExtensionTest() {
|
||||
|
||||
@Test
|
||||
fun `nativeMain iosMain linux macos iosX64 iosArm64`() = project.runLifecycleAwareTest {
|
||||
val task = this@CInteropCommonizerTaskTest.task.await()
|
||||
val linuxInterop = kotlin.linuxX64("linux").compilations.getByName("main").cinterops.create("anyInteropName").identifier
|
||||
val macosInterop = kotlin.macosX64("macos").compilations.getByName("main").cinterops.create("anyInteropName").identifier
|
||||
val iosX64Interop = kotlin.iosX64("iosX64").compilations.getByName("main").cinterops.create("anyInteropName").identifier
|
||||
@@ -159,8 +164,9 @@ class CInteropCommonizerTaskTest : MultiplatformExtensionTest() {
|
||||
}
|
||||
|
||||
private fun `nativeTest nativeMain linux macos`(
|
||||
nativeTestDependsOnNativeMain: Boolean
|
||||
nativeTestDependsOnNativeMain: Boolean,
|
||||
) = project.runLifecycleAwareTest {
|
||||
val task = this@CInteropCommonizerTaskTest.task.await()
|
||||
val linuxInterop = kotlin.linuxX64("linux").compilations.getByName("main").cinterops.create("anyInteropName").identifier
|
||||
val macosInterop = kotlin.macosX64("macos").compilations.getByName("main").cinterops.create("anyInteropName").identifier
|
||||
|
||||
@@ -222,8 +228,9 @@ class CInteropCommonizerTaskTest : MultiplatformExtensionTest() {
|
||||
}
|
||||
|
||||
private fun `nativeTest nativeMain linux macos - test compilation defines custom cinterop`(
|
||||
nativeTestDependsOnNativeMain: Boolean
|
||||
nativeTestDependsOnNativeMain: Boolean,
|
||||
) = project.runLifecycleAwareTest {
|
||||
val task = this@CInteropCommonizerTaskTest.task.await()
|
||||
val linuxInterop = kotlin.linuxX64("linux").compilations.getByName("main").cinterops.create("anyInteropName").identifier
|
||||
val macosInterop = kotlin.macosX64("macos").compilations.getByName("main").cinterops.create("anyInteropName").identifier
|
||||
kotlin.linuxX64("linux").compilations.getByName("test").cinterops.create("anyOtherName").identifier
|
||||
@@ -285,6 +292,7 @@ class CInteropCommonizerTaskTest : MultiplatformExtensionTest() {
|
||||
}
|
||||
|
||||
private fun `hierarchical project`(testSourceSetsDependOnMainSourceSets: Boolean) = project.runLifecycleAwareTest {
|
||||
val task = this@CInteropCommonizerTaskTest.task.await()
|
||||
/* Define targets */
|
||||
val linux = kotlin.linuxX64("linux")
|
||||
val macos = kotlin.macosX64("macos")
|
||||
|
||||
+36
-34
@@ -11,21 +11,20 @@ import org.gradle.api.Project
|
||||
import org.gradle.api.internal.TaskInternal
|
||||
import org.gradle.testfixtures.ProjectBuilder
|
||||
import org.jetbrains.kotlin.gradle.dsl.multiplatformExtension
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinPluginLifecycle
|
||||
import org.jetbrains.kotlin.gradle.plugin.await
|
||||
import org.jetbrains.kotlin.gradle.plugin.sources.DefaultKotlinSourceSet
|
||||
import org.jetbrains.kotlin.gradle.targets.native.internal.locateOrRegisterCInteropMetadataDependencyTransformationTask
|
||||
import org.jetbrains.kotlin.gradle.targets.native.internal.locateOrRegisterCInteropMetadataDependencyTransformationTaskForIde
|
||||
import org.jetbrains.kotlin.gradle.util.MultiplatformExtensionTest
|
||||
import org.jetbrains.kotlin.gradle.util.buildProjectWithMPP
|
||||
import org.jetbrains.kotlin.gradle.util.enableCInteropCommonization
|
||||
import org.jetbrains.kotlin.gradle.util.kotlin
|
||||
import org.jetbrains.kotlin.gradle.util.*
|
||||
import java.io.File
|
||||
import kotlin.test.*
|
||||
|
||||
class CInteropMetadataDependencyTransformationTaskTest : MultiplatformExtensionTest() {
|
||||
|
||||
@Test
|
||||
fun `task not registered when cinterop commonization is disabled`() {
|
||||
project.enableCInteropCommonization(false)
|
||||
fun `task not registered when cinterop commonization is disabled`() = project.runLifecycleAwareTest {
|
||||
enableCInteropCommonization(false)
|
||||
|
||||
kotlin.linuxArm64()
|
||||
kotlin.linuxX64()
|
||||
@@ -40,13 +39,13 @@ class CInteropMetadataDependencyTransformationTaskTest : MultiplatformExtensionT
|
||||
linuxX64Main.dependsOn(linuxMain)
|
||||
|
||||
/* Expect no tasks being registered without the cinterop commonization feature flag */
|
||||
assertNull(project.locateOrRegisterCInteropMetadataDependencyTransformationTask(linuxMain))
|
||||
assertNull(project.locateOrRegisterCInteropMetadataDependencyTransformationTaskForIde(linuxMain))
|
||||
assertNull(locateOrRegisterCInteropMetadataDependencyTransformationTask(linuxMain))
|
||||
assertNull(locateOrRegisterCInteropMetadataDependencyTransformationTaskForIde(linuxMain))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test task ordering`() {
|
||||
project.enableCInteropCommonization(true)
|
||||
fun `test task ordering`() = project.runLifecycleAwareTest {
|
||||
enableCInteropCommonization(true)
|
||||
kotlin.linuxX64()
|
||||
kotlin.linuxArm64()
|
||||
|
||||
@@ -67,16 +66,17 @@ class CInteropMetadataDependencyTransformationTaskTest : MultiplatformExtensionT
|
||||
linuxX64Test.dependsOn(nativeTest)
|
||||
linuxArm64Test.dependsOn(nativeTest)
|
||||
|
||||
project.evaluate()
|
||||
val nativeTestTransformationTask = project.locateOrRegisterCInteropMetadataDependencyTransformationTask(nativeTest)
|
||||
KotlinPluginLifecycle.Stage.ReadyForExecution.await()
|
||||
|
||||
val nativeTestTransformationTask = locateOrRegisterCInteropMetadataDependencyTransformationTask(nativeTest)
|
||||
|
||||
assertNotNull(nativeTestTransformationTask, "Expected transformation task registered for 'nativeTest'")
|
||||
assertEquals(
|
||||
listOf(commonMain, commonTest, nativeMain).flatMap { sourceSet ->
|
||||
listOf(
|
||||
project.locateOrRegisterCInteropMetadataDependencyTransformationTask(sourceSet as DefaultKotlinSourceSet)?.get()
|
||||
locateOrRegisterCInteropMetadataDependencyTransformationTask(sourceSet as DefaultKotlinSourceSet)?.get()
|
||||
?: fail("Expected transformation task registered for '${sourceSet.name}'"),
|
||||
project.locateOrRegisterCInteropMetadataDependencyTransformationTaskForIde(sourceSet)?.get()
|
||||
locateOrRegisterCInteropMetadataDependencyTransformationTaskForIde(sourceSet)?.get()
|
||||
?: fail("Expected transformation task registered for '${sourceSet.name}'(forIde)")
|
||||
)
|
||||
}.toSet(),
|
||||
@@ -101,31 +101,33 @@ class CInteropMetadataDependencyTransformationTaskTest : MultiplatformExtensionT
|
||||
linuxArm64Main.dependsOn(linuxMain)
|
||||
linuxX64Main.dependsOn(linuxMain)
|
||||
|
||||
project.evaluate()
|
||||
project.runLifecycleAwareTest {
|
||||
KotlinPluginLifecycle.Stage.ReadyForExecution.await()
|
||||
|
||||
listOf(
|
||||
"commonMain", "jvmMain", "linuxArm64Main", "linuxX64Main"
|
||||
).map { sourceSetName -> kotlin.sourceSets.getByName(sourceSetName) }.forEach { sourceSet ->
|
||||
val task = project.locateOrRegisterCInteropMetadataDependencyTransformationTask(sourceSet as DefaultKotlinSourceSet)
|
||||
?: return@forEach
|
||||
listOf(
|
||||
"commonMain", "jvmMain", "linuxArm64Main", "linuxX64Main"
|
||||
).map { sourceSetName -> kotlin.sourceSets.getByName(sourceSetName) }.forEach { sourceSet ->
|
||||
val task = locateOrRegisterCInteropMetadataDependencyTransformationTask(sourceSet as DefaultKotlinSourceSet)
|
||||
?: return@forEach
|
||||
|
||||
assertFalse(
|
||||
task.get().onlyIf.isSatisfiedBy(task.get() as TaskInternal),
|
||||
"Expected task ${task.name} to be disabled (not a shared native source set)"
|
||||
assertFalse(
|
||||
task.get().onlyIf.isSatisfiedBy(task.get() as TaskInternal),
|
||||
"Expected task ${task.name} to be disabled (not a shared native source set)"
|
||||
)
|
||||
}
|
||||
|
||||
val linuxMainTask = locateOrRegisterCInteropMetadataDependencyTransformationTaskForIde(linuxMain)
|
||||
?: fail("Expected transformation task registered for 'linuxMain'")
|
||||
|
||||
assertTrue(
|
||||
linuxMainTask.get().onlyIf.isSatisfiedBy(linuxMainTask.get() as TaskInternal),
|
||||
"Expected task ${linuxMainTask.name} to be enabled"
|
||||
)
|
||||
}
|
||||
|
||||
val linuxMainTask = project.locateOrRegisterCInteropMetadataDependencyTransformationTaskForIde(linuxMain)
|
||||
?: fail("Expected transformation task registered for 'linuxMain'")
|
||||
|
||||
assertTrue(
|
||||
linuxMainTask.get().onlyIf.isSatisfiedBy(linuxMainTask.get() as TaskInternal),
|
||||
"Expected task ${linuxMainTask.name} to be enabled"
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test IDE task outputs doesnt conflict`() {
|
||||
fun `test IDE task outputs doesnt conflict`() = project.runLifecycleAwareTest {
|
||||
fun projectWithCinterops(name: String, parent: Project? = null) = buildProjectWithMPP(
|
||||
projectBuilder = { withName(name); if (parent != null) withParent(parent) }
|
||||
) {
|
||||
@@ -137,7 +139,7 @@ class CInteropMetadataDependencyTransformationTaskTest : MultiplatformExtensionT
|
||||
}
|
||||
}.also { it.evaluate() }
|
||||
|
||||
fun Project.transformationTaskOutputs(): Set<File> {
|
||||
suspend fun Project.transformationTaskOutputs(): Set<File> {
|
||||
val kotlin = multiplatformExtension
|
||||
val nativeMain = kotlin.sourceSets.findByName("nativeMain") ?: fail("Expected source set 'nativeMain")
|
||||
val cinteropTransformationTaskProvider = locateOrRegisterCInteropMetadataDependencyTransformationTaskForIde(
|
||||
@@ -154,7 +156,7 @@ class CInteropMetadataDependencyTransformationTaskTest : MultiplatformExtensionT
|
||||
.minus(File(".gradle/kotlin/kotlinTransformedCInteropMetadataLibraries"))
|
||||
}
|
||||
|
||||
fun assertTasksOutputsDoesntIntersect(a: Project, b: Project) {
|
||||
suspend fun assertTasksOutputsDoesntIntersect(a: Project, b: Project) {
|
||||
val outputsA = a.transformationTaskOutputs()
|
||||
val outputsB = b.transformationTaskOutputs()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user