General fixes for composite builds in HMPP

* Register project structure metadata providers globally, so included
  builds can access it from the root build.

* Rework some dependency management logic so that it doesn't assume that
  dependencies resolved to projects are safe to access – it is so only
  if the project is in the same build; also, in dependency handling, use
  proper keys which distinguish project with same ID in different
  builds.

* Add a separate implementation of `MppDependencyMetadataExtractor` that
  reads the project structure metadata from the mentioned global storage
  (as we can't read it from artifacts – those are not yet build at the
  project configuration phase) but when it comes to artifacts
  processing, takes real artifacts rather than introspect the project
  structure.

* Register the Kotlin/Native host-specific metadata artifact
  configurations as consumable, so that a consumer from a different
  build can properly resolve a dependency to such a configuration and
  get the artifact.
This commit is contained in:
Sergey Igushkin
2020-09-29 18:45:24 +03:00
parent 7d1a3a137b
commit 3a5ffe479e
11 changed files with 168 additions and 83 deletions
@@ -6,8 +6,9 @@
package org.jetbrains.kotlin.gradle.plugin.mpp
import org.gradle.api.Project
import org.gradle.api.artifacts.*
import org.gradle.api.artifacts.component.*
import org.gradle.api.artifacts.Configuration
import org.gradle.api.artifacts.Dependency
import org.gradle.api.artifacts.component.ProjectComponentIdentifier
import org.gradle.api.artifacts.result.ResolvedComponentResult
import org.gradle.api.artifacts.result.ResolvedDependencyResult
import org.gradle.api.attributes.Attribute
@@ -164,15 +165,12 @@ internal class GranularMetadataTransformation(
while (resolvedDependencyQueue.isNotEmpty()) {
val (resolvedDependency: ResolvedComponentResult, parent: ResolvedComponentResult?) = resolvedDependencyQueue.poll()
val resolvedToProject: Project? = (resolvedDependency.id as? ProjectComponentIdentifier)?.projectPath?.let(project::project)
visitedDependencies.add(resolvedDependency)
val dependencyResult = processDependency(
resolvedDependency,
parentResolutions[ModuleIds.fromComponent(project, resolvedDependency)].orEmpty(),
parent,
resolvedToProject
parent
)
result.add(dependencyResult)
@@ -196,7 +194,9 @@ internal class GranularMetadataTransformation(
result.add(
MetadataDependencyResolution.ExcludeAsUnrequested(
resolvedDependency.selected,
(resolvedDependency.selected.id as? ProjectComponentIdentifier)?.let { project.project(it.projectPath) }
(resolvedDependency.selected.id as? ProjectComponentIdentifier)
?.takeIf { it.build.isCurrentBuild() }
?.let { project.project(it.projectPath) }
)
)
}
@@ -222,23 +222,28 @@ internal class GranularMetadataTransformation(
private fun processDependency(
module: ResolvedComponentResult,
parentResolutionsForModule: Iterable<MetadataDependencyResolution>,
parent: ResolvedComponentResult?,
resolvedToProject: Project?
parent: ResolvedComponentResult?
): MetadataDependencyResolution {
val resolvedMppVariantsProvider = ResolvedMppVariantsProvider.get(project)
val mppDependencyMetadataExtractor = if (resolvedToProject != null) {
ProjectMppDependencyMetadataExtractor(project, module, resolvedToProject)
} else {
val metadataArtifact = resolvedMppVariantsProvider.getPlatformArtifactByPlatformModule(
ModuleIds.fromComponent(project, module),
configurationToResolve
)
if (metadataArtifact != null) {
JarArtifactMppDependencyMetadataExtractor(project, module, metadataArtifact)
} else null
val metadataArtifact = resolvedMppVariantsProvider.getPlatformArtifactByPlatformModule(
ModuleIds.fromComponent(project, module),
configurationToResolve
)
val moduleId = module.id
val mppDependencyMetadataExtractor: MppDependencyMetadataExtractor? = when {
moduleId is ProjectComponentIdentifier -> when {
moduleId.build.isCurrentBuild ->
ProjectMppDependencyMetadataExtractor(project, module, project.project(moduleId.projectPath))
metadataArtifact != null ->
IncludedBuildMetadataExtractor(project, module, metadataArtifact)
else -> null
}
metadataArtifact != null -> JarArtifactMppDependencyMetadataExtractor(project, module, metadataArtifact)
else -> null
}
val resolvedToProject: Project? = (mppDependencyMetadataExtractor as? ProjectMppDependencyMetadataExtractor)?.dependencyProject
val projectStructureMetadata = mppDependencyMetadataExtractor?.getProjectStructureMetadata()
?: return MetadataDependencyResolution.KeepOriginalDependency(module, resolvedToProject)
@@ -318,7 +323,7 @@ private abstract class MppDependencyMetadataExtractor(val project: Project, val
private class ProjectMppDependencyMetadataExtractor(
project: Project,
dependency: ResolvedComponentResult,
private val dependencyProject: Project
val dependencyProject: Project
) : MppDependencyMetadataExtractor(project, dependency) {
override fun getProjectStructureMetadata(): KotlinProjectStructureMetadata? =
buildKotlinProjectStructureMetadata(dependencyProject)
@@ -337,7 +342,26 @@ private class ProjectMppDependencyMetadataExtractor(
}
}
private class JarArtifactMppDependencyMetadataExtractor(
private class IncludedBuildMetadataExtractor(
project: Project,
dependency: ResolvedComponentResult,
primaryArtifact: File
) : JarArtifactMppDependencyMetadataExtractor(project, dependency, primaryArtifact) {
private val id: ProjectComponentIdentifier
init {
val id = dependency.id
require(id is ProjectComponentIdentifier) { "dependency should resolve to a project" }
require(!(id as ProjectComponentIdentifier).build.isCurrentBuild) { "should be a project from an included build" }
this.id = id
}
override fun getProjectStructureMetadata(): KotlinProjectStructureMetadata? =
GlobalProjectStructureMetadataStorage.getProjectStructureMetadata(project, id.build.name, id.projectPath)
}
private open class JarArtifactMppDependencyMetadataExtractor(
project: Project,
dependency: ResolvedComponentResult,
val primaryArtifact: File
@@ -394,20 +418,31 @@ private class JarArtifactMppDependencyMetadataExtractor(
val projectStructureMetadata = projectStructureMetadata
artifactBySourceSet.forEach { (sourceSetName, artifact) ->
ZipFile(artifact).use { zip ->
val entries = zip.entries().asSequence().filter { it.name.startsWith("$sourceSetName/") }.toList()
val extension = projectStructureMetadata.sourceSetBinaryLayout[sourceSetName]?.archiveExtension
?: SourceSetMetadataLayout.METADATA.archiveExtension
val extractToJarFile = transformedModuleRoot.resolve("$moduleString-$sourceSetName.$extension")
// TODO: once IJ supports non-JAR metadata dependencies, extract to a directory, not a JAR
// Also, if both IJ and the CLI compiler can read metadata from a path inside a JAR, then no operations will be needed
/** NB: the result may contain files that do not exist and won't be created if the actual metadata artifact doesn't contain
* entries for the corresponding source set. It's the consumer's responsibility to filter the result if they need only
* existing files! */
resultFiles[sourceSetName] = project.files(extractToJarFile)
if (entries.any()) {
val extension = projectStructureMetadata.sourceSetBinaryLayout[sourceSetName]?.archiveExtension
?: SourceSetMetadataLayout.METADATA.archiveExtension
if (doProcessFiles) {
if (extractToJarFile.exists()) {
extractToJarFile.delete()
}
val extractToJarFile = transformedModuleRoot.resolve("$moduleString-$sourceSetName.$extension")
resultFiles[sourceSetName] = project.files(extractToJarFile)
/** In composite builds, we don't really need tro process the file in IDE import, so ignore it if it's missing */
// refactor: allow only included builds to provide no artifacts, and allow this only in IDE import
if (!artifact.isFile) return@forEach
if (doProcessFiles) {
ZipFile(artifact).use { zip ->
val entries = zip.entries().asSequence().filter { it.name.startsWith("$sourceSetName/") }.toList()
// TODO: once IJ supports non-JAR metadata dependencies, extract to a directory, not a JAR
// Also, if both IJ and the CLI compiler can read metadata from a path inside a JAR, then no operations will be needed
if (entries.any()) {
ZipOutputStream(extractToJarFile.outputStream()).use { resultZipOutput ->
for (entry in entries) {
if (entry.isDirectory)
@@ -110,6 +110,16 @@ class KotlinMultiplatformPlugin(
project.setupGeneralKotlinExtensionParameters()
project.pluginManager.apply(ScriptingGradleSubplugin::class.java)
exportProjectStructureMetadataForOtherBuilds(project)
}
private fun exportProjectStructureMetadataForOtherBuilds(
project: Project
) {
GlobalProjectStructureMetadataStorage.registerProjectStructureMetadata(project) {
checkNotNull(buildKotlinProjectStructureMetadata(project))
}
}
private fun setupAdditionalCompilerArguments(project: Project) {
@@ -125,7 +125,9 @@ internal fun buildKotlinProjectStructureMetadata(project: Project): KotlinProjec
}
sourceSet.name to sourceSetExportedDependencies.map { ModuleIds.fromDependency(it) }.toSet()
},
hostSpecificSourceSets = getHostSpecificSourceSets(project).map { it.name }.toSet(),
hostSpecificSourceSets = getHostSpecificSourceSets(project)
.filter { it in sourceSetsWithMetadataCompilations }.map { it.name }
.toSet(),
sourceSetBinaryLayout = sourceSetsWithMetadataCompilations.keys.associate { sourceSet ->
sourceSet.name to SourceSetMetadataLayout.chooseForProducingProject(project)
},
@@ -289,6 +291,31 @@ internal fun <ParsingContext> parseKotlinSourceSetMetadata(
)
}
object GlobalProjectStructureMetadataStorage {
fun propertyName(buildName: String, projectPath: String) = "kotlin.projectStructureMetadata.build.$buildName.path.$projectPath"
fun registerProjectStructureMetadata(project: Project, metadataProvider: () -> KotlinProjectStructureMetadata) {
val compositeBuildRoot = generateSequence(project.gradle) { it.parent }.last().rootProject
compositeBuildRoot.extensions.extraProperties.set(
propertyName(project.rootProject.name, project.path),
{ metadataProvider().toJson() }
)
}
fun getProjectStructureMetadata(project: Project, otherBuildName: String, otherProjectPath: String): KotlinProjectStructureMetadata? {
val compositeBuildRoot = generateSequence(project.gradle) { it.parent }.last().rootProject
val property = propertyName(otherBuildName, otherProjectPath)
return with(compositeBuildRoot.extensions.extraProperties) {
if (has(property)) {
val jsonStringProvider = get(property) as? Function0<*> ?: return null
val jsonString = jsonStringProvider.invoke() as? String ?: return null
parseKotlinSourceSetMetadataFromJson(jsonString)
} else null
}
}
}
private const val ROOT_NODE_NAME = "projectStructure"
private const val PUBLISHED_AS_ROOT_NAME = "isPublishedAsRoot"
private const val FORMAT_VERSION_NODE_NAME = "formatVersion"
@@ -28,7 +28,7 @@ internal object ModuleIds {
else -> idFromName(componentSelector.displayName)
}
fun fromComponentId(
private fun fromComponentId(
thisProject: Project,
componentIdentifier: ComponentIdentifier
): ModuleDependencyIdentifier =
@@ -39,7 +39,11 @@ internal object ModuleIds {
}
fun fromComponent(thisProject: Project, component: ResolvedComponentResult) =
fromComponentId(thisProject, component.id)
// If the project component comes from another build, we can't extract anything from it, so just use the module coordinates:
if ((component.id as? ProjectComponentIdentifier)?.build?.isCurrentBuild == false)
ModuleDependencyIdentifier(component.moduleVersion?.group ?: "unspecified", component.moduleVersion?.name ?: "unspecified")
else
fromComponentId(thisProject, component.id)
private fun idOfRootModule(project: Project): ModuleDependencyIdentifier =
if (project.multiplatformExtensionOrNull != null) {
@@ -7,7 +7,6 @@ package org.jetbrains.kotlin.gradle.plugin.mpp
import org.gradle.api.Project
import org.gradle.api.artifacts.Configuration
import org.gradle.api.artifacts.component.ComponentIdentifier
import org.gradle.api.artifacts.component.ProjectComponentIdentifier
import org.gradle.api.artifacts.result.ResolvedArtifactResult
import org.gradle.api.artifacts.result.ResolvedComponentResult
@@ -61,6 +60,7 @@ internal class ResolvedMppVariantsProvider private constructor(private val proje
if (configuration !in resolvedMetadataArtifactByConfiguration) {
resolveConfigurationAndSaveVariants(configuration, artifactResolutionMode = ArtifactResolutionMode.METADATA)
}
// At this point the map should contain the result if calculation above succeeded. If not, put null to avoid recalculation.
resolvedMetadataArtifactByConfiguration.getOrPut(configuration) { null }
}
}
@@ -71,6 +71,7 @@ internal class ResolvedMppVariantsProvider private constructor(private val proje
if (configuration !in resolvedArtifactByConfiguration) {
resolveConfigurationAndSaveVariants(configuration, artifactResolutionMode = ArtifactResolutionMode.NORMAL)
}
// At this point the map should contain the result if the calculation above succeeded. If not, put null to avoid recalculation.
resolvedArtifactByConfiguration.getOrPut(configuration) { null }
}
@@ -79,7 +80,7 @@ internal class ResolvedMppVariantsProvider private constructor(private val proje
private val entriesCache: MutableMap<ModuleDependencyIdentifier, ModuleEntry> = mutableMapOf()
private val mppComponentIdsByConfiguration: MutableMap<Configuration, Set<ComponentIdentifier>> = mutableMapOf()
private val mppComponentsByConfiguration: MutableMap<Configuration, Set<ResolvedComponentResult>> = mutableMapOf()
private enum class ArtifactResolutionMode {
NONE, NORMAL, METADATA
@@ -89,7 +90,7 @@ internal class ResolvedMppVariantsProvider private constructor(private val proje
configuration: Configuration,
artifactResolutionMode: ArtifactResolutionMode
) {
val mppComponentIds: Set<ComponentIdentifier> = mppComponentIdsByConfiguration.getOrPut(configuration) {
val mppComponentIds: Set<ResolvedComponentResult> = mppComponentsByConfiguration.getOrPut(configuration) {
resolveMppComponents(configuration)
}
@@ -99,7 +100,7 @@ internal class ResolvedMppVariantsProvider private constructor(private val proje
}
}
private fun resolveMppComponents(configuration: Configuration): MutableSet<ComponentIdentifier> {
private fun resolveMppComponents(configuration: Configuration): Set<ResolvedComponentResult> {
val result = mutableListOf<ResolvedComponentResult>()
configuration.incoming.resolutionResult.allComponents { component ->
@@ -123,14 +124,16 @@ internal class ResolvedMppVariantsProvider private constructor(private val proje
}
}
return result.mapTo(mutableSetOf()) { it.id }
return result.toSet()
}
private fun resolveArtifacts(
artifactResolutionMode: ArtifactResolutionMode,
configuration: Configuration,
mppComponentIds: Set<ComponentIdentifier>
): Map<ComponentIdentifier, ResolvedArtifactResult> {
mppComponents: Set<ResolvedComponentResult>
): Map<ResolvedComponentResult, ResolvedArtifactResult> {
val mppComponentById = mppComponents.associateBy { it.id }
val artifactsConfiguration =
if (
artifactResolutionMode == ArtifactResolutionMode.NORMAL ||
@@ -144,22 +147,22 @@ internal class ResolvedMppVariantsProvider private constructor(private val proje
}
return artifactsConfiguration.incoming.artifactView { view ->
view.componentFilter { it in mppComponentIds }
view.componentFilter { it in mppComponentById }
view.attributes { attrs -> attrs.attribute(Usage.USAGE_ATTRIBUTE, project.usageByName(KotlinUsages.KOTLIN_METADATA)) }
view.lenient(true)
}.artifacts.associateBy { it.id.componentIdentifier }
}.artifacts.associateBy { mppComponentById.getValue(it.id.componentIdentifier) }
}
private fun matchMppComponentsWithResolvedArtifacts(
mppComponentIds: Set<ComponentIdentifier>,
artifacts: Map<ComponentIdentifier, ResolvedArtifactResult>,
mppComponentIds: Set<ResolvedComponentResult>,
artifacts: Map<ResolvedComponentResult, ResolvedArtifactResult>,
configuration: Configuration,
artifactResolutionMode: ArtifactResolutionMode
) {
val mppModuleIds = mppComponentIds.mapTo(mutableSetOf()) { ModuleIds.fromComponentId(project, it) }
val mppModuleIds = mppComponentIds.mapTo(mutableSetOf()) { ModuleIds.fromComponent(project, it) }
mppComponentIds.forEach { componentId ->
val moduleEntry = getEntryForModule(ModuleIds.fromComponentId(project, componentId))
val moduleEntry = getEntryForModule(ModuleIds.fromComponent(project, componentId))
val artifact = artifacts[componentId]
when {
// With project dependencies, we don't need the host-specific metadata artifacts, as we have the compilation outputs:
@@ -101,7 +101,9 @@ open class TransformKotlinGranularMetadata
@get:Internal
internal val filesByResolution: Map<out MetadataDependencyResolution, FileCollection>
get() = extractableFilesByResolution.mapValues { (_, value) -> project.files(value.getMetadataFilesPerSourceSet(false).values) }
get() = extractableFilesByResolution.mapValues { (_, value) ->
project.files(value.getMetadataFilesPerSourceSet(false).values)
}
private val extractableFiles by project.provider { extractableFilesByResolution.values }
@@ -177,6 +177,7 @@ class DefaultKotlinSourceSet(
baseDir,
doProcessFiles = true
)
MetadataDependencyTransformation(
group, name, projectPath,
resolution.projectStructureMetadata,
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.gradle.targets.metadata
import org.gradle.api.Project
import org.gradle.api.artifacts.Configuration
import org.gradle.api.artifacts.component.ComponentIdentifier
import org.gradle.api.attributes.Usage.USAGE_ATTRIBUTE
import org.gradle.api.file.FileCollection
import org.gradle.api.internal.component.SoftwareComponentInternal
@@ -28,7 +29,6 @@ import org.jetbrains.kotlin.gradle.tasks.registerTask
import org.jetbrains.kotlin.gradle.utils.addExtendsFromRelation
import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName
import org.jetbrains.kotlin.statistics.metrics.BooleanMetrics
import java.util.concurrent.Callable
internal const val ALL_COMPILE_METADATA_CONFIGURATION_NAME = "allSourceSetsCompileDependenciesMetadata"
internal const val ALL_RUNTIME_METADATA_CONFIGURATION_NAME = "allSourceSetsRuntimeDependenciesMetadata"
@@ -408,12 +408,12 @@ class KotlinMetadataTargetConfigurator(kotlinPluginVersion: String) :
project.locateTask<TransformKotlinGranularMetadata>(transformGranularMetadataTaskName(hierarchySourceSet.name))
}
val allResolutionsByModule: Map<ModuleDependencyIdentifier, List<MetadataDependencyResolution>> =
mutableMapOf<ModuleDependencyIdentifier, MutableList<MetadataDependencyResolution>>().apply {
val allResolutionsByComponentId: Map<ComponentIdentifier, List<MetadataDependencyResolution>> =
mutableMapOf<ComponentIdentifier, MutableList<MetadataDependencyResolution>>().apply {
transformationTaskHolders.forEach {
val resolutions = it.get().metadataDependencyResolutions
resolutions.forEach { resolution ->
getOrPut(ModuleIds.fromComponent(project, resolution.dependency)) { mutableListOf() }.add(resolution)
getOrPut(resolution.dependency.id) { mutableListOf() }.add(resolution)
}
}
}
@@ -428,8 +428,7 @@ class KotlinMetadataTargetConfigurator(kotlinPluginVersion: String) :
val artifactView = fromFiles.incoming.artifactView { view ->
view.componentFilter { id ->
val moduleId = ModuleIds.fromComponentId(project, id)
allResolutionsByModule[moduleId].let { resolutions ->
allResolutionsByComponentId[id].let { resolutions ->
resolutions == null || resolutions.any { it !is MetadataDependencyResolution.ExcludeAsUnrequested }
}
}
@@ -438,8 +437,7 @@ class KotlinMetadataTargetConfigurator(kotlinPluginVersion: String) :
mutableSetOf<Any /* File | FileCollection */>().apply {
addAll(dependsOnCompilationOutputs)
artifactView.artifacts.forEach { artifact ->
val resolutions =
allResolutionsByModule[ModuleIds.fromComponentId(project, artifact.id.componentIdentifier)]
val resolutions = allResolutionsByComponentId[artifact.id.componentIdentifier]
if (resolutions == null) {
add(artifact.file)
} else {
@@ -44,7 +44,7 @@ open class KotlinNativeTarget @Inject constructor(
private val hostSpecificMetadataJarTaskName get() = disambiguateName("MetadataJar")
private val hostSpecificMetadataElementsConfigurationName get() = disambiguateName("MetadataElements")
internal val hostSpecificMetadataElementsConfigurationName get() = disambiguateName("MetadataElements")
override val kotlinComponents: Set<KotlinTargetComponent> by lazy {
if (!project.isKotlinGranularMetadataEnabled)
@@ -60,13 +60,10 @@ open class KotlinNativeTarget @Inject constructor(
.intersect(mainCompilation.allKotlinSourceSets)
if (hostSpecificSourceSets.isNotEmpty()) {
val hostSpecificMetadataJar = project.locateOrRegisterTask<Jar>(hostSpecificMetadataJarTaskName) {
it.archiveAppendix.set(project.provider { disambiguationClassifier.orEmpty().toLowerCase() })
it.archiveClassifier.set("metadata")
}
project.artifacts.add(Dependency.ARCHIVES_CONFIGURATION, hostSpecificMetadataJar)
val hostSpecificMetadataJar = project.locateOrRegisterTask<Jar>(hostSpecificMetadataJarTaskName) { metadataJar ->
metadataJar.archiveAppendix.set(project.provider { disambiguationClassifier.orEmpty().toLowerCase() })
metadataJar.archiveClassifier.set("metadata")
hostSpecificMetadataJar.configure { metadataJar ->
metadataJar.onlyIf { this@KotlinNativeTarget.publishable }
val metadataCompilations = hostSpecificSourceSets.mapNotNull {
@@ -80,29 +77,18 @@ open class KotlinNativeTarget @Inject constructor(
metadataJar.dependsOn(it.output.classesDirs)
}
}
project.artifacts.add(Dependency.ARCHIVES_CONFIGURATION, hostSpecificMetadataJar)
val metadataConfiguration = project.configurations.findByName(hostSpecificMetadataElementsConfigurationName)
?: project.configurations.create(hostSpecificMetadataElementsConfigurationName) { configuration ->
configuration.isCanBeConsumed = false
configuration.isCanBeResolved = false
project.artifacts.add(configuration.name, hostSpecificMetadataJar) { artifact ->
artifact.classifier = "metadata"
}
configuration.extendsFrom(*configurations.getByName(apiElementsConfigurationName).extendsFrom.toTypedArray())
}
val metadataAttributes =
HierarchyAttributeContainer(project.configurations.getByName(apiElementsConfigurationName).attributes).apply {
attribute(Usage.USAGE_ATTRIBUTE, project.usageByName(KotlinUsages.KOTLIN_METADATA))
}
val metadataConfiguration = project.configurations.getByName(hostSpecificMetadataElementsConfigurationName)
project.artifacts.add(metadataConfiguration.name, hostSpecificMetadataJar) { artifact ->
artifact.classifier = "metadata"
}
mutableUsageContexts.add(
DefaultKotlinUsageContext(
mainCompilation,
project.usageByName(javaApiUsageForMavenScoping()),
metadataConfiguration.name,
overrideConfigurationAttributes = metadataAttributes,
includeIntoProjectStructureMetadata = false
)
)
@@ -10,6 +10,9 @@ import org.gradle.api.DefaultTask
import org.gradle.api.Project
import org.gradle.api.artifacts.ConfigurationContainer
import org.gradle.api.artifacts.Dependency
import org.gradle.api.attributes.Attribute
import org.gradle.api.attributes.AttributeContainer
import org.gradle.api.attributes.Usage
import org.gradle.api.attributes.Usage.USAGE_ATTRIBUTE
import org.gradle.api.internal.artifacts.ArtifactAttributes
import org.gradle.api.internal.plugins.DefaultArtifactPublicationSet
@@ -23,6 +26,7 @@ import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation.Companion.MAIN_COMPI
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation.Companion.TEST_COMPILATION_NAME
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.Companion.KOTLIN_NATIVE_IGNORE_INCORRECT_DEPENDENCIES
import org.jetbrains.kotlin.gradle.plugin.mpp.*
import org.jetbrains.kotlin.gradle.targets.metadata.isKotlinGranularMetadataEnabled
import org.jetbrains.kotlin.gradle.targets.native.*
import org.jetbrains.kotlin.gradle.targets.native.tasks.KotlinNativeHostTest
import org.jetbrains.kotlin.gradle.targets.native.tasks.KotlinNativeSimulatorTest
@@ -243,8 +247,23 @@ open class KotlinNativeTargetConfigurator<T : KotlinNativeTarget>(
createKlibCompilationTask(it)
}
with(configurations.getByName(target.apiElementsConfigurationName)) {
outgoing.attributes.attribute(ArtifactAttributes.ARTIFACT_FORMAT, NativeArtifactFormat.KLIB)
val apiElements = configurations.getByName(target.apiElementsConfigurationName)
apiElements.outgoing.attributes.attribute(ArtifactAttributes.ARTIFACT_FORMAT, NativeArtifactFormat.KLIB)
if (project.isKotlinGranularMetadataEnabled) {
project.configurations.create(target.hostSpecificMetadataElementsConfigurationName) { configuration ->
configuration.isCanBeConsumed = true
configuration.isCanBeResolved = false
configuration.extendsFrom(*apiElements.extendsFrom.toTypedArray())
fun <T> copyAttribute(from: AttributeContainer, to: AttributeContainer, attribute: Attribute<T>) {
to.attribute(attribute, from.getAttribute(attribute)!!)
}
with(apiElements.attributes) { keySet().forEach { copyAttribute(this, configuration.attributes, it) } }
configuration.attributes.attribute(USAGE_ATTRIBUTE, objects.named(Usage::class.java, KotlinUsages.KOTLIN_METADATA))
}
}
}
@@ -64,7 +64,7 @@ open class KotlinCompileCommon : AbstractKotlinCompile<K2MetadataCompilerArgumen
if (defaultsOnly) return
val classpathList = classpath.files.toMutableList()
val classpathList = classpath.files.filter { it.exists() }.toMutableList()
with(args) {
classpath = classpathList.joinToString(File.pathSeparator)