[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( abstract class ExecClang @Inject constructor(
private val platformManager: PlatformManager, private val platformManager: PlatformManager,
private val llvmDir: File ) {
) {
@get:Inject @get:Inject
protected abstract val fileOperations: FileOperations protected abstract val fileOperations: FileOperations
@@ -54,7 +53,7 @@ abstract class ExecClang @Inject constructor(
val executable = executableOrNull ?: "clang" val executable = executableOrNull ?: "clang"
if (listOf("clang", "clang++").contains(executable)) { if (listOf("clang", "clang++").contains(executable)) {
return "${llvmDir.absolutePath}/bin/$executable" return "${platformManager.hostPlatform.absoluteLlvmHome}/bin/$executable"
} else { } else {
throw GradleException("unsupported clang executable: $executable") throw GradleException("unsupported clang executable: $executable")
} }
@@ -146,11 +145,10 @@ abstract class ExecClang @Inject constructor(
fun create(project: Project): ExecClang = create( fun create(project: Project): ExecClang = create(
project.objects, project.objects,
project.project(":kotlin-native").findProperty("platformManager") as PlatformManager, project.project(":kotlin-native").findProperty("platformManager") as PlatformManager,
project.file(project.findProperty("llvmDir")!!)
) )
@JvmStatic @JvmStatic
fun create(objects: ObjectFactory, platformManager: PlatformManager, llvmDir: File) = fun create(objects: ObjectFactory, platformManager: PlatformManager) =
objects.newInstance(ExecClang::class.java, platformManager, llvmDir) objects.newInstance(ExecClang::class.java, platformManager)
} }
} }
@@ -8,8 +8,10 @@ package org.jetbrains.kotlin
import groovy.lang.Closure import groovy.lang.Closure
import org.gradle.api.Action import org.gradle.api.Action
import org.gradle.api.Project import org.gradle.api.Project
import org.gradle.process.ExecOperations
import org.gradle.process.ExecResult import org.gradle.process.ExecResult
import org.gradle.process.ExecSpec import org.gradle.process.ExecSpec
import org.jetbrains.kotlin.konan.target.PlatformManager
import org.jetbrains.kotlin.konan.util.DependencyProcessor import org.jetbrains.kotlin.konan.util.DependencyProcessor
fun execLlvmUtility(project: Project, utility: String, action: Action<in ExecSpec>): ExecResult { 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 { fun execLlvmUtility(project: Project, utility: String, closure: Closure<in ExecSpec>): ExecResult {
return execLlvmUtility(project, utility) { project.configure(this, closure) } 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 kotlinBuildProperties
import org.gradle.api.Project import org.gradle.api.Project
import org.gradle.api.model.ObjectFactory import org.gradle.api.model.ObjectFactory
import org.gradle.api.provider.Property
import org.gradle.process.ExecOperations import org.gradle.process.ExecOperations
import org.gradle.workers.WorkAction import org.gradle.workers.WorkAction
import org.gradle.workers.WorkParameters import org.gradle.workers.WorkParameters
import org.gradle.workers.WorkerExecutor import org.gradle.workers.WorkerExecutor
import org.jetbrains.kotlin.execLlvmUtility
import org.jetbrains.kotlin.konan.target.* import org.jetbrains.kotlin.konan.target.*
import org.jetbrains.kotlin.platformManager
interface CompileToBitcodeParameters : WorkParameters { interface CompileToBitcodeParameters : WorkParameters {
var objDir: File var objDir: File
@@ -27,10 +30,7 @@ interface CompileToBitcodeParameters : WorkParameters {
var compilerExecutable: String var compilerExecutable: String
var compilerArgs: List<String> var compilerArgs: List<String>
var llvmLinkArgs: List<String> var llvmLinkArgs: List<String>
val platformManager: Property<PlatformManager>
var konanHome: File
var llvmDir: File
var experimentalDistribution: Boolean
} }
abstract class CompileToBitcodeJob : WorkAction<CompileToBitcodeParameters> { abstract class CompileToBitcodeJob : WorkAction<CompileToBitcodeParameters> {
@@ -44,8 +44,7 @@ abstract class CompileToBitcodeJob : WorkAction<CompileToBitcodeParameters> {
with(parameters) { with(parameters) {
objDir.mkdirs() objDir.mkdirs()
val platformManager = PlatformManager(buildDistribution(konanHome.absolutePath), experimentalDistribution) val execClang = ExecClang.create(objects, platformManager.get())
val execClang = ExecClang.create(objects, platformManager, llvmDir)
execClang.execKonanClang(target) { execClang.execKonanClang(target) {
workingDir = objDir workingDir = objDir
@@ -53,8 +52,7 @@ abstract class CompileToBitcodeJob : WorkAction<CompileToBitcodeParameters> {
args = compilerArgs args = compilerArgs
} }
execOperations.exec { execOperations.execLlvmUtility(platformManager.get(), "llvm-link") {
executable = "${llvmDir.absolutePath}/bin/llvm-link"
args = llvmLinkArgs args = llvmLinkArgs
} }
} }
@@ -234,9 +232,7 @@ abstract class CompileToBitcode @Inject constructor(
inputFiles.map { inputFiles.map {
bitcodeFileForInputFile(it).absolutePath bitcodeFileForInputFile(it).absolutePath
} }
it.platformManager.set(project.platformManager)
it.konanHome = project.project(":kotlin-native").projectDir
it.llvmDir = project.file(project.findProperty("llvmDir")!!)
} }
workQueue.submit(CompileToBitcodeJob::class.java, parameters) workQueue.submit(CompileToBitcodeJob::class.java, parameters)
@@ -10,13 +10,16 @@ import java.io.File
import javax.inject.Inject import javax.inject.Inject
import org.gradle.api.* import org.gradle.api.*
import org.gradle.api.file.ConfigurableFileCollection import org.gradle.api.file.ConfigurableFileCollection
import org.gradle.api.logging.Logging
import org.gradle.api.tasks.* import org.gradle.api.tasks.*
import org.gradle.api.model.ObjectFactory import org.gradle.api.model.ObjectFactory
import org.gradle.api.provider.Property
import org.gradle.process.ExecOperations import org.gradle.process.ExecOperations
import org.gradle.workers.WorkAction import org.gradle.workers.WorkAction
import org.gradle.workers.WorkParameters import org.gradle.workers.WorkParameters
import org.gradle.workers.WorkerExecutor import org.gradle.workers.WorkerExecutor
import org.jetbrains.kotlin.ExecClang import org.jetbrains.kotlin.ExecClang
import org.jetbrains.kotlin.execLlvmUtility
import org.jetbrains.kotlin.konan.target.* import org.jetbrains.kotlin.konan.target.*
import java.io.OutputStream import java.io.OutputStream
@@ -28,11 +31,7 @@ interface CompileNativeTestParameters : WorkParameters {
var targetName: String var targetName: String
var compilerArgs: List<String> var compilerArgs: List<String>
var linkCommands: List<List<String>> var linkCommands: List<List<String>>
val platformManager: Property<PlatformManager>
var konanHome: File
var llvmDir: File
var experimentalDistribution: Boolean
var isInfoEnabled: Boolean
} }
abstract class CompileNativeTestJob : WorkAction<CompileNativeTestParameters> { 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 // 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 // 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. // run internalizes this big module and links it with a module containing the entry point.
execOperations.exec { execOperations.execLlvmUtility(platformManager.get(), "llvm-link") {
executable = "$llvmDir/bin/llvm-link"
args = listOf("-o", tmpOutput.absolutePath) + inputFiles.map { it.absolutePath } args = listOf("-o", tmpOutput.absolutePath) + inputFiles.map { it.absolutePath }
} }
execOperations.exec { execOperations.execLlvmUtility(platformManager.get(), "llvm-link") {
executable = "$llvmDir/bin/llvm-link"
args = listOf( args = listOf(
"-o", llvmLinkOutputFile.absolutePath, "-o", llvmLinkOutputFile.absolutePath,
mainFile.absolutePath, mainFile.absolutePath,
@@ -74,11 +71,10 @@ abstract class CompileNativeTestJob : WorkAction<CompileNativeTestParameters> {
private fun compile() { private fun compile() {
with(parameters) { with(parameters) {
val platformManager = PlatformManager(buildDistribution(konanHome.absolutePath), experimentalDistribution) val execClang = ExecClang.create(objects, platformManager.get())
val execClang = ExecClang.create(objects, platformManager, llvmDir) val target = platformManager.get().targetByName(targetName)
val target = platformManager.targetByName(targetName)
val clangFlags = buildClangFlags(platformManager.platform(target).configurables) val clangFlags = buildClangFlags(platformManager.get().platform(target).configurables)
if (target.family.isAppleFamily) { if (target.family.isAppleFamily) {
execClang.execToolchainClang(target) { execClang.execToolchainClang(target) {
@@ -95,11 +91,13 @@ abstract class CompileNativeTestJob : WorkAction<CompileNativeTestParameters> {
} }
private fun link() { private fun link() {
val logging = Logging.getLogger(CompileNativeTestJob::class.java)
with(parameters) { with(parameters) {
for (command in linkCommands) { for (command in linkCommands) {
execOperations.exec { execOperations.exec {
commandLine(command) commandLine(command)
if (!isInfoEnabled && command[0].endsWith("dsymutil")) { if (!logging.isInfoEnabled && command[0].endsWith("dsymutil")) {
// Suppress dsymutl's warnings. // Suppress dsymutl's warnings.
// See: https://bugs.swift.org/browse/SR-11539. // See: https://bugs.swift.org/browse/SR-11539.
val nullOutputStream = object: OutputStream() { val nullOutputStream = object: OutputStream() {
@@ -197,10 +195,7 @@ abstract class CompileNativeTest @Inject constructor(
it.targetName = target.name it.targetName = target.name
it.compilerArgs = clangArgs + sanitizerFlags it.compilerArgs = clangArgs + sanitizerFlags
it.linkCommands = linkCommands it.linkCommands = linkCommands
it.platformManager.set(platformManager)
it.konanHome = project.project(":kotlin-native").projectDir
it.llvmDir = project.file(project.findProperty("llvmDir")!!)
it.isInfoEnabled = logger.isInfoEnabled
} }
workQueue.submit(CompileNativeTestJob::class.java, parameters) workQueue.submit(CompileNativeTestJob::class.java, parameters)
@@ -34,10 +34,13 @@ class Platform(val configurables: Configurables)
} }
} }
class PlatformManager(private val distribution: Distribution, experimental: Boolean = false) : class PlatformManager private constructor(private val serialized: Serialized) :
HostManager(distribution, experimental) { 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 { private val loaders = enabled.map {
it to loadConfigurables(it, distribution.properties, DependencyProcessor.defaultDependenciesRoot.absolutePath) 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) val hostPlatform = platforms.getValue(host)
fun loader(target: KonanTarget) = loaders.getValue(target) 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.properties.loadProperties
import org.jetbrains.kotlin.konan.util.DependencyDirectories import org.jetbrains.kotlin.konan.util.DependencyDirectories
class Distribution( class Distribution private constructor(private val serialized: Serialized) : java.io.Serializable {
val konanHome: String, constructor(
private val onlyDefaultProfiles: Boolean = false, konanHome: String,
private val runtimeFileOverride: String? = null, onlyDefaultProfiles: Boolean = false,
private val propertyOverrides: Map<String, String>? = null 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 val localKonanDir = DependencyDirectories.localKonanDir
@@ -110,6 +116,21 @@ class Distribution(
fun getCompilerVersion(propertyVersion: String?, konanHome: String): String? = fun getCompilerVersion(propertyVersion: String?, konanHome: String): String? =
propertyVersion ?: getBundleVersion(konanHome) 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? // TODO: Move into K/N?