[Gradle] Replace usage of ResolvedConfiguration to ResolvedDependencyResult
ResolvedConfiguration is a legacy API that doesn't work with Gradle Configuration Cache. ResolvedDependencyResult is cacheable but lightweight.
This commit is contained in:
+28
-14
@@ -637,7 +637,7 @@ constructor(
|
||||
@get:Internal
|
||||
internal abstract val konanPropertiesService: Property<KonanPropertiesBuildService>
|
||||
|
||||
private val compileDependencyFiles = FilesWithResolvedDependencyGraph(
|
||||
private val resolvedDependencyGraph = ResolvedDependencyGraph(
|
||||
project,
|
||||
project.configurations.getByName(compilation.compileDependencyConfigurationName)
|
||||
)
|
||||
@@ -659,7 +659,7 @@ constructor(
|
||||
executionContext = executionContext,
|
||||
settings = cacheBuilderSettings,
|
||||
konanPropertiesService = konanPropertiesService.get()
|
||||
).buildCompilerArgs(compileDependencyFiles)
|
||||
).buildCompilerArgs(resolvedDependencyGraph)
|
||||
|
||||
val buildArgs = buildKotlinNativeBinaryLinkerArgs(
|
||||
output,
|
||||
@@ -939,33 +939,47 @@ internal class CacheBuilder(
|
||||
private val partialLinkage: Boolean
|
||||
get() = PARTIAL_LINKAGE in settings.kotlinOptions.freeCompilerArgs
|
||||
|
||||
private fun getCacheDirectory(dependency: ResolvedDependency): File = getCacheDirectory(
|
||||
private fun getCacheDirectory(
|
||||
resolvedDependencyGraph: ResolvedDependencyGraph,
|
||||
dependency: ResolvedDependencyResult
|
||||
): File = getCacheDirectory(
|
||||
rootCacheDirectory = rootCacheDirectory,
|
||||
dependency = dependency,
|
||||
artifact = null,
|
||||
resolvedDependencyGraph = resolvedDependencyGraph,
|
||||
partialLinkage = partialLinkage
|
||||
)
|
||||
|
||||
private fun needCache(libraryPath: String) =
|
||||
libraryPath.startsWith(settings.gradleUserHomeDir.absolutePath) && libraryPath.endsWith(".klib")
|
||||
|
||||
private fun ensureDependencyPrecached(dependency: ResolvedDependency, visitedDependencies: MutableSet<ResolvedDependency>) {
|
||||
private fun ResolvedDependencyGraph.ensureDependencyPrecached(
|
||||
dependency: ResolvedDependencyResult,
|
||||
visitedDependencies: MutableSet<ResolvedDependencyResult>
|
||||
) {
|
||||
if (dependency in visitedDependencies)
|
||||
return
|
||||
visitedDependencies += dependency
|
||||
dependency.children.forEach { ensureDependencyPrecached(it, visitedDependencies) }
|
||||
|
||||
val artifactsToAddToCache = dependency.moduleArtifacts.filter { needCache(it.file.absolutePath) }
|
||||
visitedDependencies += dependency
|
||||
dependency
|
||||
.selected
|
||||
.dependencies
|
||||
.filterIsInstance<ResolvedDependencyResult>()
|
||||
.forEach { ensureDependencyPrecached(it, visitedDependencies) }
|
||||
|
||||
val artifactsToAddToCache = dependencyArtifacts(dependency).filter { needCache(it.file.absolutePath) }
|
||||
|
||||
if (artifactsToAddToCache.isEmpty()) return
|
||||
|
||||
val dependenciesCacheDirectories = getDependenciesCacheDirectories(
|
||||
rootCacheDirectory = rootCacheDirectory,
|
||||
dependency = dependency,
|
||||
considerArtifact = false,
|
||||
resolvedDependencyGraph = this,
|
||||
partialLinkage = partialLinkage
|
||||
) ?: return
|
||||
|
||||
val cacheDirectory = getCacheDirectory(dependency)
|
||||
val cacheDirectory = getCacheDirectory(this, dependency)
|
||||
cacheDirectory.mkdirs()
|
||||
|
||||
val artifactsLibraries = artifactsToAddToCache
|
||||
@@ -1017,7 +1031,7 @@ internal class CacheBuilder(
|
||||
args += "-Xcache-directory=${it.absolutePath}"
|
||||
}
|
||||
getAllDependencies(dependency)
|
||||
.flatMap { it.moduleArtifacts }
|
||||
.flatMap { dependencyArtifacts(it) }
|
||||
.map { it.file }
|
||||
.filterKlibsPassedToCompiler()
|
||||
.forEach {
|
||||
@@ -1085,17 +1099,17 @@ internal class CacheBuilder(
|
||||
ensureCompilerProvidedLibPrecached(platformLibName, platformLibs, visitedLibs)
|
||||
}
|
||||
|
||||
fun buildCompilerArgs(compileDependencyFiles: FilesWithResolvedDependencyGraph): List<String> = mutableListOf<String>().apply {
|
||||
fun buildCompilerArgs(resolvedDependencyGraph: ResolvedDependencyGraph): List<String> = mutableListOf<String>().apply {
|
||||
if (konanCacheKind != NativeCacheKind.NONE && !optimized && konanPropertiesService.cacheWorksFor(konanTarget)) {
|
||||
rootCacheDirectory.mkdirs()
|
||||
ensureCompilerProvidedLibsPrecached()
|
||||
add("-Xcache-directory=${rootCacheDirectory.absolutePath}")
|
||||
val visitedDependencies = mutableSetOf<ResolvedDependency>()
|
||||
val visitedDependencies = mutableSetOf<ResolvedDependencyResult>()
|
||||
val allCacheDirectories = mutableSetOf<String>()
|
||||
for (root in compileDependencyFiles.graphRoot.firstLevelModuleDependencies) {
|
||||
ensureDependencyPrecached(root, visitedDependencies)
|
||||
for (root in resolvedDependencyGraph.root.dependencies.filterIsInstance<ResolvedDependencyResult>()) {
|
||||
resolvedDependencyGraph.ensureDependencyPrecached(root, visitedDependencies)
|
||||
for (dependency in listOf(root) + getAllDependencies(root)) {
|
||||
val cacheDirectory = getCacheDirectory(dependency)
|
||||
val cacheDirectory = getCacheDirectory(resolvedDependencyGraph, dependency)
|
||||
if (cacheDirectory.exists())
|
||||
allCacheDirectories += cacheDirectory.absolutePath
|
||||
}
|
||||
|
||||
+23
-19
@@ -5,8 +5,8 @@
|
||||
|
||||
package org.jetbrains.kotlin.gradle.utils
|
||||
|
||||
import org.gradle.api.artifacts.ResolvedArtifact
|
||||
import org.gradle.api.artifacts.ResolvedDependency
|
||||
import org.gradle.api.artifacts.result.ResolvedArtifactResult
|
||||
import org.gradle.api.artifacts.result.ResolvedDependencyResult
|
||||
import org.gradle.api.logging.Logger
|
||||
import org.jetbrains.kotlin.library.resolveSingleFileKlib
|
||||
import org.jetbrains.kotlin.library.uniqueName
|
||||
@@ -14,14 +14,15 @@ import java.io.File
|
||||
import java.nio.charset.StandardCharsets
|
||||
import java.security.MessageDigest
|
||||
|
||||
fun getCacheDirectory(
|
||||
internal fun getCacheDirectory(
|
||||
rootCacheDirectory: File,
|
||||
dependency: ResolvedDependency,
|
||||
artifact: ResolvedArtifact?,
|
||||
dependency: ResolvedDependencyResult,
|
||||
artifact: ResolvedArtifactResult?,
|
||||
resolvedDependencyGraph: ResolvedDependencyGraph,
|
||||
partialLinkage: Boolean
|
||||
): File {
|
||||
val moduleCacheDirectory = File(rootCacheDirectory, dependency.moduleName)
|
||||
val versionCacheDirectory = File(moduleCacheDirectory, dependency.moduleVersion)
|
||||
val moduleCacheDirectory = File(rootCacheDirectory, dependency.selected.moduleVersion?.name ?: "undefined")
|
||||
val versionCacheDirectory = File(moduleCacheDirectory, dependency.selected.moduleVersion?.version ?: "undefined")
|
||||
val uniqueName = artifact
|
||||
?.let {
|
||||
if (libraryFilter(it))
|
||||
@@ -40,16 +41,17 @@ fun getCacheDirectory(
|
||||
versionCacheDirectory.resolve(hash)
|
||||
} else versionCacheDirectory
|
||||
|
||||
return File(cacheDirectory, computeDependenciesHash(dependency, partialLinkage))
|
||||
return File(cacheDirectory, computeDependenciesHash(dependency, resolvedDependencyGraph, partialLinkage))
|
||||
}
|
||||
|
||||
internal fun ByteArray.toHexString() = joinToString("") { (0xFF and it.toInt()).toString(16).padStart(2, '0') }
|
||||
|
||||
private fun computeDependenciesHash(dependency: ResolvedDependency, partialLinkage: Boolean): String {
|
||||
private fun computeDependenciesHash(dependency: ResolvedDependencyResult, resolvedDependencyGraph: ResolvedDependencyGraph, partialLinkage: Boolean): String {
|
||||
val hashedValue = buildString {
|
||||
if (partialLinkage) append("#__PL__#")
|
||||
|
||||
(dependency.moduleArtifacts + getAllDependencies(dependency).flatMap { it.moduleArtifacts })
|
||||
(listOf(dependency) + getAllDependencies(dependency))
|
||||
.flatMap { resolvedDependencyGraph.dependencyArtifacts(it) }
|
||||
.map { it.file.absolutePath }
|
||||
.distinct()
|
||||
.sortedBy { it }
|
||||
@@ -61,20 +63,22 @@ private fun computeDependenciesHash(dependency: ResolvedDependency, partialLinka
|
||||
return hash.toHexString()
|
||||
}
|
||||
|
||||
fun getDependenciesCacheDirectories(
|
||||
internal fun getDependenciesCacheDirectories(
|
||||
rootCacheDirectory: File,
|
||||
dependency: ResolvedDependency,
|
||||
dependency: ResolvedDependencyResult,
|
||||
resolvedDependencyGraph: ResolvedDependencyGraph,
|
||||
considerArtifact: Boolean,
|
||||
partialLinkage: Boolean
|
||||
): List<File>? {
|
||||
return getAllDependencies(dependency)
|
||||
.flatMap { childDependency ->
|
||||
childDependency.moduleArtifacts.map {
|
||||
resolvedDependencyGraph.dependencyArtifacts(childDependency).map {
|
||||
if (libraryFilter(it)) {
|
||||
val cacheDirectory = getCacheDirectory(
|
||||
rootCacheDirectory = rootCacheDirectory,
|
||||
dependency = childDependency,
|
||||
artifact = if (considerArtifact) it else null,
|
||||
resolvedDependencyGraph = resolvedDependencyGraph,
|
||||
partialLinkage = partialLinkage
|
||||
)
|
||||
if (!cacheDirectory.exists()) return null
|
||||
@@ -88,17 +92,17 @@ fun getDependenciesCacheDirectories(
|
||||
.filter { it.exists() }
|
||||
}
|
||||
|
||||
fun getAllDependencies(dependency: ResolvedDependency): Set<ResolvedDependency> {
|
||||
val allDependencies = mutableSetOf<ResolvedDependency>()
|
||||
internal fun getAllDependencies(dependency: ResolvedDependencyResult): Set<ResolvedDependencyResult> {
|
||||
val allDependencies = mutableSetOf<ResolvedDependencyResult>()
|
||||
|
||||
fun traverseAllDependencies(dependency: ResolvedDependency) {
|
||||
fun traverseAllDependencies(dependency: ResolvedDependencyResult) {
|
||||
if (dependency in allDependencies)
|
||||
return
|
||||
allDependencies.add(dependency)
|
||||
dependency.children.forEach { traverseAllDependencies(it) }
|
||||
dependency.selected.dependencies.filterIsInstance<ResolvedDependencyResult>().forEach { traverseAllDependencies(it) }
|
||||
}
|
||||
|
||||
dependency.children.forEach { traverseAllDependencies(it) }
|
||||
dependency.selected.dependencies.filterIsInstance<ResolvedDependencyResult>().forEach { traverseAllDependencies(it) }
|
||||
return allDependencies
|
||||
}
|
||||
|
||||
@@ -109,4 +113,4 @@ internal class GradleLoggerAdapter(private val gradleLogger: Logger) : org.jetbr
|
||||
override fun fatal(message: String): Nothing = kotlin.error(message)
|
||||
}
|
||||
|
||||
private fun libraryFilter(artifact: ResolvedArtifact): Boolean = artifact.file.absolutePath.endsWith(".klib")
|
||||
private fun libraryFilter(artifact: ResolvedArtifactResult): Boolean = artifact.file.absolutePath.endsWith(".klib")
|
||||
|
||||
+19
-15
@@ -7,9 +7,9 @@ package org.jetbrains.kotlin.gradle.utils
|
||||
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.artifacts.Configuration
|
||||
import org.gradle.api.artifacts.ResolvedConfiguration
|
||||
import org.gradle.api.artifacts.ResolvedDependency
|
||||
import org.gradle.api.artifacts.result.ResolvedArtifactResult
|
||||
import org.gradle.api.artifacts.result.ResolvedComponentResult
|
||||
import org.gradle.api.artifacts.result.ResolvedDependencyResult
|
||||
import org.gradle.api.file.FileCollection
|
||||
import org.gradle.api.provider.Provider
|
||||
|
||||
@@ -22,25 +22,29 @@ const val RUNTIME = "runtime"
|
||||
internal const val INTRANSITIVE = "intransitive"
|
||||
|
||||
/**
|
||||
* Gradle Configuration Cache-friendly holder of resolved Configuration
|
||||
* Gradle Configuration Cache-friendly representation of resolved Configuration
|
||||
*/
|
||||
class FilesWithResolvedDependencyGraph
|
||||
internal class ResolvedDependencyGraph
|
||||
private constructor (
|
||||
val files: FileCollection,
|
||||
val graphRootProvider: Provider<ResolvedComponentResult>
|
||||
private val graphRootProvider: Provider<ResolvedComponentResult>,
|
||||
private val artifactsProvider: Provider<Set<ResolvedArtifactResult>>
|
||||
) {
|
||||
val graphRoot get() = graphRootProvider.get()
|
||||
val root get() = graphRootProvider.get()
|
||||
val artifacts get() = artifactsProvider.get()
|
||||
|
||||
val artifactsByComponentId by lazy { artifacts.groupBy { it.id.componentIdentifier } }
|
||||
|
||||
fun dependencyArtifacts(dependency: ResolvedDependencyResult): List<ResolvedArtifactResult> {
|
||||
val componentId = dependency.selected.id
|
||||
return artifactsByComponentId[componentId] ?: emptyList()
|
||||
}
|
||||
|
||||
companion object {
|
||||
operator fun invoke(project: Project, configuration: Configuration) = FilesWithResolvedDependencyGraph(
|
||||
operator fun invoke(project: Project, configuration: Configuration) = ResolvedDependencyGraph(
|
||||
files = project.files(configuration),
|
||||
graphRootProvider = configuration.incoming.resolutionResult.let { rr -> project.provider { rr.root } }
|
||||
graphRootProvider = configuration.incoming.resolutionResult.let { rr -> project.provider { rr.root } },
|
||||
artifactsProvider = configuration.incoming.artifacts.let { collection -> project.provider { collection.artifacts } }
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Configuration Cache-friendly alternative of [ResolvedConfiguration.getFirstLevelModuleDependencies]
|
||||
*/
|
||||
internal val ResolvedComponentResult.firstLevelModuleDependencies: Set<ResolvedDependency> get() =
|
||||
dependencies.filterIsInstance<ResolvedDependency>().toSet()
|
||||
}
|
||||
Reference in New Issue
Block a user