[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
|
@file:Suppress("PackageDirectoryMismatch") // Old package for compatibility
|
||||||
package org.jetbrains.kotlin.gradle.plugin
|
package org.jetbrains.kotlin.gradle.plugin
|
||||||
|
|
||||||
import org.gradle.api.DefaultTask
|
|
||||||
import org.gradle.api.NamedDomainObjectCollection
|
import org.gradle.api.NamedDomainObjectCollection
|
||||||
import org.gradle.api.Project
|
import org.gradle.api.Project
|
||||||
import org.gradle.api.Task
|
|
||||||
import org.gradle.api.artifacts.Dependency
|
import org.gradle.api.artifacts.Dependency
|
||||||
import org.gradle.api.attributes.Category
|
import org.gradle.api.attributes.Category
|
||||||
import org.gradle.api.attributes.Usage.USAGE_ATTRIBUTE
|
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.KotlinCompilation.Companion.TEST_COMPILATION_NAME
|
||||||
import org.jetbrains.kotlin.gradle.plugin.KotlinPluginLifecycle.Stage.ReadyForExecution
|
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.PropertiesProvider.Companion.KOTLIN_NATIVE_IGNORE_INCORRECT_DEPENDENCIES
|
||||||
import org.jetbrains.kotlin.gradle.plugin.mpp.*
|
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.registerEmbedAndSignAppleFrameworkTask
|
||||||
import org.jetbrains.kotlin.gradle.plugin.mpp.apple.version
|
|
||||||
import org.jetbrains.kotlin.gradle.artifacts.createKlibArtifact
|
import org.jetbrains.kotlin.gradle.artifacts.createKlibArtifact
|
||||||
import org.jetbrains.kotlin.gradle.artifacts.klibOutputDirectory
|
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.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.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.gradle.utils.newInstance
|
||||||
import org.jetbrains.kotlin.konan.target.HostManager
|
|
||||||
|
|
||||||
open class KotlinNativeTargetConfigurator<T : KotlinNativeTarget> : AbstractKotlinTargetConfigurator<T>(
|
open class KotlinNativeTargetConfigurator<T : KotlinNativeTarget> : AbstractKotlinTargetConfigurator<T>(
|
||||||
createTestCompilation = true
|
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.NativeBuildType
|
||||||
import org.jetbrains.kotlin.gradle.plugin.mpp.isCurrentHost
|
import org.jetbrains.kotlin.gradle.plugin.mpp.isCurrentHost
|
||||||
import org.jetbrains.kotlin.gradle.targets.KotlinTestRunFactory
|
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.KotlinNativeSimulatorTest
|
||||||
import org.jetbrains.kotlin.gradle.targets.native.tasks.KotlinNativeTest
|
import org.jetbrains.kotlin.gradle.targets.native.tasks.KotlinNativeTest
|
||||||
import org.jetbrains.kotlin.gradle.tasks.registerTask
|
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.internal.kotlinTestRegistry
|
||||||
import org.jetbrains.kotlin.gradle.testing.testTaskName
|
import org.jetbrains.kotlin.gradle.testing.testTaskName
|
||||||
import org.jetbrains.kotlin.gradle.utils.XcodeUtils
|
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.HostManager
|
||||||
import org.jetbrains.kotlin.konan.target.KonanTarget
|
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) {
|
private fun KotlinNativeSimulatorTest.configureDeviceId(konanTarget: KonanTarget) {
|
||||||
if (!isEnabled) return
|
if (!isEnabled) return
|
||||||
val deviceIdProvider = project.provider {
|
val deviceIdProvider = project.valueSourceProviderCompat(XcodeDefaultTestDevicesValueSource::class.java)
|
||||||
XcodeUtils.getDefaultTestDeviceId(konanTarget) ?: error(
|
|
||||||
"Xcode does not support simulator tests for ${konanTarget.name}. Check that requested SDK is installed."
|
// 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.ARM32
|
||||||
import org.jetbrains.kotlin.konan.target.Architecture.ARM64
|
import org.jetbrains.kotlin.konan.target.Architecture.ARM64
|
||||||
import org.jetbrains.kotlin.konan.target.Family.*
|
import org.jetbrains.kotlin.konan.target.Family.*
|
||||||
import org.jetbrains.kotlin.util.capitalizeDecapitalize.toUpperCaseAsciiOnly
|
|
||||||
|
|
||||||
@InternalKotlinGradlePluginApi
|
@InternalKotlinGradlePluginApi
|
||||||
object XcodeUtils {
|
object XcodeUtils {
|
||||||
@@ -41,44 +40,6 @@ object XcodeUtils {
|
|||||||
&& target.family in listOf(IOS, WATCHOS, TVOS)
|
&& target.family in listOf(IOS, WATCHOS, TVOS)
|
||||||
&& target.architecture in listOf(ARM32, ARM64)
|
&& 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 {
|
internal fun XcodeVersion.Companion.parse(file: Provider<RegularFile>): XcodeVersion {
|
||||||
|
|||||||
+17
-7
@@ -21,20 +21,15 @@ import org.gradle.api.Project
|
|||||||
import org.gradle.api.Task
|
import org.gradle.api.Task
|
||||||
import org.gradle.api.artifacts.ArtifactCollection
|
import org.gradle.api.artifacts.ArtifactCollection
|
||||||
import org.gradle.api.artifacts.result.ResolvedArtifactResult
|
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.internal.tasks.testing.TestDescriptorInternal
|
||||||
import org.gradle.api.provider.Provider
|
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.specs.Spec
|
||||||
import org.gradle.api.tasks.WorkResult
|
|
||||||
import org.gradle.api.tasks.bundling.AbstractArchiveTask
|
import org.gradle.api.tasks.bundling.AbstractArchiveTask
|
||||||
import org.gradle.api.tasks.testing.TestDescriptor
|
import org.gradle.api.tasks.testing.TestDescriptor
|
||||||
import org.gradle.util.GradleVersion
|
import org.gradle.util.GradleVersion
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.io.Serializable
|
|
||||||
|
|
||||||
const val minSupportedGradleVersion = "6.8.3"
|
const val minSupportedGradleVersion = "6.8.3"
|
||||||
|
|
||||||
@@ -100,3 +95,18 @@ internal fun ArtifactCollection.getResolvedArtifactsCompat(project: Project): Pr
|
|||||||
} else {
|
} else {
|
||||||
project.provider { artifacts }
|
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