[Gradle] Fix GCC support for IOS specific Kotlin Native Test Tasks
^KT-63044 Verification Pending
This commit is contained in:
committed by
Space Team
parent
704adc053a
commit
ebe0a84dee
-17
@@ -6,38 +6,21 @@
|
||||
@file:Suppress("PackageDirectoryMismatch") // Old package for compatibility
|
||||
package org.jetbrains.kotlin.gradle.plugin
|
||||
|
||||
import org.gradle.api.DefaultTask
|
||||
import org.gradle.api.NamedDomainObjectCollection
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.Task
|
||||
import org.gradle.api.artifacts.Dependency
|
||||
import org.gradle.api.attributes.Category
|
||||
import org.gradle.api.attributes.Usage.USAGE_ATTRIBUTE
|
||||
import org.gradle.api.plugins.BasePlugin
|
||||
import org.gradle.api.tasks.Exec
|
||||
import org.gradle.language.base.plugins.LifecycleBasePlugin
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation.Companion.TEST_COMPILATION_NAME
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinPluginLifecycle.Stage.ReadyForExecution
|
||||
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.plugin.mpp.apple.XcodeVersionTask
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.apple.registerEmbedAndSignAppleFrameworkTask
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.apple.version
|
||||
import org.jetbrains.kotlin.gradle.artifacts.createKlibArtifact
|
||||
import org.jetbrains.kotlin.gradle.artifacts.klibOutputDirectory
|
||||
import org.jetbrains.kotlin.gradle.targets.native.*
|
||||
import org.jetbrains.kotlin.gradle.targets.native.internal.*
|
||||
import org.jetbrains.kotlin.gradle.targets.native.tasks.KotlinNativeHostTest
|
||||
import org.jetbrains.kotlin.gradle.targets.native.tasks.KotlinNativeSimulatorTest
|
||||
import org.jetbrains.kotlin.gradle.targets.native.tasks.KotlinNativeTest
|
||||
import org.jetbrains.kotlin.gradle.tasks.*
|
||||
import org.jetbrains.kotlin.gradle.testing.internal.configureConventions
|
||||
import org.jetbrains.kotlin.gradle.testing.internal.kotlinTestRegistry
|
||||
import org.jetbrains.kotlin.gradle.testing.testTaskName
|
||||
import org.jetbrains.kotlin.gradle.utils.whenEvaluated
|
||||
import org.jetbrains.kotlin.gradle.utils.XcodeUtils
|
||||
import org.jetbrains.kotlin.gradle.utils.newInstance
|
||||
import org.jetbrains.kotlin.konan.target.HostManager
|
||||
|
||||
open class KotlinNativeTargetConfigurator<T : KotlinNativeTarget> : AbstractKotlinTargetConfigurator<T>(
|
||||
createTestCompilation = true
|
||||
|
||||
+12
-5
@@ -11,6 +11,7 @@ import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.NativeBuildType
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.isCurrentHost
|
||||
import org.jetbrains.kotlin.gradle.targets.KotlinTestRunFactory
|
||||
import org.jetbrains.kotlin.gradle.targets.native.internal.XcodeDefaultTestDevicesValueSource
|
||||
import org.jetbrains.kotlin.gradle.targets.native.tasks.KotlinNativeSimulatorTest
|
||||
import org.jetbrains.kotlin.gradle.targets.native.tasks.KotlinNativeTest
|
||||
import org.jetbrains.kotlin.gradle.tasks.registerTask
|
||||
@@ -18,6 +19,7 @@ import org.jetbrains.kotlin.gradle.testing.internal.configureConventions
|
||||
import org.jetbrains.kotlin.gradle.testing.internal.kotlinTestRegistry
|
||||
import org.jetbrains.kotlin.gradle.testing.testTaskName
|
||||
import org.jetbrains.kotlin.gradle.utils.XcodeUtils
|
||||
import org.jetbrains.kotlin.gradle.utils.valueSourceProviderCompat
|
||||
import org.jetbrains.kotlin.konan.target.HostManager
|
||||
import org.jetbrains.kotlin.konan.target.KonanTarget
|
||||
|
||||
@@ -65,10 +67,15 @@ private inline fun <reified T : KotlinNativeTest> KotlinNativeTarget.registerNat
|
||||
|
||||
private fun KotlinNativeSimulatorTest.configureDeviceId(konanTarget: KonanTarget) {
|
||||
if (!isEnabled) return
|
||||
val deviceIdProvider = project.provider {
|
||||
XcodeUtils.getDefaultTestDeviceId(konanTarget) ?: error(
|
||||
"Xcode does not support simulator tests for ${konanTarget.name}. Check that requested SDK is installed."
|
||||
)
|
||||
val deviceIdProvider = project.valueSourceProviderCompat(XcodeDefaultTestDevicesValueSource::class.java)
|
||||
|
||||
// Extract primitive values to avoid [target] capture in lambda
|
||||
val konanTargetFamily = konanTarget.family
|
||||
val konanTargetName = konanTarget.name
|
||||
|
||||
val defaultDevice = deviceIdProvider.map {
|
||||
it[konanTargetFamily]
|
||||
?: error("Xcode does not support simulator tests for ${konanTargetName}. Check that requested SDK is installed.")
|
||||
}
|
||||
device.convention(deviceIdProvider).finalizeValueOnRead()
|
||||
device.convention(defaultDevice).finalizeValueOnRead()
|
||||
}
|
||||
+63
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright 2010-2023 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.provider.ValueSource
|
||||
import org.gradle.api.provider.ValueSourceParameters
|
||||
import org.gradle.process.ExecOperations
|
||||
import org.jetbrains.kotlin.konan.target.Family
|
||||
import org.jetbrains.kotlin.konan.target.HostManager
|
||||
import org.jetbrains.kotlin.util.capitalizeDecapitalize.toUpperCaseAsciiOnly
|
||||
import java.io.ByteArrayOutputStream
|
||||
import java.nio.charset.Charset
|
||||
import javax.inject.Inject
|
||||
|
||||
internal abstract class XcodeDefaultTestDevicesValueSource : ValueSource<Map<Family, String>, ValueSourceParameters.None> {
|
||||
|
||||
@get:Inject
|
||||
abstract val execOperations: ExecOperations
|
||||
|
||||
override fun obtain(): Map<Family, String> {
|
||||
if (!HostManager.hostIsMac) {
|
||||
return emptyMap()
|
||||
}
|
||||
|
||||
val osRegex = "-- .* --".toRegex()
|
||||
val deviceRegex = """[0-9A-F]{8}-([0-9A-F]{4}-){3}[0-9A-F]{12}""".toRegex()
|
||||
|
||||
val output = ByteArrayOutputStream()
|
||||
execOperations.exec {
|
||||
it.commandLine(listOf("/usr/bin/xcrun", "simctl", "list", "devices", "available"))
|
||||
it.standardOutput = output
|
||||
}
|
||||
val out = String(output.toByteArray(), Charset.defaultCharset())
|
||||
|
||||
val result = mutableMapOf<Family, String>()
|
||||
var os: Family? = null
|
||||
out.lines().forEach { s ->
|
||||
val osFound = osRegex.find(s)?.value
|
||||
if (osFound != null) {
|
||||
val osName = osFound.split(" ")[1]
|
||||
os = try {
|
||||
Family.valueOf(osName.toUpperCaseAsciiOnly())
|
||||
} catch (e: Exception) {
|
||||
null
|
||||
}
|
||||
} else {
|
||||
val currentOs = os
|
||||
if (currentOs != null) {
|
||||
val deviceFound = deviceRegex.find(s)?.value
|
||||
if (deviceFound != null) {
|
||||
result[currentOs] = deviceFound
|
||||
os = null
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
}
|
||||
-39
@@ -13,7 +13,6 @@ import org.jetbrains.kotlin.konan.target.*
|
||||
import org.jetbrains.kotlin.konan.target.Architecture.ARM32
|
||||
import org.jetbrains.kotlin.konan.target.Architecture.ARM64
|
||||
import org.jetbrains.kotlin.konan.target.Family.*
|
||||
import org.jetbrains.kotlin.util.capitalizeDecapitalize.toUpperCaseAsciiOnly
|
||||
|
||||
@InternalKotlinGradlePluginApi
|
||||
object XcodeUtils {
|
||||
@@ -41,44 +40,6 @@ object XcodeUtils {
|
||||
&& target.family in listOf(IOS, WATCHOS, TVOS)
|
||||
&& target.architecture in listOf(ARM32, ARM64)
|
||||
}
|
||||
|
||||
fun getDefaultTestDeviceId(target: KonanTarget): String? = defaultTestDevices[target.family]
|
||||
|
||||
private val defaultTestDevices: Map<Family, String> by lazy {
|
||||
if (!HostManager.hostIsMac) {
|
||||
return@lazy emptyMap()
|
||||
}
|
||||
|
||||
val osRegex = "-- .* --".toRegex()
|
||||
val deviceRegex = """[0-9A-F]{8}-([0-9A-F]{4}-){3}[0-9A-F]{12}""".toRegex()
|
||||
|
||||
val out = runCommand(listOf("/usr/bin/xcrun", "simctl", "list", "devices", "available"))
|
||||
|
||||
val result = mutableMapOf<Family, String>()
|
||||
var os: Family? = null
|
||||
out.lines().forEach { s ->
|
||||
val osFound = osRegex.find(s)?.value
|
||||
if (osFound != null) {
|
||||
val osName = osFound.split(" ")[1]
|
||||
os = try {
|
||||
Family.valueOf(osName.toUpperCaseAsciiOnly())
|
||||
} catch (e: Exception) {
|
||||
null
|
||||
}
|
||||
} else {
|
||||
val currentOs = os
|
||||
if (currentOs != null) {
|
||||
val deviceFound = deviceRegex.find(s)?.value
|
||||
if (deviceFound != null) {
|
||||
result[currentOs] = deviceFound
|
||||
os = null
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
result
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
internal fun XcodeVersion.Companion.parse(file: Provider<RegularFile>): XcodeVersion {
|
||||
|
||||
+18
-8
@@ -21,20 +21,15 @@ import org.gradle.api.Project
|
||||
import org.gradle.api.Task
|
||||
import org.gradle.api.artifacts.ArtifactCollection
|
||||
import org.gradle.api.artifacts.result.ResolvedArtifactResult
|
||||
import org.gradle.api.file.ArchiveOperations
|
||||
import org.gradle.api.file.CopySpec
|
||||
import org.gradle.api.file.FileSystemOperations
|
||||
import org.gradle.api.file.FileTree
|
||||
import org.gradle.api.internal.project.ProjectInternal
|
||||
import org.gradle.api.internal.tasks.testing.TestDescriptorInternal
|
||||
import org.gradle.api.provider.Provider
|
||||
import org.gradle.api.provider.ValueSource
|
||||
import org.gradle.api.provider.ValueSourceParameters
|
||||
import org.gradle.api.specs.Spec
|
||||
import org.gradle.api.tasks.WorkResult
|
||||
import org.gradle.api.tasks.bundling.AbstractArchiveTask
|
||||
import org.gradle.api.tasks.testing.TestDescriptor
|
||||
import org.gradle.util.GradleVersion
|
||||
import java.io.File
|
||||
import java.io.Serializable
|
||||
|
||||
const val minSupportedGradleVersion = "6.8.3"
|
||||
|
||||
@@ -99,4 +94,19 @@ internal fun ArtifactCollection.getResolvedArtifactsCompat(project: Project): Pr
|
||||
resolvedArtifacts
|
||||
} else {
|
||||
project.provider { artifacts }
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* ValueSources are not well-supported with Configuration Cache in early Gradle versions
|
||||
* Gradle 8.1 is discovered experimentally
|
||||
*/
|
||||
internal fun <T> Project.valueSourceProviderCompat(
|
||||
clazz: Class<out ValueSource<T, ValueSourceParameters.None>>
|
||||
): Provider<T> {
|
||||
return if (GradleVersion.current() < GradleVersion.version("8.1")) {
|
||||
val vs = project.objects.newInstance(clazz)
|
||||
project.provider { vs.obtain() }
|
||||
} else {
|
||||
providers.of(clazz) { }
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user