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:
+67
-32
@@ -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)
|
||||
|
||||
+10
@@ -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) {
|
||||
|
||||
+28
-1
@@ -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"
|
||||
|
||||
+6
-2
@@ -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) {
|
||||
|
||||
+16
-13
@@ -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:
|
||||
|
||||
+3
-1
@@ -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 }
|
||||
|
||||
|
||||
+1
@@ -177,6 +177,7 @@ class DefaultKotlinSourceSet(
|
||||
baseDir,
|
||||
doProcessFiles = true
|
||||
)
|
||||
|
||||
MetadataDependencyTransformation(
|
||||
group, name, projectPath,
|
||||
resolution.projectStructureMetadata,
|
||||
|
||||
+6
-8
@@ -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 {
|
||||
|
||||
+9
-23
@@ -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
|
||||
)
|
||||
)
|
||||
|
||||
+21
-2
@@ -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))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user