All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jetbrains.kotlin.gradle.targets.native.internal.CInteropConfigurations.kt Maven / Gradle / Ivy

There is a newer version: 2.0.0-RC3
Show newest version
/*
 * Copyright 2010-2021 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.targets.native.internal

import org.gradle.api.Project
import org.gradle.api.artifacts.Configuration
import org.gradle.api.attributes.*
import org.gradle.api.tasks.TaskProvider
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation.Companion.MAIN_COMPILATION_NAME
import org.jetbrains.kotlin.gradle.plugin.KotlinNativeTargetConfigurator.NativeArtifactFormat
import org.jetbrains.kotlin.gradle.plugin.KotlinPluginLifecycle.Stage.AfterFinaliseDsl
import org.jetbrains.kotlin.gradle.plugin.KotlinTarget
import org.jetbrains.kotlin.gradle.plugin.categoryByName
import org.jetbrains.kotlin.gradle.plugin.internal.artifactTypeAttribute
import org.jetbrains.kotlin.gradle.plugin.launchInStage
import org.jetbrains.kotlin.gradle.plugin.mpp.*
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.copyAttributes
import org.jetbrains.kotlin.gradle.plugin.usesPlatformOf
import org.jetbrains.kotlin.gradle.targets.native.internal.CInteropKlibLibraryElements.cinteropKlibLibraryElements
import org.jetbrains.kotlin.gradle.tasks.CInteropProcess
import org.jetbrains.kotlin.gradle.utils.markResolvable

internal fun createCInteropApiElementsKlibArtifact(
    target: KotlinNativeTarget,
    settings: DefaultCInteropSettings,
    interopTask: TaskProvider,
) {
    val project = target.project
    val configurationName = cInteropApiElementsConfigurationName(target)
    val configuration = project.configurations.getByName(configurationName)
    project.artifacts.add(configuration.name, interopTask.map { it.outputFile }) { artifact ->
        artifact.extension = "klib"
        artifact.type = "klib"
        artifact.classifier = "cinterop-${settings.name}"
        artifact.builtBy(interopTask)
    }
}

internal fun Project.locateOrCreateCInteropDependencyConfiguration(
    compilation: KotlinNativeCompilation,
): Configuration {
    configurations.findByName(compilation.cInteropDependencyConfigurationName)?.let { return it }

    val compileOnlyConfiguration = configurations.getByName(compilation.compileOnlyConfigurationName)
    val implementationConfiguration = configurations.getByName(compilation.implementationConfigurationName)

    return configurations.create(compilation.cInteropDependencyConfigurationName).apply {
        extendsFrom(compileOnlyConfiguration, implementationConfiguration)
        isVisible = false
        markResolvable()

        /* Deferring attributes to wait for compilation.attributes to be configured  by user*/
        launchInStage(AfterFinaliseDsl) {
            usesPlatformOf(compilation.target)
            copyAttributes(compilation.attributes, attributes)
            attributes.attribute(LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, cinteropKlibLibraryElements())
            attributes.attribute(Usage.USAGE_ATTRIBUTE, objects.named(Usage::class.java, KotlinUsages.KOTLIN_CINTEROP))
            attributes.attribute(Category.CATEGORY_ATTRIBUTE, project.categoryByName(Category.LIBRARY))
            description = "CInterop dependencies for compilation '${compilation.name}')."
        }
    }
}

internal val KotlinNativeCompilation.cInteropDependencyConfigurationName: String
    get() = compilation.disambiguateName("CInterop")

internal fun Project.locateOrCreateCInteropApiElementsConfiguration(target: KotlinTarget): Configuration {
    val configurationName = cInteropApiElementsConfigurationName(target)
    configurations.findByName(configurationName)?.let { return it }

    return configurations.create(configurationName).apply {
        isCanBeResolved = false
        isCanBeConsumed = true

        /* Deferring attributes to wait for target.attributes to be configured by user */
        launchInStage(AfterFinaliseDsl) {
            usesPlatformOf(target)
            copyAttributes(target.attributes, attributes)
            attributes.attribute(LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, cinteropKlibLibraryElements())
            attributes.attribute(Usage.USAGE_ATTRIBUTE, objects.named(Usage::class.java, KotlinUsages.KOTLIN_CINTEROP))
            attributes.attribute(Category.CATEGORY_ATTRIBUTE, project.categoryByName(Category.LIBRARY))
            attributes.attribute(artifactTypeAttribute, NativeArtifactFormat.KLIB)

            /* Expose api dependencies */
            target.compilations.findByName(MAIN_COMPILATION_NAME)?.let { compilation ->
                extendsFrom(compilation.internal.configurations.apiConfiguration)
            }
        }
    }
}

private fun cInteropApiElementsConfigurationName(target: KotlinTarget): String {
    return target.name + "CInteropApiElements"
}

internal object CInteropKlibLibraryElements {
    const val CINTEROP_KLIB = "cinterop-klib"

    fun Project.cinteropKlibLibraryElements(): LibraryElements = objects.named(LibraryElements::class.java, CINTEROP_KLIB)

    fun setupAttributesMatchingStrategy(schema: AttributesSchema) {
        schema.attribute(LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE) { strategy ->
            strategy.compatibilityRules.add(CInteropLibraryElementsCompatibilityRule::class.java)
        }
    }
}

private class CInteropLibraryElementsCompatibilityRule : AttributeCompatibilityRule {
    override fun execute(details: CompatibilityCheckDetails) {
        if (details.consumerValue?.name == CInteropKlibLibraryElements.CINTEROP_KLIB) {
            if (details.producerValue?.name == LibraryElements.JAR || details.producerValue?.name == LibraryElements.CLASSES) {
                details.compatible()
            }
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy