[Commonizer] Integrate commonizer to the Gradle plugin, p.1
Detect when it's really necessary to run commonizer. Resolve Kotlin/Native platform dependencies. Add dependencies to the proper Gradle configurations. Note: The most common source sets such as "commonMain" and "commonTest" should not be used as Native intermediate source sets.
This commit is contained in:
+4
-88
@@ -10,16 +10,12 @@
|
|||||||
package org.jetbrains.kotlin.gradle.plugin.mpp
|
package org.jetbrains.kotlin.gradle.plugin.mpp
|
||||||
|
|
||||||
import org.gradle.api.Project
|
import org.gradle.api.Project
|
||||||
import org.gradle.api.artifacts.Dependency
|
|
||||||
import org.jetbrains.kotlin.compilerRunner.konanHome
|
import org.jetbrains.kotlin.compilerRunner.konanHome
|
||||||
import org.jetbrains.kotlin.gradle.dsl.kotlinExtension
|
|
||||||
import org.jetbrains.kotlin.gradle.plugin.*
|
import org.jetbrains.kotlin.gradle.plugin.*
|
||||||
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider
|
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider
|
||||||
import org.jetbrains.kotlin.gradle.targets.native.DisabledNativeTargetsReporter
|
import org.jetbrains.kotlin.gradle.targets.native.DisabledNativeTargetsReporter
|
||||||
import org.jetbrains.kotlin.gradle.targets.native.KotlinNativeHostTestRun
|
import org.jetbrains.kotlin.gradle.targets.native.internal.setUpKotlinNativePlatformDependencies
|
||||||
import org.jetbrains.kotlin.gradle.targets.native.KotlinNativeSimulatorTestRun
|
|
||||||
import org.jetbrains.kotlin.gradle.utils.NativeCompilerDownloader
|
import org.jetbrains.kotlin.gradle.utils.NativeCompilerDownloader
|
||||||
import org.jetbrains.kotlin.gradle.utils.SingleWarningPerBuild
|
|
||||||
import org.jetbrains.kotlin.konan.target.HostManager
|
import org.jetbrains.kotlin.konan.target.HostManager
|
||||||
import org.jetbrains.kotlin.konan.target.KonanTarget
|
import org.jetbrains.kotlin.konan.target.KonanTarget
|
||||||
|
|
||||||
@@ -54,27 +50,6 @@ abstract class AbstractKotlinNativeTargetPreset<T : KotlinNativeTarget>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun nativeLibrariesList(directory: String) = with(project) {
|
|
||||||
file("$konanHome/klib/$directory")
|
|
||||||
.listFiles { file -> file.isDirectory }
|
|
||||||
?.sortedBy { dir -> dir.name.toLowerCase() }
|
|
||||||
}
|
|
||||||
|
|
||||||
// We declare default K/N dependencies (default and platform libraries) as files to avoid searching them in remote repos (see KT-28128).
|
|
||||||
private fun defaultLibs(stdlibOnly: Boolean = false): List<Dependency> = with(project) {
|
|
||||||
var filesList = nativeLibrariesList("common")
|
|
||||||
if (stdlibOnly) {
|
|
||||||
filesList = filesList?.filter { dir -> dir.name == "stdlib" }
|
|
||||||
}
|
|
||||||
|
|
||||||
filesList?.map { dir -> dependencies.create(files(dir)) } ?: emptyList()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun platformLibs(target: KonanTarget): List<Dependency> = with(project) {
|
|
||||||
val filesList = nativeLibrariesList("platform/${target.name}")
|
|
||||||
filesList?.map { dir -> dependencies.create(files(dir)) } ?: emptyList()
|
|
||||||
}
|
|
||||||
|
|
||||||
protected abstract fun createTargetConfigurator(): KotlinTargetConfigurator<T>
|
protected abstract fun createTargetConfigurator(): KotlinTargetConfigurator<T>
|
||||||
|
|
||||||
protected abstract fun instantiateTarget(name: String): T
|
protected abstract fun instantiateTarget(name: String): T
|
||||||
@@ -93,7 +68,9 @@ abstract class AbstractKotlinNativeTargetPreset<T : KotlinNativeTarget>(
|
|||||||
|
|
||||||
createTargetConfigurator().configureTarget(result)
|
createTargetConfigurator().configureTarget(result)
|
||||||
|
|
||||||
addDependenciesOnLibrariesFromDistribution(result)
|
project.gradle.taskGraph.whenReady {
|
||||||
|
project.rootProject.setUpKotlinNativePlatformDependencies()
|
||||||
|
}
|
||||||
|
|
||||||
if (!konanTarget.enabledOnCurrentHost) {
|
if (!konanTarget.enabledOnCurrentHost) {
|
||||||
with(HostManager()) {
|
with(HostManager()) {
|
||||||
@@ -105,69 +82,8 @@ abstract class AbstractKotlinNativeTargetPreset<T : KotlinNativeTarget>(
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allow IDE to resolve the libraries provided by the compiler by adding them into dependencies.
|
|
||||||
private fun addDependenciesOnLibrariesFromDistribution(result: T) {
|
|
||||||
result.compilations.all { compilation ->
|
|
||||||
val target = compilation.konanTarget
|
|
||||||
project.whenEvaluated {
|
|
||||||
// First, put common libs:
|
|
||||||
defaultLibs(!compilation.enableEndorsedLibs).forEach {
|
|
||||||
project.dependencies.add(compilation.compileDependencyConfigurationName, it)
|
|
||||||
}
|
|
||||||
// Then, platform-specific libs:
|
|
||||||
platformLibs(target).forEach {
|
|
||||||
project.dependencies.add(compilation.compileDependencyConfigurationName, it)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add dependencies to stdlib-native for intermediate single-backend source-sets (like 'allNative')
|
|
||||||
project.whenEvaluated {
|
|
||||||
val compilationsBySourceSets = CompilationSourceSetUtil.compilationsBySourceSets(this)
|
|
||||||
|
|
||||||
fun KotlinSourceSet.isIntermediateNativeSourceSet(): Boolean {
|
|
||||||
val compilations = compilationsBySourceSets[this] ?: return false
|
|
||||||
|
|
||||||
if (compilations.all { it.defaultSourceSet == this })
|
|
||||||
return false
|
|
||||||
|
|
||||||
return compilations.all { it.target.platformType == KotlinPlatformType.native }
|
|
||||||
}
|
|
||||||
|
|
||||||
val stdlib = defaultLibs(stdlibOnly = true).singleOrNull() ?: run {
|
|
||||||
warnAboutMissingNativeStdlib(project)
|
|
||||||
return@whenEvaluated
|
|
||||||
}
|
|
||||||
|
|
||||||
project.kotlinExtension.sourceSets
|
|
||||||
.filter { it.isIntermediateNativeSourceSet() }
|
|
||||||
.forEach {
|
|
||||||
project.dependencies.add(it.implementationMetadataConfigurationName, stdlib)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private const val KOTLIN_NATIVE_HOME_PRIVATE_PROPERTY = "konanHome"
|
private const val KOTLIN_NATIVE_HOME_PRIVATE_PROPERTY = "konanHome"
|
||||||
|
|
||||||
private fun warnAboutMissingNativeStdlib(project: Project) {
|
|
||||||
if (!project.hasProperty("kotlin.native.nostdlib")) {
|
|
||||||
SingleWarningPerBuild.show(
|
|
||||||
project,
|
|
||||||
buildString {
|
|
||||||
append(NO_NATIVE_STDLIB_WARNING)
|
|
||||||
if (PropertiesProvider(project).nativeHome != null)
|
|
||||||
append(NO_NATIVE_STDLIB_PROPERTY_WARNING)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal const val NO_NATIVE_STDLIB_WARNING =
|
|
||||||
"The Kotlin/Native distribution used in this build does not provide the standard library. "
|
|
||||||
|
|
||||||
internal const val NO_NATIVE_STDLIB_PROPERTY_WARNING =
|
|
||||||
"Make sure that the '${PropertiesProvider.KOTLIN_NATIVE_HOME}' property points to a valid Kotlin/Native distribution."
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+127
@@ -0,0 +1,127 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2020 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.jetbrains.kotlin.konan.library.KONAN_DISTRIBUTION_KLIB_DIR
|
||||||
|
import org.jetbrains.kotlin.konan.target.KonanTarget
|
||||||
|
import java.io.File
|
||||||
|
import java.io.IOException
|
||||||
|
import java.nio.charset.StandardCharsets
|
||||||
|
import java.nio.file.AtomicMoveNotSupportedException
|
||||||
|
import java.nio.file.Files
|
||||||
|
import java.nio.file.StandardCopyOption
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
internal fun runCommonizerInBulk(
|
||||||
|
distributionDir: File,
|
||||||
|
baseDestinationDir: File,
|
||||||
|
targetGroups: List<Set<KonanTarget>>,
|
||||||
|
kotlinVersion: String
|
||||||
|
): List<File> {
|
||||||
|
val commandLineParameters = mutableListOf<String>()
|
||||||
|
val postActions = mutableListOf<() -> Unit>()
|
||||||
|
|
||||||
|
val result = targetGroups.map { targets ->
|
||||||
|
if (targets.size == 1) {
|
||||||
|
// no need to commonize, just use the libraries from the distribution
|
||||||
|
distributionDir.resolve(KONAN_DISTRIBUTION_KLIB_DIR)
|
||||||
|
} else {
|
||||||
|
// naive up-to-date check:
|
||||||
|
// "X.Y.Z-SNAPSHOT" is not enough to uniquely identify the concrete version of Kotlin plugin,
|
||||||
|
// therefore lets assume that it's always not up to date
|
||||||
|
val definitelyNotUpToDate = kotlinVersion.endsWith("SNAPSHOT", ignoreCase = true)
|
||||||
|
|
||||||
|
// need stable order of targets for consistency
|
||||||
|
val orderedTargets = targets.sortedBy { it.name }
|
||||||
|
|
||||||
|
val discriminator = buildString {
|
||||||
|
orderedTargets.joinTo(this, separator = "-")
|
||||||
|
append("-")
|
||||||
|
append(kotlinVersion.toLowerCase().base64)
|
||||||
|
}
|
||||||
|
|
||||||
|
val destinationDir = baseDestinationDir.resolve(discriminator)
|
||||||
|
if (definitelyNotUpToDate || !destinationDir.isDirectory) {
|
||||||
|
val parentDir = destinationDir.parentFile
|
||||||
|
parentDir.mkdirs()
|
||||||
|
|
||||||
|
val destinationTmpDir = createTempDir(
|
||||||
|
prefix = "tmp-" + destinationDir.name,
|
||||||
|
suffix = ".new",
|
||||||
|
directory = parentDir
|
||||||
|
)
|
||||||
|
|
||||||
|
commandLineParameters += "native-dist-commonize"
|
||||||
|
commandLineParameters += "-distribution-path"
|
||||||
|
commandLineParameters += distributionDir.toString()
|
||||||
|
commandLineParameters += "-output-path"
|
||||||
|
commandLineParameters += destinationTmpDir.toString()
|
||||||
|
commandLineParameters += "-targets"
|
||||||
|
commandLineParameters += orderedTargets.joinToString(separator = ",")
|
||||||
|
|
||||||
|
postActions.add { renameDirectory(destinationTmpDir, destinationDir) }
|
||||||
|
}
|
||||||
|
|
||||||
|
destinationDir
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
callCommonizerCLI(commandLineParameters)
|
||||||
|
|
||||||
|
postActions.forEach { it() }
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun callCommonizerCLI(commandLineParameters: List<String>) {
|
||||||
|
if (commandLineParameters.isEmpty()) return
|
||||||
|
|
||||||
|
// TODO: implement
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun renameDirectory(source: File, destination: File) {
|
||||||
|
val sourcePath = source.toPath()
|
||||||
|
val destinationPath = destination.toPath()
|
||||||
|
|
||||||
|
val suppressedExceptions = mutableListOf<IOException>()
|
||||||
|
|
||||||
|
for (it in 0 until 3) {
|
||||||
|
try {
|
||||||
|
safeDelete(destination)
|
||||||
|
Files.move(sourcePath, destinationPath, StandardCopyOption.ATOMIC_MOVE)
|
||||||
|
return
|
||||||
|
} catch (e: IOException) {
|
||||||
|
suppressedExceptions += e
|
||||||
|
|
||||||
|
if (e is AtomicMoveNotSupportedException) {
|
||||||
|
// new attempts have no more sense
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw IllegalStateException("Failed to rename $source to $destination").apply { suppressedExceptions.forEach(::addSuppressed) }
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun safeDelete(directory: File) {
|
||||||
|
if (!directory.exists()) return
|
||||||
|
|
||||||
|
// first, rename directory to some temp directory
|
||||||
|
val tempDir = createTempFile(
|
||||||
|
prefix = "tmp-" + directory.name,
|
||||||
|
suffix = ".old",
|
||||||
|
directory = directory.parentFile
|
||||||
|
)
|
||||||
|
tempDir.delete()
|
||||||
|
|
||||||
|
Files.move(directory.toPath(), tempDir.toPath(), StandardCopyOption.ATOMIC_MOVE)
|
||||||
|
|
||||||
|
// only then delete it recursively
|
||||||
|
tempDir.deleteRecursively()
|
||||||
|
}
|
||||||
|
|
||||||
|
private val String.base64
|
||||||
|
get() = Base64.getEncoder().encodeToString(toByteArray(StandardCharsets.UTF_8))
|
||||||
+268
@@ -0,0 +1,268 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2020 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.jetbrains.kotlin.compilerRunner.konanHome
|
||||||
|
import org.jetbrains.kotlin.gradle.dsl.multiplatformExtensionOrNull
|
||||||
|
import org.jetbrains.kotlin.gradle.internal.isInIdeaSync
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.Companion.KOTLIN_NATIVE_HOME
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.compareVersionNumbers
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.getKotlinPluginVersion
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.mpp.CompilationSourceSetUtil
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeCompilation
|
||||||
|
import org.jetbrains.kotlin.gradle.targets.metadata.isKotlinGranularMetadataEnabled
|
||||||
|
import org.jetbrains.kotlin.gradle.targets.native.internal.NativePlatformDependency.*
|
||||||
|
import org.jetbrains.kotlin.gradle.utils.SingleWarningPerBuild
|
||||||
|
import org.jetbrains.kotlin.konan.library.*
|
||||||
|
import org.jetbrains.kotlin.konan.target.KonanTarget
|
||||||
|
import org.jetbrains.kotlin.utils.addToStdlib.flattenTo
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
|
internal fun Project.setUpKotlinNativePlatformDependencies() {
|
||||||
|
if (multiplatformExtensionOrNull == null) {
|
||||||
|
// not a multiplatform project, nothing to set up
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
val kotlinVersion = getKotlinPluginVersion()!!
|
||||||
|
|
||||||
|
// run commonizer only for 1.4+, only for HMPP projects and only on IDE sync
|
||||||
|
val allowCommonizer = compareVersionNumbers(kotlinVersion, "1.4") >= 0
|
||||||
|
&& isKotlinGranularMetadataEnabled
|
||||||
|
&& isInIdeaSync
|
||||||
|
|
||||||
|
val dependencyResolver = NativePlatformDependencyResolver(this, kotlinVersion)
|
||||||
|
|
||||||
|
findSourceSetsToAddDependencies(allowCommonizer).forEach { (sourceSet: KotlinSourceSet, sourceSetDeps: Set<NativePlatformDependency>) ->
|
||||||
|
sourceSetDeps.forEach { sourceSetDep: NativePlatformDependency ->
|
||||||
|
dependencyResolver.addForResolve(sourceSetDep) { resolvedFiles: Set<File> ->
|
||||||
|
resolvedFiles.forEach { resolvedFile ->
|
||||||
|
dependencies.add(sourceSet.implementationMetadataConfigurationName, dependencies.create(files(resolvedFile)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencyResolver.resolveAll()
|
||||||
|
}
|
||||||
|
|
||||||
|
private sealed class NativePlatformDependency {
|
||||||
|
/* Non-commonized target-neutral libraries taken directly from the Kotlin/Native distribution */
|
||||||
|
data class OutOfDistributionCommon(val includeEndorsedLibs: Boolean) : NativePlatformDependency()
|
||||||
|
|
||||||
|
/* Non-commonized libraries for the specific target taken directly from the Kotlin/Native distribution */
|
||||||
|
data class OutOfDistributionPlatform(val target: KonanTarget) : NativePlatformDependency()
|
||||||
|
|
||||||
|
/* Commonized (common) libraries */
|
||||||
|
data class CommonizedCommon(val targets: Set<KonanTarget>) : NativePlatformDependency()
|
||||||
|
|
||||||
|
/* Commonized libraries for a specific target platform */
|
||||||
|
data class CommonizedPlatform(val target: KonanTarget, val common: CommonizedCommon) : NativePlatformDependency()
|
||||||
|
}
|
||||||
|
|
||||||
|
private class NativePlatformDependencyResolver(val project: Project, val kotlinVersion: String) {
|
||||||
|
private val distributionDir = File(project.konanHome)
|
||||||
|
private val distributionLibsDir = distributionDir.resolve(KONAN_DISTRIBUTION_KLIB_DIR)
|
||||||
|
|
||||||
|
private var alreadyResolved = false
|
||||||
|
private val dependencies = mutableMapOf<NativePlatformDependency, MutableList<(Set<File>) -> Unit>>()
|
||||||
|
|
||||||
|
fun addForResolve(dependency: NativePlatformDependency, whenResolved: (Set<File>) -> Unit) {
|
||||||
|
check(!alreadyResolved)
|
||||||
|
dependencies.computeIfAbsent(dependency) { mutableListOf() }.add(whenResolved)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun resolveAll() {
|
||||||
|
check(!alreadyResolved)
|
||||||
|
alreadyResolved = true
|
||||||
|
|
||||||
|
// first, run commonization
|
||||||
|
val targetGroups: List<Pair<CommonizedCommon, Set<KonanTarget>>> = dependencies.keys.filterIsInstance<CommonizedCommon>()
|
||||||
|
.map { it to it.targets }
|
||||||
|
|
||||||
|
val commonizedLibsDirs: Map<CommonizedCommon, File> =
|
||||||
|
runCommonizerInBulk(
|
||||||
|
distributionDir = distributionDir,
|
||||||
|
baseDestinationDir = distributionDir.resolve(KONAN_DISTRIBUTION_KLIB_DIR).resolve(KONAN_DISTRIBUTION_COMMONIZED_LIBS_DIR),
|
||||||
|
targetGroups = targetGroups.map { it.second },
|
||||||
|
kotlinVersion = kotlinVersion
|
||||||
|
).mapIndexed { index: Int, commonizedLibsDir: File ->
|
||||||
|
targetGroups[index].first to commonizedLibsDir
|
||||||
|
}.toMap()
|
||||||
|
|
||||||
|
// then, resolve dependencies one by one
|
||||||
|
dependencies.forEach { (dependency, actions) ->
|
||||||
|
val libs = when (dependency) {
|
||||||
|
is OutOfDistributionCommon -> {
|
||||||
|
/* stdlib, endorsed libs */
|
||||||
|
var hasStdlib = false
|
||||||
|
|
||||||
|
val libs = libsInCommonDir(distributionLibsDir) { dir ->
|
||||||
|
val isStdlib = dir.endsWith(KONAN_STDLIB_NAME)
|
||||||
|
hasStdlib = hasStdlib || isStdlib
|
||||||
|
|
||||||
|
return@libsInCommonDir isStdlib || dependency.includeEndorsedLibs
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hasStdlib) warnAboutMissingNativeStdlib()
|
||||||
|
|
||||||
|
libs
|
||||||
|
}
|
||||||
|
|
||||||
|
is OutOfDistributionPlatform -> {
|
||||||
|
/* platform libs for a specific target */
|
||||||
|
libsInPlatformDir(distributionLibsDir, dependency.target)
|
||||||
|
}
|
||||||
|
|
||||||
|
is CommonizedCommon -> {
|
||||||
|
/* commonized platform libs with expect declarations */
|
||||||
|
val commonizedLibsDir = commonizedLibsDirs.getValue(dependency)
|
||||||
|
libsInCommonDir(commonizedLibsDir)
|
||||||
|
}
|
||||||
|
|
||||||
|
is CommonizedPlatform -> {
|
||||||
|
/* commonized platform libs with actual declarations */
|
||||||
|
val commonizedLibsDir = commonizedLibsDirs.getValue(dependency.common)
|
||||||
|
libsInPlatformDir(commonizedLibsDir, dependency.target)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
actions.forEach { it(libs) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun warnAboutMissingNativeStdlib() {
|
||||||
|
if (!project.hasProperty("kotlin.native.nostdlib")) {
|
||||||
|
SingleWarningPerBuild.show(
|
||||||
|
project,
|
||||||
|
buildString {
|
||||||
|
append(NO_NATIVE_STDLIB_WARNING)
|
||||||
|
if (PropertiesProvider(project).nativeHome != null)
|
||||||
|
append(NO_NATIVE_STDLIB_PROPERTY_WARNING)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private fun libsInCommonDir(basePath: File, predicate: (File) -> Boolean = { true }) =
|
||||||
|
basePath.resolve(KONAN_DISTRIBUTION_COMMON_LIBS_DIR).listFiles()?.filter { predicate(it) }?.toSet() ?: emptySet()
|
||||||
|
|
||||||
|
private fun libsInPlatformDir(basePath: File, target: KonanTarget) =
|
||||||
|
basePath.resolve(KONAN_DISTRIBUTION_PLATFORM_LIBS_DIR).resolve(target.name).listFiles()?.toSet() ?: emptySet()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun Project.findSourceSetsToAddDependencies(allowCommonizer: Boolean): Map<KotlinSourceSet, Set<NativePlatformDependency>> {
|
||||||
|
val sourceSetsToAddDeps = mutableMapOf<KotlinSourceSet, Set<NativePlatformDependency>>()
|
||||||
|
if (allowCommonizer) {
|
||||||
|
sourceSetsToAddDeps += findSourceSetsToAddCommonizedPlatformDependencies()
|
||||||
|
}
|
||||||
|
|
||||||
|
val compilationsBySourceSets = CompilationSourceSetUtil.compilationsBySourceSets(this)
|
||||||
|
val nativeCompilations = compilationsBySourceSets.values.flattenTo(mutableSetOf()).filterIsInstance<KotlinNativeCompilation>()
|
||||||
|
|
||||||
|
nativeCompilations.associate { it.defaultSourceSet to NativeSourceSetDetails(it.konanTarget, it.enableEndorsedLibs) }
|
||||||
|
.forEach { (defaultSourceSet, details) ->
|
||||||
|
if (defaultSourceSet !in sourceSetsToAddDeps) {
|
||||||
|
sourceSetsToAddDeps[defaultSourceSet] = setOf(
|
||||||
|
OutOfDistributionCommon(details.includeEndorsedLibs),
|
||||||
|
OutOfDistributionPlatform(details.target)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return sourceSetsToAddDeps
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun Project.findSourceSetsToAddCommonizedPlatformDependencies(): Map<KotlinSourceSet, Set<NativePlatformDependency>> {
|
||||||
|
val sourceSetsToAddDeps = mutableMapOf<KotlinSourceSet, Set<NativePlatformDependency>>()
|
||||||
|
|
||||||
|
val compilationsBySourceSets = CompilationSourceSetUtil.compilationsBySourceSets(this)
|
||||||
|
val nativeCompilations = compilationsBySourceSets.values.flattenTo(mutableSetOf()).filterIsInstance<KotlinNativeCompilation>()
|
||||||
|
|
||||||
|
nativeCompilations.forEach { nativeCompilation ->
|
||||||
|
// consider source sets in compilation only one step above the default source set
|
||||||
|
// TODO: reconsider this restriction
|
||||||
|
val commonSourceSetCandidates = nativeCompilation.defaultSourceSet.dependsOn - nativeCompilation.defaultSourceSet
|
||||||
|
|
||||||
|
commonSourceSetCandidates.forEach sourceSet@{ sourceSet ->
|
||||||
|
if (sourceSet.name == KotlinSourceSet.COMMON_MAIN_SOURCE_SET_NAME
|
||||||
|
|| sourceSet.name == KotlinSourceSet.COMMON_TEST_SOURCE_SET_NAME
|
||||||
|
) {
|
||||||
|
// exclude the most common source sets
|
||||||
|
return@sourceSet
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sourceSet in sourceSetsToAddDeps) {
|
||||||
|
// already processed
|
||||||
|
return@sourceSet
|
||||||
|
}
|
||||||
|
|
||||||
|
val leafSourceSets = mutableMapOf<KotlinSourceSet, NativeSourceSetDetails>()
|
||||||
|
|
||||||
|
for (compilation in compilationsBySourceSets.getValue(sourceSet)) {
|
||||||
|
if (compilation !is KotlinNativeCompilation) {
|
||||||
|
// the source set participates in non-native compilation
|
||||||
|
return@sourceSet
|
||||||
|
}
|
||||||
|
|
||||||
|
val defaultSourceSet = compilation.defaultSourceSet
|
||||||
|
if (defaultSourceSet == sourceSet) {
|
||||||
|
// there is a compilation where the source set is the default source set
|
||||||
|
return@sourceSet
|
||||||
|
}
|
||||||
|
|
||||||
|
leafSourceSets[defaultSourceSet] = NativeSourceSetDetails(
|
||||||
|
target = compilation.konanTarget,
|
||||||
|
includeEndorsedLibs = compilation.enableEndorsedLibs
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
val allTargets = leafSourceSets.values.mapTo(mutableSetOf()) { it.target }
|
||||||
|
if (allTargets.isEmpty())
|
||||||
|
return@sourceSet
|
||||||
|
|
||||||
|
val commonizedCommonDep = CommonizedCommon(allTargets)
|
||||||
|
val includeEndorsedLibsToCommonSourceSet = leafSourceSets.values.all { it.includeEndorsedLibs }
|
||||||
|
|
||||||
|
sourceSetsToAddDeps[sourceSet] = setOf(
|
||||||
|
OutOfDistributionCommon(includeEndorsedLibsToCommonSourceSet),
|
||||||
|
commonizedCommonDep
|
||||||
|
)
|
||||||
|
|
||||||
|
leafSourceSets.forEach { (leafSourceSet, details) ->
|
||||||
|
val existingDep = sourceSetsToAddDeps[leafSourceSet]
|
||||||
|
if (existingDep == null) {
|
||||||
|
val commonizedPlatformDep = CommonizedPlatform(details.target, commonizedCommonDep)
|
||||||
|
|
||||||
|
sourceSetsToAddDeps[leafSourceSet] = setOf(
|
||||||
|
OutOfDistributionCommon(details.includeEndorsedLibs),
|
||||||
|
commonizedPlatformDep
|
||||||
|
)
|
||||||
|
} /*else if (existingDep != leafDep) {
|
||||||
|
// actually, no action required
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return sourceSetsToAddDeps
|
||||||
|
}
|
||||||
|
|
||||||
|
private class NativeSourceSetDetails(
|
||||||
|
val target: KonanTarget,
|
||||||
|
val includeEndorsedLibs: Boolean
|
||||||
|
)
|
||||||
|
|
||||||
|
internal const val NO_NATIVE_STDLIB_WARNING =
|
||||||
|
"The Kotlin/Native distribution used in this build does not provide the standard library. "
|
||||||
|
|
||||||
|
internal const val NO_NATIVE_STDLIB_PROPERTY_WARNING =
|
||||||
|
"Make sure that the '$KOTLIN_NATIVE_HOME' property points to a valid Kotlin/Native distribution."
|
||||||
+12
-13
@@ -5,28 +5,27 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.gradle.internals
|
package org.jetbrains.kotlin.gradle.internals
|
||||||
|
|
||||||
import org.jetbrains.kotlin.gradle.plugin.mpp.AbstractKotlinNativeTargetPreset.Companion.NO_NATIVE_STDLIB_PROPERTY_WARNING
|
import org.jetbrains.kotlin.gradle.plugin.KOTLIN_12X_MPP_DEPRECATION_WARNING
|
||||||
import org.jetbrains.kotlin.gradle.plugin.mpp.AbstractKotlinNativeTargetPreset.Companion.NO_NATIVE_STDLIB_WARNING
|
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinMultiplatformPlugin.Companion.GRADLE_NO_METADATA_WARNING
|
||||||
|
import org.jetbrains.kotlin.gradle.targets.native.internal.NO_NATIVE_STDLIB_PROPERTY_WARNING
|
||||||
|
import org.jetbrains.kotlin.gradle.targets.native.internal.NO_NATIVE_STDLIB_WARNING
|
||||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinProjectStructureMetadata
|
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinProjectStructureMetadata
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.mpp.MULTIPLATFORM_PROJECT_METADATA_FILE_NAME
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.mpp.parseKotlinSourceSetMetadataFromXml
|
||||||
import org.jetbrains.kotlin.gradle.targets.native.DisabledNativeTargetsReporter
|
import org.jetbrains.kotlin.gradle.targets.native.DisabledNativeTargetsReporter
|
||||||
import org.w3c.dom.Document
|
import org.w3c.dom.Document
|
||||||
|
|
||||||
fun parseKotlinSourceSetMetadataFromXml(document: Document): KotlinProjectStructureMetadata? =
|
fun parseKotlinSourceSetMetadataFromXml(document: Document): KotlinProjectStructureMetadata? = parseKotlinSourceSetMetadataFromXml(document)
|
||||||
org.jetbrains.kotlin.gradle.plugin.mpp.parseKotlinSourceSetMetadataFromXml(document)
|
|
||||||
|
|
||||||
const val MULTIPLATFORM_PROJECT_METADATA_FILE_NAME =
|
const val MULTIPLATFORM_PROJECT_METADATA_FILE_NAME = MULTIPLATFORM_PROJECT_METADATA_FILE_NAME
|
||||||
org.jetbrains.kotlin.gradle.plugin.mpp.MULTIPLATFORM_PROJECT_METADATA_FILE_NAME
|
|
||||||
|
|
||||||
const val GRADLE_NO_METADATA_WARNING =
|
const val GRADLE_NO_METADATA_WARNING = GRADLE_NO_METADATA_WARNING
|
||||||
org.jetbrains.kotlin.gradle.plugin.mpp.KotlinMultiplatformPlugin.GRADLE_NO_METADATA_WARNING
|
|
||||||
|
|
||||||
const val DISABLED_NATIVE_TARGETS_REPORTER_DISABLE_WARNING_PROPERTY_NAME =
|
const val DISABLED_NATIVE_TARGETS_REPORTER_DISABLE_WARNING_PROPERTY_NAME = DisabledNativeTargetsReporter.DISABLE_WARNING_PROPERTY_NAME
|
||||||
DisabledNativeTargetsReporter.DISABLE_WARNING_PROPERTY_NAME
|
|
||||||
|
|
||||||
const val DISABLED_NATIVE_TARGETS_REPORTER_WARNING_PREFIX: String =
|
const val DISABLED_NATIVE_TARGETS_REPORTER_WARNING_PREFIX: String = DisabledNativeTargetsReporter.WARNING_PREFIX
|
||||||
DisabledNativeTargetsReporter.WARNING_PREFIX
|
|
||||||
|
|
||||||
const val NO_NATIVE_STDLIB_WARNING = NO_NATIVE_STDLIB_WARNING
|
const val NO_NATIVE_STDLIB_WARNING = NO_NATIVE_STDLIB_WARNING
|
||||||
const val NO_NATIVE_STDLIB_PROPERTY_WARNING = NO_NATIVE_STDLIB_PROPERTY_WARNING
|
const val NO_NATIVE_STDLIB_PROPERTY_WARNING = NO_NATIVE_STDLIB_PROPERTY_WARNING
|
||||||
|
|
||||||
val KOTLIN_12X_MPP_DEPRECATION_WARNING = org.jetbrains.kotlin.gradle.plugin.KOTLIN_12X_MPP_DEPRECATION_WARNING
|
val KOTLIN_12X_MPP_DEPRECATION_WARNING = KOTLIN_12X_MPP_DEPRECATION_WARNING
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ const val KONAN_STDLIB_NAME = "stdlib"
|
|||||||
const val KONAN_DISTRIBUTION_KLIB_DIR = "klib"
|
const val KONAN_DISTRIBUTION_KLIB_DIR = "klib"
|
||||||
const val KONAN_DISTRIBUTION_COMMON_LIBS_DIR = "common"
|
const val KONAN_DISTRIBUTION_COMMON_LIBS_DIR = "common"
|
||||||
const val KONAN_DISTRIBUTION_PLATFORM_LIBS_DIR = "platform"
|
const val KONAN_DISTRIBUTION_PLATFORM_LIBS_DIR = "platform"
|
||||||
|
const val KONAN_DISTRIBUTION_COMMONIZED_LIBS_DIR = "commonized"
|
||||||
|
|
||||||
const val KONAN_DISTRIBUTION_SOURCES_DIR = "sources"
|
const val KONAN_DISTRIBUTION_SOURCES_DIR = "sources"
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user