[K/N] Add RosettaExecutor
Merge-request: KT-MR-9986 Merged-by: Alexander Shabalin <Alexander.Shabalin@jetbrains.com>
This commit is contained in:
committed by
Space Team
parent
917f64c893
commit
142e2b4b2a
@@ -53,7 +53,7 @@ private fun Executor.service(project: Project) = object: ExecutorService {
|
|||||||
val execSpec = project.objects.newInstance<DefaultExecSpec>().apply {
|
val execSpec = project.objects.newInstance<DefaultExecSpec>().apply {
|
||||||
action.execute(this)
|
action.execute(this)
|
||||||
}
|
}
|
||||||
val request = executeRequest(
|
val request = ExecuteRequest(
|
||||||
executableAbsolutePath = execSpec.executable,
|
executableAbsolutePath = execSpec.executable,
|
||||||
args = execSpec.args,
|
args = execSpec.args,
|
||||||
).apply {
|
).apply {
|
||||||
@@ -105,6 +105,7 @@ fun create(project: Project): ExecutorService {
|
|||||||
}
|
}
|
||||||
}.service(project)
|
}.service(project)
|
||||||
supportsRunningTestsOnDevice(testTarget) -> deviceLauncher(project)
|
supportsRunningTestsOnDevice(testTarget) -> deviceLauncher(project)
|
||||||
|
configurables is AppleConfigurables && RosettaExecutor.availableFor(configurables) -> RosettaExecutor(configurables).service(project)
|
||||||
else -> HostExecutor().service(project)
|
else -> HostExecutor().service(project)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ private abstract class RunGTestJob : WorkAction<RunGTestJob.Parameters> {
|
|||||||
when {
|
when {
|
||||||
target == hostTarget -> HostExecutor()
|
target == hostTarget -> HostExecutor()
|
||||||
configurables is AppleConfigurables && configurables.targetTriple.isSimulator -> XcodeSimulatorExecutor(configurables)
|
configurables is AppleConfigurables && configurables.targetTriple.isSimulator -> XcodeSimulatorExecutor(configurables)
|
||||||
|
configurables is AppleConfigurables && RosettaExecutor.availableFor(configurables) -> RosettaExecutor(configurables)
|
||||||
else -> error("Cannot run for target $target")
|
else -> error("Cannot run for target $target")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -50,7 +51,7 @@ private abstract class RunGTestJob : WorkAction<RunGTestJob.Parameters> {
|
|||||||
with(parameters) {
|
with(parameters) {
|
||||||
reportFileUnprocessed.asFile.get().parentFile.mkdirs()
|
reportFileUnprocessed.asFile.get().parentFile.mkdirs()
|
||||||
|
|
||||||
executor.execute(executeRequest(this@with.executable.asFile.get().absolutePath).apply {
|
executor.execute(ExecuteRequest(this@with.executable.asFile.get().absolutePath).apply {
|
||||||
this.args.add("--gtest_output=xml:${reportFileUnprocessed.asFile.get().absolutePath}")
|
this.args.add("--gtest_output=xml:${reportFileUnprocessed.asFile.get().absolutePath}")
|
||||||
filter.orNull?.also {
|
filter.orNull?.also {
|
||||||
this.args.add("--gtest_filter=${it}")
|
this.args.add("--gtest_filter=${it}")
|
||||||
|
|||||||
@@ -3,8 +3,6 @@
|
|||||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@file:OptIn(ExperimentalTime::class)
|
|
||||||
|
|
||||||
package org.jetbrains.kotlin.native.executors
|
package org.jetbrains.kotlin.native.executors
|
||||||
|
|
||||||
import java.io.*
|
import java.io.*
|
||||||
@@ -62,13 +60,6 @@ data class ExecuteRequest(
|
|||||||
inline fun copying(block: ExecuteRequest.() -> Unit): ExecuteRequest = copy().apply(block)
|
inline fun copying(block: ExecuteRequest.() -> Unit): ExecuteRequest = copy().apply(block)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Helper for [ExecuteRequest] creation.
|
|
||||||
* Allows to create it without opting in [kotlin.time.ExperimentalTime] for API < 1.6.
|
|
||||||
*/
|
|
||||||
fun executeRequest(executableAbsolutePath: String, args: MutableList<String> = mutableListOf()): ExecuteRequest =
|
|
||||||
ExecuteRequest(executableAbsolutePath, args)
|
|
||||||
|
|
||||||
data class ExecuteResponse(
|
data class ExecuteResponse(
|
||||||
/**
|
/**
|
||||||
* Process exit code if it exited by itself, or `null` if it was killed by a timeout.
|
* Process exit code if it exited by itself, or `null` if it was killed by a timeout.
|
||||||
|
|||||||
+61
@@ -0,0 +1,61 @@
|
|||||||
|
/*
|
||||||
|
* 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.native.executors
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.konan.target.AppleConfigurables
|
||||||
|
import org.jetbrains.kotlin.konan.target.Configurables
|
||||||
|
import org.jetbrains.kotlin.konan.target.HostManager
|
||||||
|
import org.jetbrains.kotlin.konan.target.KonanTarget
|
||||||
|
|
||||||
|
/**
|
||||||
|
* [Executor] that runs the process using Apple's Rosetta 2.
|
||||||
|
*
|
||||||
|
* @param configurables [Configurables] for target
|
||||||
|
*/
|
||||||
|
class RosettaExecutor(
|
||||||
|
private val configurables: AppleConfigurables,
|
||||||
|
) : Executor {
|
||||||
|
companion object {
|
||||||
|
/**
|
||||||
|
* Returns `true` if running via Rosetta 2 can be made available for given [configurables].
|
||||||
|
*
|
||||||
|
* This does not check that Rosetta 2 is installed.
|
||||||
|
*/
|
||||||
|
fun availableFor(configurables: AppleConfigurables): Boolean {
|
||||||
|
return HostManager.host is KonanTarget.MACOS_ARM64 && configurables.target is KonanTarget.MACOS_X64
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return `true` if Rosetta 2 is installed.
|
||||||
|
*
|
||||||
|
* @param [hostExecutor] executor in which to run the check. By default [HostExecutor].
|
||||||
|
*/
|
||||||
|
fun checkIsInstalled(hostExecutor: Executor = HostExecutor()): Boolean {
|
||||||
|
if (HostManager.host !is KonanTarget.MACOS_ARM64) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return hostExecutor.execute(ExecuteRequest("/usr/bin/arch").apply {
|
||||||
|
this.args.addAll(listOf("-x86_64", "/usr/bin/true"))
|
||||||
|
}).exitCode == 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private val hostExecutor: Executor = HostExecutor()
|
||||||
|
|
||||||
|
private val target by configurables::target
|
||||||
|
|
||||||
|
init {
|
||||||
|
require(availableFor(configurables)) {
|
||||||
|
"$target cannot be run under Rosetta 2 from host ${HostManager.host}"
|
||||||
|
}
|
||||||
|
require(checkIsInstalled(hostExecutor)) {
|
||||||
|
"Rosetta 2 is not installed on host ${HostManager.host}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// When Rosetta 2 is installed, all x64 binaries are automatically run through it.
|
||||||
|
override fun execute(request: ExecuteRequest): ExecuteResponse = hostExecutor.execute(request)
|
||||||
|
}
|
||||||
+1
-1
@@ -19,7 +19,7 @@ private fun defaultDeviceId(target: KonanTarget) = when (target.family) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun Executor.run(executableAbsolutePath: String, vararg args: String) = ByteArrayOutputStream().let {
|
private fun Executor.run(executableAbsolutePath: String, vararg args: String) = ByteArrayOutputStream().let {
|
||||||
this.execute(executeRequest(executableAbsolutePath).apply {
|
this.execute(ExecuteRequest(executableAbsolutePath).apply {
|
||||||
this.args.addAll(args)
|
this.args.addAll(args)
|
||||||
stdout = it
|
stdout = it
|
||||||
workingDirectory = File("").absoluteFile
|
workingDirectory = File("").absoluteFile
|
||||||
|
|||||||
+2
@@ -15,6 +15,7 @@ import org.jetbrains.kotlin.native.executors.Executor
|
|||||||
import org.jetbrains.kotlin.native.executors.EmulatorExecutor
|
import org.jetbrains.kotlin.native.executors.EmulatorExecutor
|
||||||
import org.jetbrains.kotlin.native.executors.XcodeSimulatorExecutor
|
import org.jetbrains.kotlin.native.executors.XcodeSimulatorExecutor
|
||||||
import org.jetbrains.kotlin.konan.target.*
|
import org.jetbrains.kotlin.konan.target.*
|
||||||
|
import org.jetbrains.kotlin.native.executors.RosettaExecutor
|
||||||
import org.jetbrains.kotlin.test.services.JUnit5Assertions.fail
|
import org.jetbrains.kotlin.test.services.JUnit5Assertions.fail
|
||||||
import java.util.concurrent.ConcurrentHashMap
|
import java.util.concurrent.ConcurrentHashMap
|
||||||
|
|
||||||
@@ -35,6 +36,7 @@ internal object TestRunners {
|
|||||||
configurables is ConfigurablesWithEmulator -> EmulatorExecutor(configurables)
|
configurables is ConfigurablesWithEmulator -> EmulatorExecutor(configurables)
|
||||||
configurables is AppleConfigurables && configurables.targetTriple.isSimulator ->
|
configurables is AppleConfigurables && configurables.targetTriple.isSimulator ->
|
||||||
XcodeSimulatorExecutor(configurables)
|
XcodeSimulatorExecutor(configurables)
|
||||||
|
configurables is AppleConfigurables && RosettaExecutor.availableFor(configurables) -> RosettaExecutor(configurables)
|
||||||
else -> runningOnUnsupportedTarget()
|
else -> runningOnUnsupportedTarget()
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user