[K/N] Use Gradle configurations for CompileToBitcode modules ^KT-53776

This commit is contained in:
Alexander Shabalin
2022-12-07 13:56:42 +01:00
committed by Space Team
parent 584280bdd4
commit f2835f3534
5 changed files with 163 additions and 40 deletions
+33 -4
View File
@@ -1,7 +1,8 @@
import org.jetbrains.kotlin.CopyCommonSources
import org.jetbrains.kotlin.konan.target.HostManager
import org.jetbrains.kotlin.konan.target.*
import org.jetbrains.kotlin.*
import org.jetbrains.gradle.plugins.tools.*
import org.jetbrains.kotlin.bitcode.*
/*
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the LICENSE file.
@@ -40,6 +41,32 @@ compileCli_bcKotlin {
kotlinOptions.freeCompilerArgs += ['-Xskip-prerelease-check']
}
configurations {
commonFilesBitcode {
canBeConsumed = false
canBeResolved = true
attributes {
attribute(Usage.USAGE_ATTRIBUTE, objects.named(Usage, CompileToBitcodeExtension.USAGE))
attribute(TargetWithSanitizer.TARGET_ATTRIBUTE, TargetWithSanitizer.host)
attribute(CompileToBitcodeExtension.MODULE_ATTRIBUTE, "files")
}
}
commonEnvBitcode {
canBeConsumed = false
canBeResolved = true
attributes {
attribute(Usage.USAGE_ATTRIBUTE, objects.named(Usage, CompileToBitcodeExtension.USAGE))
attribute(TargetWithSanitizer.TARGET_ATTRIBUTE, TargetWithSanitizer.host)
attribute(CompileToBitcodeExtension.MODULE_ATTRIBUTE, "env")
}
}
}
dependencies {
commonFilesBitcode project(":kotlin-native:common")
commonEnvBitcode project(":kotlin-native:common")
}
kotlinNativeInterop {
llvm {
@@ -63,8 +90,9 @@ kotlinNativeInterop {
files {
linker 'clang++'
linkOutputs ":kotlin-native:common:${hostName}Files"
link configurations.commonFilesBitcode
// TODO: These should come from some sort of commonFilesApi configuration
headers fileTree('../common/src/files/headers') {
include '**/*.h'
include '**/*.hpp'
@@ -76,8 +104,9 @@ kotlinNativeInterop {
env {
linker 'clang++'
linkOutputs ":kotlin-native:common:${hostName}Env"
link configurations.commonEnvBitcode
// TODO: These should come from some sort of commonEnvApi configuration
headers fileTree('../common/src/env/headers') {
include '**/*.h'
include '**/*.hpp'
@@ -155,7 +184,7 @@ jar {
sourceSets.envInteropStubs.output,
sourceSets.llvmInteropStubs.output
dependsOn ':kotlin-native:runtime:hostRuntime', 'external_jars'
dependsOn 'external_jars'
}
def externalJars = ['compiler', 'stdlib', 'reflect', 'script_runtime']
@@ -9,6 +9,8 @@ import kotlinBuildProperties
import org.gradle.api.Action
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.attributes.Attribute
import org.gradle.api.attributes.Usage
import org.gradle.api.provider.ListProperty
import org.gradle.api.provider.Property
import org.gradle.api.services.BuildService
@@ -51,21 +53,6 @@ private val SanitizerKind?.description
private abstract class RunGTestSemaphore : BuildService<BuildServiceParameters.None>
private abstract class CompileTestsSemaphore : BuildService<BuildServiceParameters.None>
/**
* A plugin creating extensions to compile
*/
open class CompileToBitcodePlugin : Plugin<Project> {
override fun apply(target: Project) {
target.apply<CompilationDatabasePlugin>()
target.apply<GitClangFormatPlugin>()
target.extensions.create<CompileToBitcodeExtension>(EXTENSION_NAME, target)
}
companion object {
const val EXTENSION_NAME = "bitcode"
}
}
open class CompileToBitcodeExtension @Inject constructor(val project: Project) : TargetDomainObjectContainer<CompileToBitcodeExtension.Target>(project) {
init {
this.factory = { target ->
@@ -73,6 +60,15 @@ open class CompileToBitcodeExtension @Inject constructor(val project: Project) :
}
}
val compileBitcodeMainElements by project.configurations.creating {
description = "LLVM bitcode of all defined modules (main sources)"
isCanBeConsumed = true
isCanBeResolved = false
attributes {
attribute(Usage.USAGE_ATTRIBUTE, project.objects.named(USAGE))
}
}
// TODO: These should be set by the plugin users.
private val DEFAULT_CPP_FLAGS = listOfNotNull(
"-gdwarf-2".takeIf { project.kotlinBuildProperties.getBoolean("kotlin.native.isNativeRuntimeDebugInfoEnabled", false) },
@@ -89,16 +85,6 @@ open class CompileToBitcodeExtension @Inject constructor(val project: Project) :
provider { (rootProject.project(":kotlin-native").property("targetList") as? List<*>)?.filterIsInstance<String>() ?: emptyList() } // TODO: Can we make it better?
}
private val allMainModulesTasks by lazy {
val name = project.name.capitalized
targetList.get().associateBy(keySelector = { it }, valueTransform = {
project.tasks.register("${it}$name") {
description = "Build all main modules of $name for $it"
group = BUILD_TASK_GROUP
}
})
}
private val allTestsTasks by lazy {
val name = project.name.capitalized
targetList.get().associateBy(keySelector = { it }, valueTransform = {
@@ -147,6 +133,12 @@ open class CompileToBitcodeExtension @Inject constructor(val project: Project) :
maxParallelUsages.set(5)
}
private val compileBitcodeMainElements = owner.compileBitcodeMainElements.outgoing.variants.create("$_target") {
attributes {
attribute(TargetWithSanitizer.TARGET_ATTRIBUTE, _target)
}
}
private fun addToCompdb(compileTask: CompileToBitcode) {
compilationDatabase.target(_target) {
entry {
@@ -169,9 +161,9 @@ open class CompileToBitcodeExtension @Inject constructor(val project: Project) :
fun module(name: String, srcRoot: File = project.file("src/$name"), outputGroup: String = "main", configurationBlock: CompileToBitcode.() -> Unit = {}) {
val targetName = target.name
val allMainModulesTask = owner.allMainModulesTasks[targetName]!!
val taskName = fullTaskName(name, targetName, sanitizer)
val task = project.tasks.create(taskName, CompileToBitcode::class.java, _target).apply {
val task = project.tasks.register<CompileToBitcode>(taskName, _target)
task.configure {
this.moduleName.set(name)
this.outputFile.convention(moduleName.flatMap { project.layout.buildDirectory.file("bitcode/$outputGroup/$target${sanitizer.dirSuffix}/$it.bc") })
this.outputDirectory.convention(moduleName.flatMap { project.layout.buildDirectory.dir("bitcode/$outputGroup/$target${sanitizer.dirSuffix}/$it") })
@@ -190,10 +182,30 @@ open class CompileToBitcodeExtension @Inject constructor(val project: Project) :
dependsOn(":kotlin-native:dependencies:update")
configurationBlock()
}
addToCompdb(task)
if (outputGroup == "main" && sanitizer == null) {
allMainModulesTask.configure {
dependsOn(taskName)
addToCompdb(task.get()) // TODO: Do not force task configuration.
if (outputGroup == "main") {
compileBitcodeMainElements.artifact(task)
// TODO: This seems to go against gradle conventions. So, each module should probably be in
// a gradle project of its own. Current project should be used for grouping (i.e. reexporting all
// compileBitcodeMainElements from subprojects under a single umbrella configuration) and integration testing.
project.configurations.maybeCreate("${name}CompileBitcodeMainElements").apply {
description = "LLVM bitcode of $name module (main sources)"
isCanBeConsumed = true
isCanBeResolved = false
attributes {
attribute(Usage.USAGE_ATTRIBUTE, project.objects.named(USAGE))
attribute(MODULE_ATTRIBUTE, name)
}
outgoing {
variants {
create("$_target") {
attributes {
attribute(TargetWithSanitizer.TARGET_ATTRIBUTE, _target)
}
artifact(task)
}
}
}
}
}
}
@@ -317,5 +329,39 @@ open class CompileToBitcodeExtension @Inject constructor(val project: Project) :
const val BUILD_TASK_GROUP = LifecycleBasePlugin.BUILD_GROUP
const val VERIFICATION_TASK_GROUP = LifecycleBasePlugin.VERIFICATION_GROUP
const val VERIFICATION_BUILD_TASK_GROUP = "verification build"
@JvmField
val USAGE = "llvm-bitcode"
@JvmField
val MODULE_ATTRIBUTE = Attribute.of("org.jetbrains.kotlin.bitcode.module", String::class.java)
}
}
/**
* Compiling C and C++ modules into LLVM bitcode.
*
* Creates [CompileToBitcodeExtension] extension named `bitcode`.
*
* Creates the following [configurations][org.gradle.api.artifacts.Configuration]:
* * `compileBitcodeMainElements` - like `apiElements` (sort of) from java plugin, or `{variant}LinkElements` from C++ plugin.
* Contains bitcode produced from main sources of all defined modules.
* * `{module}CompileBitcodeMainElements` - like `compileBitcodeMainElements` but for a single `module`.
*
* Each of the defined configuration has [Usage attribute][Usage] set to [CompileToBitcodeExtension.USAGE]. Module-specific configurations
* additionally have a [CompileToBitcodeExtension.MODULE_ATTRIBUTE] set to the module name.
* Each `*Elements` configuration has variants with [TargetWithSanitizer.TARGET_ATTRIBUTE] values.
*
* @see CompileToBitcodeExtension extension that this plugin creates.
*/
open class CompileToBitcodePlugin : Plugin<Project> {
override fun apply(project: Project) {
project.apply<CompilationDatabasePlugin>()
project.apply<GitClangFormatPlugin>()
project.dependencies.attributesSchema {
attribute(TargetWithSanitizer.TARGET_ATTRIBUTE)
attribute(CompileToBitcodeExtension.MODULE_ATTRIBUTE)
}
project.extensions.create<CompileToBitcodeExtension>("bitcode", project)
}
}
@@ -32,8 +32,11 @@ class TargetWithSanitizer(
}
companion object {
@JvmStatic
@JvmField
val TARGET_ATTRIBUTE = Attribute.of("org.jetbrains.kotlin.target", TargetWithSanitizer::class.java)
@JvmField
val host = TargetWithSanitizer(HostManager.host, null)
}
}
+16 -3
View File
@@ -20,6 +20,7 @@ import org.jetbrains.kotlin.CopySamples
import org.jetbrains.kotlin.CopyCommonSources
import org.jetbrains.kotlin.PlatformInfo
import org.jetbrains.kotlin.KotlinBuildPusher
import org.jetbrains.kotlin.bitcode.CompileToBitcodeExtension
import org.jetbrains.kotlin.cpp.CompilationDatabasePlugin
import org.jetbrains.kotlin.cpp.GitClangFormatPlugin
import org.jetbrains.kotlin.CompareDistributionSignatures
@@ -140,6 +141,14 @@ configurations {
ftpAntTask
distPack
commonSources
runtimeBitcode {
canBeConsumed = false
canBeResolved = true
attributes {
attribute(Usage.USAGE_ATTRIBUTE, objects.named(Usage, CompileToBitcodeExtension.USAGE))
}
}
}
apply plugin: CompilationDatabasePlugin
@@ -161,6 +170,7 @@ dependencies {
commonSources project(path: ':kotlin-test:kotlin-test-annotations-common', configuration: 'sources')
compilationDatabase project(":kotlin-native:common")
compilationDatabase project(":kotlin-native:runtime")
runtimeBitcode project(":kotlin-native:runtime")
}
apply plugin: GitClangFormatPlugin
@@ -438,11 +448,15 @@ targetList.each { target ->
}
task("${target}CrossDistBitcodeCopy", type: Copy) {
dependsOn ":kotlin-native:runtime:${target}Runtime"
def bitcodeFiles = configurations.runtimeBitcode.incoming.artifactView {
attributes {
attribute(TargetWithSanitizer.TARGET_ATTRIBUTE, new TargetWithSanitizer(platformManager.targetByName(target), null))
}
}.files
destinationDir project.file("$distDir/konan/targets/")
from(project(':kotlin-native:runtime').file("build/bitcode/main/$target")) {
from(bitcodeFiles) {
include("*.bc")
exclude("runtime.bc")
into("$target/native")
@@ -450,7 +464,6 @@ targetList.each { target ->
}
task("${target}CrossDistRuntime", type: Copy) {
dependsOn ":kotlin-native:runtime:${target}Runtime"
dependsOn ":kotlin-native:${target}CrossDistStdlib"
dependsOn "${target}CrossDistBitcodeCopy"
+33 -1
View File
@@ -244,6 +244,33 @@ bitcode {
}
}
val runtimeBitcode by configurations.creating {
isCanBeConsumed = false
isCanBeResolved = true
attributes {
attribute(Usage.USAGE_ATTRIBUTE, objects.named(CompileToBitcodeExtension.USAGE))
}
}
dependencies {
runtimeBitcode(project(":kotlin-native:runtime"))
}
targetList.forEach { targetName ->
// TODO: replace with a more convenient user-facing task that can build for a specific target.
// like compileToBitcode with optional argument --target.
tasks.register("${targetName}Runtime") {
description = "Build all main runtime modules for $targetName"
group = CompileToBitcodeExtension.BUILD_TASK_GROUP
val dependencies = runtimeBitcode.incoming.artifactView {
attributes {
attribute(TargetWithSanitizer.TARGET_ATTRIBUTE, project.platformManager.targetByName(targetName).withSanitizer())
}
}.files
dependsOn(dependencies)
}
}
val hostRuntime by tasks.registering {
description = "Build all main runtime modules for host"
group = CompileToBitcodeExtension.BUILD_TASK_GROUP
@@ -367,7 +394,12 @@ targetList.forEach { targetName ->
destinationDir = project.buildDir.resolve("${targetName}Stdlib")
from(project.buildDir.resolve("stdlib/${hostName}/stdlib"))
from(project.buildDir.resolve("bitcode/main/$targetName")) {
val runtimeFiles = runtimeBitcode.incoming.artifactView {
attributes {
attribute(TargetWithSanitizer.TARGET_ATTRIBUTE, project.platformManager.targetByName(targetName).withSanitizer())
}
}.files
from(runtimeFiles) {
include("runtime.bc", "compiler_interface.bc")
into("default/targets/$targetName/native")
}