[K/N][build] Parallelize runtime building
This commit is contained in:
committed by
TeamCityServer
parent
8e21e954ad
commit
cb0149cdca
@@ -17,17 +17,29 @@
|
|||||||
package org.jetbrains.kotlin
|
package org.jetbrains.kotlin
|
||||||
|
|
||||||
import org.gradle.api.Action
|
import org.gradle.api.Action
|
||||||
import groovy.lang.Closure
|
|
||||||
import org.gradle.api.GradleException
|
import org.gradle.api.GradleException
|
||||||
import org.gradle.api.Project
|
import org.gradle.api.Project
|
||||||
|
import org.gradle.api.internal.file.FileOperations
|
||||||
|
import org.gradle.api.internal.project.ProjectInternal
|
||||||
|
import org.gradle.api.model.ObjectFactory
|
||||||
|
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.*
|
import org.jetbrains.kotlin.konan.target.*
|
||||||
import org.jetbrains.kotlin.konan.file.*
|
import org.jetbrains.kotlin.konan.file.*
|
||||||
|
import org.jetbrains.kotlin.konan.file.File as KFile
|
||||||
|
import java.io.File
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
class ExecClang(private val project: Project) {
|
abstract class ExecClang @Inject constructor(
|
||||||
|
private val platformManager: PlatformManager,
|
||||||
|
private val llvmDir: File
|
||||||
|
) {
|
||||||
|
|
||||||
private val platformManager = project.project(":kotlin-native").findProperty("platformManager") as PlatformManager
|
@get:Inject
|
||||||
|
protected abstract val fileOperations: FileOperations
|
||||||
|
@get:Inject
|
||||||
|
protected abstract val execOperations: ExecOperations
|
||||||
|
|
||||||
private fun clangArgsForCppRuntime(target: KonanTarget): List<String> {
|
private fun clangArgsForCppRuntime(target: KonanTarget): List<String> {
|
||||||
return platformManager.platform(target).clang.clangArgsForKonanSources.asList()
|
return platformManager.platform(target).clang.clangArgsForKonanSources.asList()
|
||||||
@@ -42,8 +54,7 @@ class ExecClang(private val project: Project) {
|
|||||||
val executable = executableOrNull ?: "clang"
|
val executable = executableOrNull ?: "clang"
|
||||||
|
|
||||||
if (listOf("clang", "clang++").contains(executable)) {
|
if (listOf("clang", "clang++").contains(executable)) {
|
||||||
val llvmDir = project.findProperty("llvmDir")
|
return "${llvmDir.absolutePath}/bin/$executable"
|
||||||
return "${llvmDir}/bin/$executable"
|
|
||||||
} else {
|
} else {
|
||||||
throw GradleException("unsupported clang executable: $executable")
|
throw GradleException("unsupported clang executable: $executable")
|
||||||
}
|
}
|
||||||
@@ -71,10 +82,6 @@ class ExecClang(private val project: Project) {
|
|||||||
return this.execClang(emptyList(), action)
|
return this.execClang(emptyList(), action)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun execBareClang(closure: Closure<in ExecSpec>): ExecResult {
|
|
||||||
return this.execClang(emptyList(), closure)
|
|
||||||
}
|
|
||||||
|
|
||||||
// The konan ones invoke clang with konan provided sysroots.
|
// The konan ones invoke clang with konan provided sysroots.
|
||||||
// So they require a target or assume it to be the host.
|
// So they require a target or assume it to be the host.
|
||||||
// The target can be specified as KonanTarget or as a
|
// The target can be specified as KonanTarget or as a
|
||||||
@@ -88,14 +95,6 @@ class ExecClang(private val project: Project) {
|
|||||||
return this.execClang(clangArgsForCppRuntime(target), action)
|
return this.execClang(clangArgsForCppRuntime(target), action)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun execKonanClang(target: String?, closure: Closure<in ExecSpec>): ExecResult {
|
|
||||||
return this.execClang(clangArgsForCppRuntime(target), closure)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun execKonanClang(target: KonanTarget, closure: Closure<in ExecSpec>): ExecResult {
|
|
||||||
return this.execClang(clangArgsForCppRuntime(target), closure)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Execute Clang the way that produced object file is compatible with
|
* Execute Clang the way that produced object file is compatible with
|
||||||
* the one that produced by Kotlin/Native for given [target]. It means:
|
* the one that produced by Kotlin/Native for given [target]. It means:
|
||||||
@@ -104,7 +103,7 @@ class ExecClang(private val project: Project) {
|
|||||||
*/
|
*/
|
||||||
fun execClangForCompilerTests(target: KonanTarget, action: Action<in ExecSpec>): ExecResult {
|
fun execClangForCompilerTests(target: KonanTarget, action: Action<in ExecSpec>): ExecResult {
|
||||||
val defaultArgs = platformManager.platform(target).clang.clangArgs.toList()
|
val defaultArgs = platformManager.platform(target).clang.clangArgs.toList()
|
||||||
return project.exec {
|
return execOperations.exec {
|
||||||
action.execute(this)
|
action.execute(this)
|
||||||
executable = if (target.family.isAppleFamily) {
|
executable = if (target.family.isAppleFamily) {
|
||||||
resolveToolchainExecutable(target, executable)
|
resolveToolchainExecutable(target, executable)
|
||||||
@@ -115,36 +114,18 @@ class ExecClang(private val project: Project) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @see execClangForCompilerTests
|
|
||||||
*/
|
|
||||||
fun execClangForCompilerTests(target: KonanTarget, closure: Closure<in ExecSpec>): ExecResult =
|
|
||||||
execClangForCompilerTests(target) { project.configure(this, closure) }
|
|
||||||
|
|
||||||
// The toolchain ones execute clang from the toolchain.
|
// The toolchain ones execute clang from the toolchain.
|
||||||
|
|
||||||
fun execToolchainClang(target: String?, action: Action<in ExecSpec>): ExecResult {
|
fun execToolchainClang(target: String?, action: Action<in ExecSpec>): ExecResult {
|
||||||
return this.execToolchainClang(platformManager.targetManager(target).target, action)
|
return this.execToolchainClang(platformManager.targetManager(target).target, action)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun execToolchainClang(target: String?, closure: Closure<in ExecSpec>): ExecResult {
|
|
||||||
return this.execToolchainClang(platformManager.targetManager(target).target) { project.configure(this, closure) }
|
|
||||||
}
|
|
||||||
|
|
||||||
fun execToolchainClang(target: KonanTarget, action: Action<in ExecSpec>): ExecResult {
|
fun execToolchainClang(target: KonanTarget, action: Action<in ExecSpec>): ExecResult {
|
||||||
val extendedAction = Action<ExecSpec> {
|
val extendedAction = Action<ExecSpec> {
|
||||||
action.execute(this)
|
action.execute(this)
|
||||||
executable = resolveToolchainExecutable(target, executable)
|
executable = resolveToolchainExecutable(target, executable)
|
||||||
}
|
}
|
||||||
return project.exec(extendedAction)
|
return execOperations.exec(extendedAction)
|
||||||
}
|
|
||||||
|
|
||||||
fun execToolchainClang(target: KonanTarget, closure: Closure<in ExecSpec>): ExecResult {
|
|
||||||
return this.execToolchainClang(target) { project.configure(this, closure) }
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun execClang(defaultArgs: List<String>, closure: Closure<in ExecSpec>): ExecResult {
|
|
||||||
return this.execClang(defaultArgs) { project.configure(this, closure) }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun execClang(defaultArgs: List<String>, action: Action<in ExecSpec>): ExecResult {
|
private fun execClang(defaultArgs: List<String>, action: Action<in ExecSpec>): ExecResult {
|
||||||
@@ -153,10 +134,23 @@ class ExecClang(private val project: Project) {
|
|||||||
executable = resolveExecutable(executable)
|
executable = resolveExecutable(executable)
|
||||||
|
|
||||||
val hostPlatform = platformManager.hostPlatform
|
val hostPlatform = platformManager.hostPlatform
|
||||||
environment["PATH"] = project.files(hostPlatform.clang.clangPaths).asPath +
|
environment["PATH"] = fileOperations.configurableFiles(hostPlatform.clang.clangPaths).asPath +
|
||||||
java.io.File.pathSeparator + environment["PATH"]
|
File.pathSeparator + environment["PATH"]
|
||||||
args = args + defaultArgs
|
args = args + defaultArgs
|
||||||
}
|
}
|
||||||
return project.exec(extendedAction)
|
return execOperations.exec(extendedAction)
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
@JvmStatic
|
||||||
|
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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -410,7 +410,7 @@ fun Project.buildStaticLibrary(cSources: Collection<File>, output: File, objDir:
|
|||||||
val platform = platformManager.platform(testTarget)
|
val platform = platformManager.platform(testTarget)
|
||||||
|
|
||||||
objDir.mkdirs()
|
objDir.mkdirs()
|
||||||
ExecClang(project).execClangForCompilerTests(testTarget) {
|
ExecClang.create(project).execClangForCompilerTests(testTarget) {
|
||||||
args = listOf("-c", *cSources.map { it.absolutePath }.toTypedArray())
|
args = listOf("-c", *cSources.map { it.absolutePath }.toTypedArray())
|
||||||
workingDir(objDir)
|
workingDir(objDir)
|
||||||
}
|
}
|
||||||
|
|||||||
+63
-17
@@ -10,16 +10,59 @@ import org.gradle.api.file.FileCollection
|
|||||||
import org.gradle.api.tasks.*
|
import org.gradle.api.tasks.*
|
||||||
import org.gradle.kotlin.dsl.getByType
|
import org.gradle.kotlin.dsl.getByType
|
||||||
import org.jetbrains.kotlin.ExecClang
|
import org.jetbrains.kotlin.ExecClang
|
||||||
import org.jetbrains.kotlin.konan.target.Family
|
|
||||||
import org.jetbrains.kotlin.konan.target.HostManager
|
|
||||||
import org.jetbrains.kotlin.konan.target.KonanTarget
|
|
||||||
import org.jetbrains.kotlin.konan.target.SanitizerKind
|
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import kotlinBuildProperties
|
import kotlinBuildProperties
|
||||||
import isNativeRuntimeDebugInfoEnabled
|
import isNativeRuntimeDebugInfoEnabled
|
||||||
|
import org.gradle.api.Project
|
||||||
|
import org.gradle.api.model.ObjectFactory
|
||||||
|
import org.gradle.process.ExecOperations
|
||||||
|
import org.gradle.workers.WorkAction
|
||||||
|
import org.gradle.workers.WorkParameters
|
||||||
|
import org.gradle.workers.WorkerExecutor
|
||||||
|
import org.jetbrains.kotlin.konan.target.*
|
||||||
|
|
||||||
open class CompileToBitcode @Inject constructor(
|
interface CompileToBitcodeParameters : WorkParameters {
|
||||||
|
var objDir: File
|
||||||
|
var target: String
|
||||||
|
var compilerExecutable: String
|
||||||
|
var compilerArgs: List<String>
|
||||||
|
var llvmLinkArgs: List<String>
|
||||||
|
|
||||||
|
var konanHome: File
|
||||||
|
var llvmDir: File
|
||||||
|
var experimentalDistribution: Boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class CompileToBitcodeJob : WorkAction<CompileToBitcodeParameters> {
|
||||||
|
@get:Inject
|
||||||
|
abstract val objects: ObjectFactory
|
||||||
|
|
||||||
|
@get:Inject
|
||||||
|
abstract val execOperations: ExecOperations
|
||||||
|
|
||||||
|
override fun execute() {
|
||||||
|
with(parameters) {
|
||||||
|
objDir.mkdirs()
|
||||||
|
|
||||||
|
val platformManager = PlatformManager(buildDistribution(konanHome.absolutePath), experimentalDistribution)
|
||||||
|
val execClang = ExecClang.create(objects, platformManager, llvmDir)
|
||||||
|
|
||||||
|
execClang.execKonanClang(target) {
|
||||||
|
workingDir = objDir
|
||||||
|
executable = compilerExecutable
|
||||||
|
args = compilerArgs
|
||||||
|
}
|
||||||
|
|
||||||
|
execOperations.exec {
|
||||||
|
executable = "${llvmDir.absolutePath}/bin/llvm-link"
|
||||||
|
args = llvmLinkArgs
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class CompileToBitcode @Inject constructor(
|
||||||
@Internal val srcRoot: File,
|
@Internal val srcRoot: File,
|
||||||
@Input val folderName: String,
|
@Input val folderName: String,
|
||||||
@Input val target: String,
|
@Input val target: String,
|
||||||
@@ -164,24 +207,27 @@ open class CompileToBitcode @Inject constructor(
|
|||||||
val outFile: File
|
val outFile: File
|
||||||
get() = File(targetDir, "${folderName}.bc")
|
get() = File(targetDir, "${folderName}.bc")
|
||||||
|
|
||||||
|
@get:Inject
|
||||||
|
abstract val workerExecutor: WorkerExecutor
|
||||||
|
|
||||||
@TaskAction
|
@TaskAction
|
||||||
fun compile() {
|
fun compile() {
|
||||||
objDir.mkdirs()
|
val workQueue = workerExecutor.noIsolation()
|
||||||
val plugin = project.extensions.getByType<ExecClang>()
|
|
||||||
|
|
||||||
plugin.execKonanClang(target) {
|
val parameters = { it: CompileToBitcodeParameters ->
|
||||||
workingDir = objDir
|
it.objDir = objDir
|
||||||
executable = executable
|
it.target = target
|
||||||
args = compilerFlags + inputFiles.map { it.absolutePath }
|
it.compilerExecutable = executable
|
||||||
}
|
it.compilerArgs = compilerFlags + inputFiles.map { it.absolutePath }
|
||||||
|
it.llvmLinkArgs = listOf("-o", outFile.absolutePath) + linkerArgs +
|
||||||
project.exec {
|
|
||||||
val llvmDir = project.findProperty("llvmDir")
|
|
||||||
executable = "$llvmDir/bin/llvm-link"
|
|
||||||
args = listOf("-o", outFile.absolutePath) + linkerArgs +
|
|
||||||
inputFiles.map {
|
inputFiles.map {
|
||||||
bitcodeFileForInputFile(it).absolutePath
|
bitcodeFileForInputFile(it).absolutePath
|
||||||
}
|
}
|
||||||
|
|
||||||
|
it.konanHome = project.project(":kotlin-native").projectDir
|
||||||
|
it.llvmDir = project.file(project.findProperty("llvmDir")!!)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
workQueue.submit(CompileToBitcodeJob::class.java, parameters)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -133,9 +133,8 @@ void setupHostAndTarget() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void setupClang(Project project) {
|
void setupClang(Project project) {
|
||||||
|
|
||||||
project.extensions.platformManager = project.project(":kotlin-native").ext.platformManager
|
project.extensions.platformManager = project.project(":kotlin-native").ext.platformManager
|
||||||
project.extensions.execClang = new org.jetbrains.kotlin.ExecClang(project)
|
project.extensions.execClang = org.jetbrains.kotlin.ExecClang.create(project)
|
||||||
}
|
}
|
||||||
|
|
||||||
void loadLocalProperties() {
|
void loadLocalProperties() {
|
||||||
|
|||||||
Reference in New Issue
Block a user