[K/N] Make PlatformManager serializable

Merge-request: KT-MR-6358
Merged-by: Alexander Shabalin <Alexander.Shabalin@jetbrains.com>
This commit is contained in:
Alexander Shabalin
2022-05-30 15:52:08 +00:00
committed by Space
parent 314d9b9477
commit ed881f3f31
6 changed files with 80 additions and 44 deletions
@@ -33,8 +33,7 @@ import javax.inject.Inject
abstract class ExecClang @Inject constructor(
private val platformManager: PlatformManager,
private val llvmDir: File
) {
) {
@get:Inject
protected abstract val fileOperations: FileOperations
@@ -54,7 +53,7 @@ abstract class ExecClang @Inject constructor(
val executable = executableOrNull ?: "clang"
if (listOf("clang", "clang++").contains(executable)) {
return "${llvmDir.absolutePath}/bin/$executable"
return "${platformManager.hostPlatform.absoluteLlvmHome}/bin/$executable"
} else {
throw GradleException("unsupported clang executable: $executable")
}
@@ -146,11 +145,10 @@ abstract class ExecClang @Inject constructor(
fun create(project: Project): ExecClang = create(
project.objects,
project.project(":kotlin-native").findProperty("platformManager") as PlatformManager,
project.file(project.findProperty("llvmDir")!!)
)
@JvmStatic
fun create(objects: ObjectFactory, platformManager: PlatformManager, llvmDir: File) =
objects.newInstance(ExecClang::class.java, platformManager, llvmDir)
fun create(objects: ObjectFactory, platformManager: PlatformManager) =
objects.newInstance(ExecClang::class.java, platformManager)
}
}
@@ -8,8 +8,10 @@ package org.jetbrains.kotlin
import groovy.lang.Closure
import org.gradle.api.Action
import org.gradle.api.Project
import org.gradle.process.ExecOperations
import org.gradle.process.ExecResult
import org.gradle.process.ExecSpec
import org.jetbrains.kotlin.konan.target.PlatformManager
import org.jetbrains.kotlin.konan.util.DependencyProcessor
fun execLlvmUtility(project: Project, utility: String, action: Action<in ExecSpec>): ExecResult {
@@ -23,3 +25,11 @@ fun execLlvmUtility(project: Project, utility: String, action: Action<in ExecSpe
fun execLlvmUtility(project: Project, utility: String, closure: Closure<in ExecSpec>): ExecResult {
return execLlvmUtility(project, utility) { project.configure(this, closure) }
}
fun ExecOperations.execLlvmUtility(platformManager: PlatformManager, utility: String, action: Action<in ExecSpec>): ExecResult {
val llvmBinDirectory = "${platformManager.hostPlatform.absoluteLlvmHome}/bin"
return exec {
action.execute(this)
executable = "$llvmBinDirectory/$utility"
}
}
@@ -15,11 +15,14 @@ import javax.inject.Inject
import kotlinBuildProperties
import org.gradle.api.Project
import org.gradle.api.model.ObjectFactory
import org.gradle.api.provider.Property
import org.gradle.process.ExecOperations
import org.gradle.workers.WorkAction
import org.gradle.workers.WorkParameters
import org.gradle.workers.WorkerExecutor
import org.jetbrains.kotlin.execLlvmUtility
import org.jetbrains.kotlin.konan.target.*
import org.jetbrains.kotlin.platformManager
interface CompileToBitcodeParameters : WorkParameters {
var objDir: File
@@ -27,10 +30,7 @@ interface CompileToBitcodeParameters : WorkParameters {
var compilerExecutable: String
var compilerArgs: List<String>
var llvmLinkArgs: List<String>
var konanHome: File
var llvmDir: File
var experimentalDistribution: Boolean
val platformManager: Property<PlatformManager>
}
abstract class CompileToBitcodeJob : WorkAction<CompileToBitcodeParameters> {
@@ -44,8 +44,7 @@ abstract class CompileToBitcodeJob : WorkAction<CompileToBitcodeParameters> {
with(parameters) {
objDir.mkdirs()
val platformManager = PlatformManager(buildDistribution(konanHome.absolutePath), experimentalDistribution)
val execClang = ExecClang.create(objects, platformManager, llvmDir)
val execClang = ExecClang.create(objects, platformManager.get())
execClang.execKonanClang(target) {
workingDir = objDir
@@ -53,8 +52,7 @@ abstract class CompileToBitcodeJob : WorkAction<CompileToBitcodeParameters> {
args = compilerArgs
}
execOperations.exec {
executable = "${llvmDir.absolutePath}/bin/llvm-link"
execOperations.execLlvmUtility(platformManager.get(), "llvm-link") {
args = llvmLinkArgs
}
}
@@ -234,9 +232,7 @@ abstract class CompileToBitcode @Inject constructor(
inputFiles.map {
bitcodeFileForInputFile(it).absolutePath
}
it.konanHome = project.project(":kotlin-native").projectDir
it.llvmDir = project.file(project.findProperty("llvmDir")!!)
it.platformManager.set(project.platformManager)
}
workQueue.submit(CompileToBitcodeJob::class.java, parameters)
@@ -10,13 +10,16 @@ import java.io.File
import javax.inject.Inject
import org.gradle.api.*
import org.gradle.api.file.ConfigurableFileCollection
import org.gradle.api.logging.Logging
import org.gradle.api.tasks.*
import org.gradle.api.model.ObjectFactory
import org.gradle.api.provider.Property
import org.gradle.process.ExecOperations
import org.gradle.workers.WorkAction
import org.gradle.workers.WorkParameters
import org.gradle.workers.WorkerExecutor
import org.jetbrains.kotlin.ExecClang
import org.jetbrains.kotlin.execLlvmUtility
import org.jetbrains.kotlin.konan.target.*
import java.io.OutputStream
@@ -28,11 +31,7 @@ interface CompileNativeTestParameters : WorkParameters {
var targetName: String
var compilerArgs: List<String>
var linkCommands: List<List<String>>
var konanHome: File
var llvmDir: File
var experimentalDistribution: Boolean
var isInfoEnabled: Boolean
val platformManager: Property<PlatformManager>
}
abstract class CompileNativeTestJob : WorkAction<CompileNativeTestParameters> {
@@ -55,13 +54,11 @@ abstract class CompileNativeTestJob : WorkAction<CompileNativeTestParameters> {
// errors at the link stage. So we have to run llvm-link twice: the first one links all modules
// except the one containing the entry point to a single *.bc without internalization. The second
// run internalizes this big module and links it with a module containing the entry point.
execOperations.exec {
executable = "$llvmDir/bin/llvm-link"
execOperations.execLlvmUtility(platformManager.get(), "llvm-link") {
args = listOf("-o", tmpOutput.absolutePath) + inputFiles.map { it.absolutePath }
}
execOperations.exec {
executable = "$llvmDir/bin/llvm-link"
execOperations.execLlvmUtility(platformManager.get(), "llvm-link") {
args = listOf(
"-o", llvmLinkOutputFile.absolutePath,
mainFile.absolutePath,
@@ -74,11 +71,10 @@ abstract class CompileNativeTestJob : WorkAction<CompileNativeTestParameters> {
private fun compile() {
with(parameters) {
val platformManager = PlatformManager(buildDistribution(konanHome.absolutePath), experimentalDistribution)
val execClang = ExecClang.create(objects, platformManager, llvmDir)
val target = platformManager.targetByName(targetName)
val execClang = ExecClang.create(objects, platformManager.get())
val target = platformManager.get().targetByName(targetName)
val clangFlags = buildClangFlags(platformManager.platform(target).configurables)
val clangFlags = buildClangFlags(platformManager.get().platform(target).configurables)
if (target.family.isAppleFamily) {
execClang.execToolchainClang(target) {
@@ -95,11 +91,13 @@ abstract class CompileNativeTestJob : WorkAction<CompileNativeTestParameters> {
}
private fun link() {
val logging = Logging.getLogger(CompileNativeTestJob::class.java)
with(parameters) {
for (command in linkCommands) {
execOperations.exec {
commandLine(command)
if (!isInfoEnabled && command[0].endsWith("dsymutil")) {
if (!logging.isInfoEnabled && command[0].endsWith("dsymutil")) {
// Suppress dsymutl's warnings.
// See: https://bugs.swift.org/browse/SR-11539.
val nullOutputStream = object: OutputStream() {
@@ -197,10 +195,7 @@ abstract class CompileNativeTest @Inject constructor(
it.targetName = target.name
it.compilerArgs = clangArgs + sanitizerFlags
it.linkCommands = linkCommands
it.konanHome = project.project(":kotlin-native").projectDir
it.llvmDir = project.file(project.findProperty("llvmDir")!!)
it.isInfoEnabled = logger.isInfoEnabled
it.platformManager.set(platformManager)
}
workQueue.submit(CompileNativeTestJob::class.java, parameters)
@@ -34,10 +34,13 @@ class Platform(val configurables: Configurables)
}
}
class PlatformManager(private val distribution: Distribution, experimental: Boolean = false) :
HostManager(distribution, experimental) {
class PlatformManager private constructor(private val serialized: Serialized) :
HostManager(serialized.distribution, serialized.experimental), java.io.Serializable {
constructor(konanHome: String, experimental: Boolean = false): this(Distribution(konanHome), experimental)
constructor(konanHome: String, experimental: Boolean = false) : this(Distribution(konanHome), experimental)
constructor(distribution: Distribution, experimental: Boolean = false) : this(Serialized(distribution, experimental))
private val distribution by serialized::distribution
private val loaders = enabled.map {
it to loadConfigurables(it, distribution.properties, DependencyProcessor.defaultDependenciesRoot.absolutePath)
@@ -51,5 +54,18 @@ class PlatformManager(private val distribution: Distribution, experimental: Bool
val hostPlatform = platforms.getValue(host)
fun loader(target: KonanTarget) = loaders.getValue(target)
private fun writeReplace(): Any = serialized
private data class Serialized(
val distribution: Distribution,
val experimental: Boolean
) : java.io.Serializable {
companion object {
private const val serialVersionUID: Long = 0L
}
private fun readResolve(): Any = PlatformManager(this)
}
}
@@ -11,12 +11,18 @@ import org.jetbrains.kotlin.konan.properties.keepOnlyDefaultProfiles
import org.jetbrains.kotlin.konan.properties.loadProperties
import org.jetbrains.kotlin.konan.util.DependencyDirectories
class Distribution(
val konanHome: String,
private val onlyDefaultProfiles: Boolean = false,
private val runtimeFileOverride: String? = null,
private val propertyOverrides: Map<String, String>? = null
) {
class Distribution private constructor(private val serialized: Serialized) : java.io.Serializable {
constructor(
konanHome: String,
onlyDefaultProfiles: Boolean = false,
runtimeFileOverride: String? = null,
propertyOverrides: Map<String, String>? = null
) : this(Serialized(konanHome, onlyDefaultProfiles, runtimeFileOverride, propertyOverrides))
val konanHome by serialized::konanHome
private val onlyDefaultProfiles by serialized::onlyDefaultProfiles
private val runtimeFileOverride by serialized::runtimeFileOverride
private val propertyOverrides by serialized::propertyOverrides
val localKonanDir = DependencyDirectories.localKonanDir
@@ -110,6 +116,21 @@ class Distribution(
fun getCompilerVersion(propertyVersion: String?, konanHome: String): String? =
propertyVersion ?: getBundleVersion(konanHome)
}
private fun writeReplace(): Any = serialized
private data class Serialized(
val konanHome: String,
val onlyDefaultProfiles: Boolean,
val runtimeFileOverride: String?,
val propertyOverrides: Map<String, String>?,
) : java.io.Serializable {
companion object {
private const val serialVersionUID: Long = 0L
}
private fun readResolve(): Any = Distribution(this)
}
}
// TODO: Move into K/N?