[K/N] Extract Module in CompileToBitcodePlugin ^KT-53776
Merge-request: KT-MR-7960 Merged-by: Alexander Shabalin <Alexander.Shabalin@jetbrains.com>
This commit is contained in:
committed by
Space Team
parent
7cbe13dee9
commit
ff2f163ac9
@@ -1,8 +1,7 @@
|
|||||||
import org.jetbrains.kotlin.CopyCommonSources
|
import org.jetbrains.kotlin.cpp.CppConsumerPlugin
|
||||||
import org.jetbrains.kotlin.konan.target.*
|
import org.jetbrains.kotlin.cpp.CppUsage
|
||||||
import org.jetbrains.kotlin.*
|
import org.jetbrains.kotlin.cpp.DependencyHandlerExKt
|
||||||
import org.jetbrains.gradle.plugins.tools.*
|
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
|
* 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.
|
* that can be found in the LICENSE file.
|
||||||
@@ -16,6 +15,7 @@ apply plugin: 'java'
|
|||||||
apply plugin: 'kotlin'
|
apply plugin: 'kotlin'
|
||||||
apply plugin: org.jetbrains.kotlin.NativeInteropPlugin
|
apply plugin: org.jetbrains.kotlin.NativeInteropPlugin
|
||||||
apply plugin: "maven-publish"
|
apply plugin: "maven-publish"
|
||||||
|
apply plugin: CppConsumerPlugin
|
||||||
|
|
||||||
sourceSets {
|
sourceSets {
|
||||||
compiler {
|
compiler {
|
||||||
@@ -46,25 +46,23 @@ configurations {
|
|||||||
canBeConsumed = false
|
canBeConsumed = false
|
||||||
canBeResolved = true
|
canBeResolved = true
|
||||||
attributes {
|
attributes {
|
||||||
attribute(Usage.USAGE_ATTRIBUTE, objects.named(Usage, CompileToBitcodeExtension.USAGE))
|
attribute(Usage.USAGE_ATTRIBUTE, objects.named(Usage, CppUsage.LLVM_BITCODE))
|
||||||
attribute(TargetWithSanitizer.TARGET_ATTRIBUTE, TargetWithSanitizer.host)
|
|
||||||
attribute(CompileToBitcodeExtension.MODULE_ATTRIBUTE, "files")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
commonEnvBitcode {
|
commonEnvBitcode {
|
||||||
canBeConsumed = false
|
canBeConsumed = false
|
||||||
canBeResolved = true
|
canBeResolved = true
|
||||||
attributes {
|
attributes {
|
||||||
attribute(Usage.USAGE_ATTRIBUTE, objects.named(Usage, CompileToBitcodeExtension.USAGE))
|
attribute(Usage.USAGE_ATTRIBUTE, objects.named(Usage, CppUsage.LLVM_BITCODE))
|
||||||
attribute(TargetWithSanitizer.TARGET_ATTRIBUTE, TargetWithSanitizer.host)
|
|
||||||
attribute(CompileToBitcodeExtension.MODULE_ATTRIBUTE, "env")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
commonFilesBitcode project(":kotlin-native:common")
|
use(DependencyHandlerExKt) {
|
||||||
commonEnvBitcode project(":kotlin-native:common")
|
commonFilesBitcode module(project(":kotlin-native:common"), "files")
|
||||||
|
commonEnvBitcode module(project(":kotlin-native:common"), "env")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
kotlinNativeInterop {
|
kotlinNativeInterop {
|
||||||
|
|||||||
-4
@@ -142,10 +142,6 @@ abstract class CompileToBitcode @Inject constructor(
|
|||||||
@get:Internal
|
@get:Internal
|
||||||
abstract val headersDirs: ConfigurableFileCollection
|
abstract val headersDirs: ConfigurableFileCollection
|
||||||
|
|
||||||
// TODO: Move to module description.
|
|
||||||
@get:Internal
|
|
||||||
abstract val moduleName: Property<String>
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Final computed compiler arguments.
|
* Final computed compiler arguments.
|
||||||
*/
|
*/
|
||||||
|
|||||||
+432
-177
@@ -6,23 +6,27 @@
|
|||||||
package org.jetbrains.kotlin.bitcode
|
package org.jetbrains.kotlin.bitcode
|
||||||
|
|
||||||
import kotlinBuildProperties
|
import kotlinBuildProperties
|
||||||
import org.gradle.api.Action
|
import org.gradle.api.*
|
||||||
import org.gradle.api.Plugin
|
import org.gradle.api.artifacts.Configuration
|
||||||
import org.gradle.api.Project
|
import org.gradle.api.artifacts.ConfigurationVariant
|
||||||
import org.gradle.api.attributes.Attribute
|
|
||||||
import org.gradle.api.attributes.Usage
|
import org.gradle.api.attributes.Usage
|
||||||
|
import org.gradle.api.file.*
|
||||||
import org.gradle.api.provider.ListProperty
|
import org.gradle.api.provider.ListProperty
|
||||||
import org.gradle.api.provider.Property
|
import org.gradle.api.provider.Property
|
||||||
|
import org.gradle.api.provider.Provider
|
||||||
import org.gradle.api.services.BuildService
|
import org.gradle.api.services.BuildService
|
||||||
import org.gradle.api.services.BuildServiceParameters
|
import org.gradle.api.services.BuildServiceParameters
|
||||||
|
import org.gradle.api.specs.Spec
|
||||||
|
import org.gradle.api.tasks.TaskProvider
|
||||||
import org.gradle.kotlin.dsl.*
|
import org.gradle.kotlin.dsl.*
|
||||||
import org.gradle.language.base.plugins.LifecycleBasePlugin
|
import org.gradle.language.base.plugins.LifecycleBasePlugin
|
||||||
import org.jetbrains.kotlin.ExecClang
|
import org.jetbrains.kotlin.ExecClang
|
||||||
import org.jetbrains.kotlin.cpp.*
|
import org.jetbrains.kotlin.cpp.*
|
||||||
import org.jetbrains.kotlin.konan.target.*
|
import org.jetbrains.kotlin.konan.target.SanitizerKind
|
||||||
|
import org.jetbrains.kotlin.konan.target.TargetDomainObjectContainer
|
||||||
|
import org.jetbrains.kotlin.konan.target.TargetWithSanitizer
|
||||||
import org.jetbrains.kotlin.testing.native.GoogleTestExtension
|
import org.jetbrains.kotlin.testing.native.GoogleTestExtension
|
||||||
import org.jetbrains.kotlin.utils.capitalized
|
import org.jetbrains.kotlin.utils.capitalized
|
||||||
import java.io.File
|
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
private fun String.snakeCaseToUpperCamelCase() = split('_').joinToString(separator = "") { it.capitalized }
|
private fun String.snakeCaseToUpperCamelCase() = split('_').joinToString(separator = "") { it.capitalized }
|
||||||
@@ -36,13 +40,6 @@ private val SanitizerKind?.taskSuffix
|
|||||||
SanitizerKind.THREAD -> "_TSAN"
|
SanitizerKind.THREAD -> "_TSAN"
|
||||||
}
|
}
|
||||||
|
|
||||||
private val SanitizerKind?.dirSuffix
|
|
||||||
get() = when (this) {
|
|
||||||
null -> ""
|
|
||||||
SanitizerKind.ADDRESS -> "-asan"
|
|
||||||
SanitizerKind.THREAD -> "-tsan"
|
|
||||||
}
|
|
||||||
|
|
||||||
private val SanitizerKind?.description
|
private val SanitizerKind?.description
|
||||||
get() = when (this) {
|
get() = when (this) {
|
||||||
null -> ""
|
null -> ""
|
||||||
@@ -50,6 +47,48 @@ private val SanitizerKind?.description
|
|||||||
SanitizerKind.THREAD -> " with TSAN"
|
SanitizerKind.THREAD -> " with TSAN"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds new object named [name] and configure it with [action] or return already existing object with this name.
|
||||||
|
*
|
||||||
|
* Similar to [NamedDomainObjectContainer.maybeCreate] but with [action] argument that will be applied only if
|
||||||
|
* an object is being created.
|
||||||
|
*/
|
||||||
|
private fun <T> NamedDomainObjectContainer<T>.getOrCreate(name: String, action: Action<in T>): T = try {
|
||||||
|
this.create(name, action)
|
||||||
|
} catch (e: InvalidUserDataException) {
|
||||||
|
this.getByName(name)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun Project.compileBitcodeElements(sourceSet: String, action: Action<in Configuration>): Configuration = configurations.getOrCreate("compileBitcode${sourceSet.capitalized}Elements") {
|
||||||
|
description = "LLVM bitcode of all defined modules ($sourceSet sources)"
|
||||||
|
isCanBeConsumed = true
|
||||||
|
isCanBeResolved = false
|
||||||
|
attributes {
|
||||||
|
attribute(Usage.USAGE_ATTRIBUTE, project.objects.named(CppUsage.LLVM_BITCODE))
|
||||||
|
}
|
||||||
|
action.execute(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun Project.compileBitcodeElements(sourceSet: String) = compileBitcodeElements(sourceSet) {}
|
||||||
|
|
||||||
|
private fun Project.moduleCompileBitcodeElements(moduleName: String, sourceSet: String, action: Action<in Configuration>): Configuration = configurations.getOrCreate("${moduleName}CompileBitcode${sourceSet.capitalized}Elements") {
|
||||||
|
description = "LLVM bitcode of $moduleName module ($sourceSet sources)"
|
||||||
|
isCanBeConsumed = true
|
||||||
|
isCanBeResolved = false
|
||||||
|
attributes {
|
||||||
|
attribute(Usage.USAGE_ATTRIBUTE, project.objects.named(CppUsage.LLVM_BITCODE))
|
||||||
|
}
|
||||||
|
action.execute(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun Project.moduleCompileBitcodeElements(moduleName: String, sourceSet: String) = moduleCompileBitcodeElements(moduleName, sourceSet) {}
|
||||||
|
|
||||||
|
private fun Configuration.targetVariant(target: TargetWithSanitizer): ConfigurationVariant = outgoing.variants.getOrCreate("$target") {
|
||||||
|
attributes {
|
||||||
|
attribute(TargetWithSanitizer.TARGET_ATTRIBUTE, target)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private abstract class RunGTestSemaphore : BuildService<BuildServiceParameters.None>
|
private abstract class RunGTestSemaphore : BuildService<BuildServiceParameters.None>
|
||||||
private abstract class CompileTestsSemaphore : BuildService<BuildServiceParameters.None>
|
private abstract class CompileTestsSemaphore : BuildService<BuildServiceParameters.None>
|
||||||
|
|
||||||
@@ -60,12 +99,26 @@ open class CompileToBitcodeExtension @Inject constructor(val project: Project) :
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val compileBitcodeMainElements by project.configurations.creating {
|
/**
|
||||||
description = "LLVM bitcode of all defined modules (main sources)"
|
* Outgoing configuration with `main` parts of all modules.
|
||||||
isCanBeConsumed = true
|
*/
|
||||||
isCanBeResolved = false
|
val compileBitcodeMainElements = project.compileBitcodeElements(MAIN_SOURCE_SET_NAME)
|
||||||
attributes {
|
|
||||||
attribute(Usage.USAGE_ATTRIBUTE, project.objects.named(USAGE))
|
/**
|
||||||
|
* Outgoing configuration with `testFixtures` parts of all modules.
|
||||||
|
*/
|
||||||
|
val compileBitcodeTestFixturesElements = project.compileBitcodeElements(TEST_FIXTURES_SOURCE_SET_NAME) {
|
||||||
|
outgoing {
|
||||||
|
capability(CppConsumerPlugin.testFixturesCapability(project))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Outgoing configuration with `test` parts of all modules.
|
||||||
|
*/
|
||||||
|
val compileBitcodeTestElements = project.compileBitcodeElements(TEST_SOURCE_SET_NAME) {
|
||||||
|
outgoing {
|
||||||
|
capability(CppConsumerPlugin.testCapability(project))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -95,6 +148,294 @@ open class CompileToBitcodeExtension @Inject constructor(val project: Project) :
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A group of source files that will be compiled together.
|
||||||
|
*
|
||||||
|
* There are 3 well known source sets: `main`, `testFixtures` and `test`.
|
||||||
|
*/
|
||||||
|
abstract class SourceSet @Inject constructor(
|
||||||
|
private val owner: CompileToBitcodeExtension,
|
||||||
|
private val module: Module,
|
||||||
|
private val name: String,
|
||||||
|
private val _target: TargetWithSanitizer,
|
||||||
|
) : Named {
|
||||||
|
val target by _target::target
|
||||||
|
val sanitizer by _target::sanitizer
|
||||||
|
|
||||||
|
override fun getName() = name
|
||||||
|
|
||||||
|
private val project by owner::project
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resulting single LLVM bitcode file.
|
||||||
|
*/
|
||||||
|
abstract val outputFile: RegularFileProperty
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Directory where LLVM bitcode files for each of the [inputFiles] is placed.
|
||||||
|
*/
|
||||||
|
abstract val outputDirectory: DirectoryProperty
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Header paths to use when compiling [inputFiles].
|
||||||
|
*/
|
||||||
|
abstract val headersDirs: ConfigurableFileCollection
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Source files to compile.
|
||||||
|
*/
|
||||||
|
abstract val inputFiles: ConfigurableFileTree
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Additional task dependencies.
|
||||||
|
*/
|
||||||
|
abstract val dependencies: ListProperty<TaskProvider<*>>
|
||||||
|
|
||||||
|
protected abstract val onlyIf: ListProperty<Spec<in SourceSet>>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builds this source set only if [spec] is satisfied.
|
||||||
|
*/
|
||||||
|
fun onlyIf(spec: Spec<in SourceSet>) {
|
||||||
|
this.onlyIf.add(spec)
|
||||||
|
}
|
||||||
|
|
||||||
|
private val compilationDatabase = project.extensions.getByType<CompilationDatabaseExtension>()
|
||||||
|
private val execClang = project.extensions.getByType<ExecClang>()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Task that produces [outputFile].
|
||||||
|
*/
|
||||||
|
val task = project.tasks.register<CompileToBitcode>("compileToBitcode${module.name.capitalized}${name.capitalized}${_target.toString().capitalized}", _target).apply {
|
||||||
|
configure {
|
||||||
|
this.description = "Compiles '${module.name}' (${this@SourceSet.name} sources) to bitcode for ${_target}"
|
||||||
|
this.outputFile.set(this@SourceSet.outputFile)
|
||||||
|
this.outputDirectory.set(this@SourceSet.outputDirectory)
|
||||||
|
this.compiler.set(module.compiler)
|
||||||
|
this.linkerArgs.set(module.linkerArgs)
|
||||||
|
this.compilerArgs.set(module.compilerArgs)
|
||||||
|
this.headersDirs.from(this@SourceSet.headersDirs)
|
||||||
|
this.inputFiles.from(this@SourceSet.inputFiles.dir)
|
||||||
|
this.inputFiles.setIncludes(this@SourceSet.inputFiles.includes)
|
||||||
|
this.inputFiles.setExcludes(this@SourceSet.inputFiles.excludes)
|
||||||
|
this.compilerWorkingDirectory.set(module.compilerWorkingDirectory)
|
||||||
|
// TODO: Should depend only on the toolchain needed to build for the _target
|
||||||
|
dependsOn(":kotlin-native:dependencies:update")
|
||||||
|
dependsOn(this@SourceSet.dependencies)
|
||||||
|
onlyIf {
|
||||||
|
this@SourceSet.onlyIf.get().all { it.isSatisfiedBy(this@SourceSet) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
compilationDatabase.target(_target) {
|
||||||
|
entry {
|
||||||
|
val compileTask = this@apply.get()
|
||||||
|
val args = listOf(execClang.resolveExecutable(compileTask.compiler.get())) + compileTask.compilerFlags.get() + execClang.clangArgsForCppRuntime(target.name)
|
||||||
|
directory.set(compileTask.compilerWorkingDirectory)
|
||||||
|
files.setFrom(compileTask.inputFiles)
|
||||||
|
arguments.set(args)
|
||||||
|
// Only the location of output file matters, compdb does not depend on the compilation result.
|
||||||
|
output.set(compileTask.outputFile.locationOnly.map { it.asFile.absolutePath })
|
||||||
|
}
|
||||||
|
task.configure {
|
||||||
|
// Compile task depends on the toolchain (including headers) and on the source code (e.g. googletest).
|
||||||
|
// compdb task should also have these dependencies. This way the generated database will point to the
|
||||||
|
// code that actually exists.
|
||||||
|
// TODO: Should depend only on the toolchain needed to build for the _target
|
||||||
|
dependsOn(":kotlin-native:dependencies:update")
|
||||||
|
dependsOn(this@SourceSet.dependencies)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
project.compileBitcodeElements(this@SourceSet.name).targetVariant(_target).artifact(this)
|
||||||
|
project.moduleCompileBitcodeElements(module.name, this@SourceSet.name).targetVariant(_target).artifact(this)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Consider putting each module 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.
|
||||||
|
abstract class Module @Inject constructor(
|
||||||
|
private val owner: CompileToBitcodeExtension,
|
||||||
|
private val name: String,
|
||||||
|
private val _target: TargetWithSanitizer,
|
||||||
|
) : Named {
|
||||||
|
/**
|
||||||
|
* A container for [SourceSet].
|
||||||
|
*
|
||||||
|
* 3 source sets are well known: [main], [testFixtures] and [test].
|
||||||
|
*/
|
||||||
|
abstract class SourceSets @Inject constructor(
|
||||||
|
private val module: Module,
|
||||||
|
private val container: ExtensiblePolymorphicDomainObjectContainer<SourceSet>
|
||||||
|
) : NamedDomainObjectContainer<SourceSet> by container {
|
||||||
|
private val project by module::project
|
||||||
|
|
||||||
|
// googleTestExtension is only used if testFixtures or tests are used.
|
||||||
|
private val googleTestExtension by lazy { project.extensions.getByType<GoogleTestExtension>() }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get `main` source set if it was configured.
|
||||||
|
*/
|
||||||
|
val main: Provider<SourceSet>
|
||||||
|
get() = named(MAIN_SOURCE_SET_NAME)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configure `main` source set. Used for main module sources. Included into `compileBitcodeMainElements` configuration.
|
||||||
|
*/
|
||||||
|
fun main(action: Action<in SourceSet>): SourceSet = create(MAIN_SOURCE_SET_NAME) {
|
||||||
|
this.inputFiles.include("**/*.cpp", "**/*.mm")
|
||||||
|
this.inputFiles.exclude("**/*Test.cpp", "**/*TestSupport.cpp", "**/*Test.mm", "**/*TestSupport.mm")
|
||||||
|
task.configure {
|
||||||
|
this.group = BUILD_TASK_GROUP
|
||||||
|
}
|
||||||
|
action.execute(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get `testFixtures` source set if it was configured.
|
||||||
|
*/
|
||||||
|
val testFixtures: Provider<SourceSet>
|
||||||
|
get() = named(TEST_FIXTURES_SOURCE_SET_NAME)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configure `testFixtures` source set. Used for testing API parts of module. Included into `compileBitcodeTestFixturesElements` configuration.
|
||||||
|
*/
|
||||||
|
fun testFixtures(action: Action<in SourceSet>): SourceSet = create(TEST_FIXTURES_SOURCE_SET_NAME) {
|
||||||
|
this.inputFiles.include("**/*TestSupport.cpp", "**/*TestSupport.mm")
|
||||||
|
this.headersDirs.from(googleTestExtension.headersDirs)
|
||||||
|
// TODO: Must generally depend on googletest module headers which must itself depend on sources being present.
|
||||||
|
dependencies.add(project.tasks.named("downloadGoogleTest"))
|
||||||
|
task.configure {
|
||||||
|
this.group = VERIFICATION_BUILD_TASK_GROUP
|
||||||
|
}
|
||||||
|
action.execute(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get `test` source set if it was configured.
|
||||||
|
*/
|
||||||
|
val test: Provider<SourceSet>
|
||||||
|
get() = named(TEST_SOURCE_SET_NAME)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configure `test` source set. Used for test files of module. Included into `compileBitcodeTestElements` configuration.
|
||||||
|
*/
|
||||||
|
fun test(action: Action<in SourceSet>): SourceSet = create(TEST_SOURCE_SET_NAME) {
|
||||||
|
this.inputFiles.include("**/*Test.cpp", "**/*Test.mm")
|
||||||
|
this.headersDirs.from(googleTestExtension.headersDirs)
|
||||||
|
// TODO: Must generally depend on googletest module headers which must itself depend on sources being present.
|
||||||
|
dependencies.add(project.tasks.named("downloadGoogleTest"))
|
||||||
|
task.configure {
|
||||||
|
this.group = VERIFICATION_BUILD_TASK_GROUP
|
||||||
|
}
|
||||||
|
action.execute(this)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val target by _target::target
|
||||||
|
val sanitizer by _target::sanitizer
|
||||||
|
|
||||||
|
override fun getName() = name
|
||||||
|
|
||||||
|
private val project by owner::project
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Outgoing configuration with `main` part of this module.
|
||||||
|
*/
|
||||||
|
val compileBitcodeMainElements = project.moduleCompileBitcodeElements(name, MAIN_SOURCE_SET_NAME) {
|
||||||
|
outgoing {
|
||||||
|
capability(CppConsumerPlugin.moduleCapability(project, this@Module.name))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Outgoing configuration with `testFixtures` part of this module.
|
||||||
|
*/
|
||||||
|
val compileBitcodeTestFixturesElements = project.moduleCompileBitcodeElements(name, TEST_FIXTURES_SOURCE_SET_NAME) {
|
||||||
|
outgoing {
|
||||||
|
capability(CppConsumerPlugin.moduleTestFixturesCapability(project, this@Module.name))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Outgoing configuration with `test` part of this module.
|
||||||
|
*/
|
||||||
|
val compileBitcodeTestElements = project.moduleCompileBitcodeElements(name, TEST_SOURCE_SET_NAME) {
|
||||||
|
outgoing {
|
||||||
|
capability(CppConsumerPlugin.moduleTestCapability(project, this@Module.name))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Directory where module sources are located. By default `src/<module name>`.
|
||||||
|
*/
|
||||||
|
abstract val srcRoot: DirectoryProperty
|
||||||
|
|
||||||
|
// TODO: This is actually API dependency. Make it so.
|
||||||
|
/**
|
||||||
|
* Header directories to use for compilation of all [SourceSet]s.
|
||||||
|
*/
|
||||||
|
abstract val headersDirs: ConfigurableFileCollection
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compiler to use. Either `clang` or `clang++`.
|
||||||
|
*/
|
||||||
|
abstract val compiler: Property<String>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extra arguments to `llvm-link`.
|
||||||
|
*/
|
||||||
|
abstract val linkerArgs: ListProperty<String>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extra arguments to [compiler].
|
||||||
|
*/
|
||||||
|
abstract val compilerArgs: ListProperty<String>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Directory in which [compiler] will be executed. Important for macro evaluation like `__FILE__`.
|
||||||
|
*/
|
||||||
|
abstract val compilerWorkingDirectory: DirectoryProperty
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extra tqsk dependencies to be used for all [SourceSet]s.
|
||||||
|
*/
|
||||||
|
abstract val dependencies: ListProperty<TaskProvider<*>>
|
||||||
|
protected abstract val onlyIf: ListProperty<Spec<in Module>>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builds this module only if [spec] is satisfied.
|
||||||
|
*/
|
||||||
|
fun onlyIf(spec: Spec<in Module>) {
|
||||||
|
this.onlyIf.add(spec)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Container for [SourceSet]s.
|
||||||
|
*/
|
||||||
|
val sourceSets by lazy {
|
||||||
|
project.objects.newInstance<SourceSets>(this, project.objects.polymorphicDomainObjectContainer(SourceSet::class.java).apply {
|
||||||
|
registerFactory(SourceSet::class.java) {
|
||||||
|
project.objects.newInstance<SourceSet>(owner, this@Module, it, _target).apply {
|
||||||
|
this.outputFile.convention(project.layout.buildDirectory.file("bitcode/$name/$_target/${this@Module.name}.bc"))
|
||||||
|
this.outputDirectory.convention(project.layout.buildDirectory.dir("bitcode/$name/$_target/${this@Module.name}"))
|
||||||
|
this.inputFiles.from(this@Module.srcRoot.dir("cpp"))
|
||||||
|
this.headersDirs.setFrom(this@Module.headersDirs)
|
||||||
|
dependencies.set(this@Module.dependencies)
|
||||||
|
onlyIf {
|
||||||
|
this@Module.onlyIf.get().all { it.isSatisfiedBy(this@Module) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Container for [SourceSet]s.
|
||||||
|
*/
|
||||||
|
fun sourceSets(action: Action<in SourceSets>) = sourceSets.apply {
|
||||||
|
action.execute(this)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
abstract class TestsGroup @Inject constructor(
|
abstract class TestsGroup @Inject constructor(
|
||||||
private val _target: TargetWithSanitizer,
|
private val _target: TargetWithSanitizer,
|
||||||
) {
|
) {
|
||||||
@@ -102,7 +443,6 @@ open class CompileToBitcodeExtension @Inject constructor(val project: Project) :
|
|||||||
val sanitizer by _target::sanitizer
|
val sanitizer by _target::sanitizer
|
||||||
abstract val testedModules: ListProperty<String>
|
abstract val testedModules: ListProperty<String>
|
||||||
abstract val testSupportModules: ListProperty<String>
|
abstract val testSupportModules: ListProperty<String>
|
||||||
abstract val testFrameworkModules: ListProperty<String>
|
|
||||||
abstract val testLauncherModule: Property<String>
|
abstract val testLauncherModule: Property<String>
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -115,13 +455,6 @@ open class CompileToBitcodeExtension @Inject constructor(val project: Project) :
|
|||||||
|
|
||||||
private val project by owner::project
|
private val project by owner::project
|
||||||
|
|
||||||
private val compilationDatabase = project.extensions.getByType<CompilationDatabaseExtension>()
|
|
||||||
private val execClang = project.extensions.getByType<ExecClang>()
|
|
||||||
private val platformManager = project.extensions.getByType<PlatformManager>()
|
|
||||||
|
|
||||||
// googleTestExtension is only used if testsGroup is used.
|
|
||||||
private val googleTestExtension by lazy { project.extensions.getByType<GoogleTestExtension>() }
|
|
||||||
|
|
||||||
// A shared service used to limit parallel execution of test binaries.
|
// A shared service used to limit parallel execution of test binaries.
|
||||||
private val runGTestSemaphore = project.gradle.sharedServices.registerIfAbsent("runGTestSemaphore", RunGTestSemaphore::class.java) {
|
private val runGTestSemaphore = project.gradle.sharedServices.registerIfAbsent("runGTestSemaphore", RunGTestSemaphore::class.java) {
|
||||||
// Probably can be made configurable if test reporting moves away from simple gtest stdout dumping.
|
// Probably can be made configurable if test reporting moves away from simple gtest stdout dumping.
|
||||||
@@ -133,158 +466,69 @@ open class CompileToBitcodeExtension @Inject constructor(val project: Project) :
|
|||||||
maxParallelUsages.set(5)
|
maxParallelUsages.set(5)
|
||||||
}
|
}
|
||||||
|
|
||||||
private val compileBitcodeMainElements = owner.compileBitcodeMainElements.outgoing.variants.create("$_target") {
|
private val modules: NamedDomainObjectContainer<Module> = project.objects.polymorphicDomainObjectContainer(Module::class.java).apply {
|
||||||
attributes {
|
registerFactory(Module::class.java) {
|
||||||
attribute(TargetWithSanitizer.TARGET_ATTRIBUTE, _target)
|
project.objects.newInstance<Module>(owner, it, _target).apply {
|
||||||
}
|
this.srcRoot.convention(project.layout.projectDirectory.dir("src/$name"))
|
||||||
}
|
this.headersDirs.from(this.srcRoot.dir("cpp"))
|
||||||
|
this.compiler.convention("clang++")
|
||||||
private fun addToCompdb(compileTask: CompileToBitcode) {
|
this.compilerArgs.set(owner.DEFAULT_CPP_FLAGS)
|
||||||
compilationDatabase.target(_target) {
|
this.compilerWorkingDirectory.set(project.layout.projectDirectory.dir("src"))
|
||||||
entry {
|
|
||||||
val args = listOf(execClang.resolveExecutable(compileTask.compiler.get())) + compileTask.compilerFlags.get() + execClang.clangArgsForCppRuntime(target.name)
|
|
||||||
directory.set(compileTask.compilerWorkingDirectory)
|
|
||||||
files.setFrom(compileTask.inputFiles)
|
|
||||||
arguments.set(args)
|
|
||||||
// Only the location of output file matters, compdb does not depend on the compilation result.
|
|
||||||
output.set(compileTask.outputFile.locationOnly.map { it.asFile.absolutePath })
|
|
||||||
}
|
|
||||||
// Compile task depends on the toolchain (including headers) and on the source code (e.g. googletest).
|
|
||||||
// compdb task should also have these dependencies. This way the generated database will point to the
|
|
||||||
// code that actually exists.
|
|
||||||
// TODO: Probably module should know dependencies on its own.
|
|
||||||
task.configure {
|
|
||||||
dependsOn(compileTask.dependsOn)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun module(name: String, srcRoot: File = project.file("src/$name"), outputGroup: String = "main", configurationBlock: CompileToBitcode.() -> Unit = {}) {
|
fun module(
|
||||||
val targetName = target.name
|
name: String,
|
||||||
val taskName = fullTaskName(name, targetName, sanitizer)
|
action: Action<in Module>,
|
||||||
val task = project.tasks.register<CompileToBitcode>(taskName, _target)
|
): Module = modules.create(name) {
|
||||||
task.configure {
|
action.execute(this)
|
||||||
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") })
|
|
||||||
this.compiler.convention("clang++")
|
|
||||||
this.compilerArgs.set(owner.DEFAULT_CPP_FLAGS)
|
|
||||||
this.inputFiles.from(srcRoot.resolve("cpp"))
|
|
||||||
this.inputFiles.include("**/*.cpp", "**/*.mm")
|
|
||||||
this.inputFiles.exclude("**/*Test.cpp", "**/*TestSupport.cpp", "**/*Test.mm", "**/*TestSupport.mm")
|
|
||||||
this.headersDirs.from(this.inputFiles.dir)
|
|
||||||
this.compilerWorkingDirectory.set(project.layout.projectDirectory.dir("src"))
|
|
||||||
when (outputGroup) {
|
|
||||||
"test" -> this.group = VERIFICATION_BUILD_TASK_GROUP
|
|
||||||
"main" -> this.group = BUILD_TASK_GROUP
|
|
||||||
}
|
|
||||||
this.description = "Compiles '$name' to bitcode for $targetName${sanitizer.description}"
|
|
||||||
dependsOn(":kotlin-native:dependencies:update")
|
|
||||||
configurationBlock()
|
|
||||||
}
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun module(name: String): Provider<Module> = modules.named(name)
|
||||||
|
|
||||||
fun testsGroup(
|
fun testsGroup(
|
||||||
testTaskName: String,
|
testTaskName: String,
|
||||||
action: Action<in TestsGroup>,
|
action: Action<in TestsGroup>,
|
||||||
) {
|
) {
|
||||||
val testsGroup = project.objects.newInstance(TestsGroup::class.java, _target).apply {
|
val testsGroup = project.objects.newInstance(TestsGroup::class.java, _target).apply {
|
||||||
testFrameworkModules.convention(listOf("googletest", "googlemock"))
|
testSupportModules.set(listOf("googletest", "googlemock"))
|
||||||
testLauncherModule.convention("test_support")
|
testLauncherModule.convention("test_support")
|
||||||
action.execute(this)
|
action.execute(this)
|
||||||
|
testLauncherModule.finalizeValue()
|
||||||
}
|
}
|
||||||
val target = testsGroup.target
|
val target = testsGroup.target
|
||||||
val sanitizer = testsGroup.sanitizer
|
val sanitizer = testsGroup.sanitizer
|
||||||
val testName = fullTaskName(testTaskName, target.name, sanitizer)
|
val testName = fullTaskName(testTaskName, target.name, sanitizer)
|
||||||
val testedModulesMainTasks = testsGroup.testedModules.get().map {
|
|
||||||
val name = fullTaskName(it, target.name, sanitizer)
|
|
||||||
project.tasks.getByName(name) as CompileToBitcode
|
|
||||||
}
|
|
||||||
val testedModulesTestTasks = testedModulesMainTasks.mapNotNull {
|
|
||||||
val name = "${it.name}TestBitcode"
|
|
||||||
val task = project.tasks.findByName(name) as? CompileToBitcode
|
|
||||||
?: project.tasks.create(name, CompileToBitcode::class.java, _target).apply {
|
|
||||||
this.moduleName.set(it.moduleName)
|
|
||||||
this.outputFile.convention(moduleName.flatMap { project.layout.buildDirectory.file("bitcode/test/$target${sanitizer.dirSuffix}/${it}Tests.bc") })
|
|
||||||
this.outputDirectory.convention(moduleName.flatMap { project.layout.buildDirectory.dir("bitcode/test/$target${sanitizer.dirSuffix}/${it}Tests") })
|
|
||||||
this.compiler.convention("clang++")
|
|
||||||
this.compilerArgs.set(it.compilerArgs)
|
|
||||||
this.inputFiles.from(it.inputFiles.dir)
|
|
||||||
this.inputFiles.include("**/*Test.cpp", "**/*Test.mm")
|
|
||||||
this.headersDirs.setFrom(it.headersDirs)
|
|
||||||
this.headersDirs.from(googleTestExtension.headersDirs)
|
|
||||||
this.compilerWorkingDirectory.set(it.compilerWorkingDirectory)
|
|
||||||
this.group = VERIFICATION_BUILD_TASK_GROUP
|
|
||||||
this.description = "Compiles '${it.name}' tests to bitcode for $target${sanitizer.description}"
|
|
||||||
|
|
||||||
dependsOn(":kotlin-native:dependencies:update")
|
val testLauncherConfiguration = project.configurations.create("${testTaskName}${_target.toString().capitalized}TestLauncher") {
|
||||||
dependsOn("downloadGoogleTest")
|
isCanBeConsumed = false
|
||||||
|
isCanBeResolved = true
|
||||||
addToCompdb(this)
|
attributes {
|
||||||
}
|
attribute(CppUsage.USAGE_ATTRIBUTE, project.objects.named(CppUsage.LLVM_BITCODE))
|
||||||
task.takeUnless { t -> t.inputFiles.isEmpty }
|
}
|
||||||
}
|
}
|
||||||
val testSupportModulesMainTasks = testsGroup.testSupportModules.get().map {
|
val testsGroupConfiguration = project.configurations.create("${testTaskName}${_target.toString().capitalized}") {
|
||||||
val name = fullTaskName(it, target.name, sanitizer)
|
isCanBeConsumed = false
|
||||||
project.tasks.getByName(name) as CompileToBitcode
|
isCanBeResolved = true
|
||||||
|
attributes {
|
||||||
|
attribute(CppUsage.USAGE_ATTRIBUTE, project.objects.named(CppUsage.LLVM_BITCODE))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
val testedAndTestSupportModulesTestSupportTasks = (testedModulesMainTasks + testSupportModulesMainTasks).mapNotNull {
|
project.dependencies {
|
||||||
val name = "${it.name}TestSupportBitcode"
|
testsGroup.testLauncherModule.get().let { moduleName ->
|
||||||
val task = project.tasks.findByName(name) as? CompileToBitcode
|
testLauncherConfiguration(module(project(project.path), moduleName))
|
||||||
?: project.tasks.create(name, CompileToBitcode::class.java, _target).apply {
|
testLauncherConfiguration(moduleTestFixtures(project(project.path), moduleName))
|
||||||
this.moduleName.set(it.moduleName)
|
}
|
||||||
this.outputFile.convention(moduleName.flatMap { project.layout.buildDirectory.file("bitcode/test/$target${sanitizer.dirSuffix}/${it}TestSupport.bc") })
|
testsGroup.testedModules.get().forEach { moduleName ->
|
||||||
this.outputDirectory.convention(moduleName.flatMap { project.layout.buildDirectory.dir("bitcode/test/$target${sanitizer.dirSuffix}/${it}TestSupport") })
|
testsGroupConfiguration(module(project(project.path), moduleName))
|
||||||
this.compiler.convention("clang++")
|
testsGroupConfiguration(moduleTestFixtures(project(project.path), moduleName))
|
||||||
this.compilerArgs.set(it.compilerArgs)
|
testsGroupConfiguration(moduleTest(project(project.path), moduleName))
|
||||||
this.inputFiles.from(it.inputFiles.dir)
|
}
|
||||||
this.inputFiles.include("**/*TestSupport.cpp", "**/*TestSupport.mm")
|
testsGroup.testSupportModules.get().forEach { moduleName ->
|
||||||
this.headersDirs.setFrom(it.headersDirs)
|
testsGroupConfiguration(module(project(project.path), moduleName))
|
||||||
this.headersDirs.from(googleTestExtension.headersDirs)
|
testsGroupConfiguration(moduleTestFixtures(project(project.path), moduleName))
|
||||||
this.compilerWorkingDirectory.set(it.compilerWorkingDirectory)
|
}
|
||||||
this.group = VERIFICATION_BUILD_TASK_GROUP
|
|
||||||
this.description = "Compiles '${it.name}' test support to bitcode for $target${sanitizer.description}"
|
|
||||||
|
|
||||||
dependsOn(":kotlin-native:dependencies:update")
|
|
||||||
dependsOn("downloadGoogleTest")
|
|
||||||
|
|
||||||
addToCompdb(this)
|
|
||||||
}
|
|
||||||
task.takeUnless { t -> t.inputFiles.isEmpty }
|
|
||||||
}
|
|
||||||
val testFrameworkMainTasks = testsGroup.testFrameworkModules.get().map {
|
|
||||||
val name = fullTaskName(it, target.name, sanitizer)
|
|
||||||
project.tasks.getByName(name) as CompileToBitcode
|
|
||||||
}
|
|
||||||
val testLauncherMainTask = testsGroup.testLauncherModule.get().let {
|
|
||||||
val name = fullTaskName(it, target.name, sanitizer)
|
|
||||||
project.tasks.getByName(name) as CompileToBitcode
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val compileTask = project.tasks.register<CompileToExecutable>("${testName}Compile") {
|
val compileTask = project.tasks.register<CompileToExecutable>("${testName}Compile") {
|
||||||
@@ -296,11 +540,26 @@ open class CompileToBitcodeExtension @Inject constructor(val project: Project) :
|
|||||||
this.llvmLinkFirstStageOutputFile.set(project.layout.buildDirectory.file("bitcode/test/$target/$testName-firstStage.bc"))
|
this.llvmLinkFirstStageOutputFile.set(project.layout.buildDirectory.file("bitcode/test/$target/$testName-firstStage.bc"))
|
||||||
this.llvmLinkOutputFile.set(project.layout.buildDirectory.file("bitcode/test/$target/$testName.bc"))
|
this.llvmLinkOutputFile.set(project.layout.buildDirectory.file("bitcode/test/$target/$testName.bc"))
|
||||||
this.compilerOutputFile.set(project.layout.buildDirectory.file("obj/$target/$testName.o"))
|
this.compilerOutputFile.set(project.layout.buildDirectory.file("obj/$target/$testName.o"))
|
||||||
this.mimallocEnabled.set(testsGroup.testedModules.get().any { it.contains("mimalloc") })
|
val allModules = listOf(testsGroup.testLauncherModule.get()) + testsGroup.testSupportModules.get() + testsGroup.testedModules.get()
|
||||||
this.mainFile.set(testLauncherMainTask.outputFile)
|
// TODO: Superwrong. Module should carry dependencies to system libraries that are passed to the linker.
|
||||||
val tasksToLink = (testedModulesTestTasks + testedModulesMainTasks + testFrameworkMainTasks + testSupportModulesMainTasks + testedAndTestSupportModulesTestSupportTasks)
|
val mimallocEnabled = allModules.contains("mimalloc")
|
||||||
this.inputFiles.setFrom(tasksToLink.map { it.outputFile })
|
this.mimallocEnabled.set(mimallocEnabled)
|
||||||
|
val mainFileConfiguration = testLauncherConfiguration.incoming.artifactView {
|
||||||
|
attributes {
|
||||||
|
attribute(TargetWithSanitizer.TARGET_ATTRIBUTE, _target)
|
||||||
|
}
|
||||||
|
}.files
|
||||||
|
// TODO: Check if this is still required.
|
||||||
|
this.mainFile.set(mainFileConfiguration.singleFile)
|
||||||
|
dependsOn(mainFileConfiguration)
|
||||||
|
val inputFilesConfiguration = testsGroupConfiguration.incoming.artifactView {
|
||||||
|
attributes {
|
||||||
|
attribute(TargetWithSanitizer.TARGET_ATTRIBUTE, _target)
|
||||||
|
}
|
||||||
|
}.files
|
||||||
|
this.inputFiles.from(inputFilesConfiguration)
|
||||||
|
|
||||||
|
// Limit parallelism.
|
||||||
usesService(compileTestsSemaphore)
|
usesService(compileTestsSemaphore)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -330,11 +589,9 @@ open class CompileToBitcodeExtension @Inject constructor(val project: Project) :
|
|||||||
const val VERIFICATION_TASK_GROUP = LifecycleBasePlugin.VERIFICATION_GROUP
|
const val VERIFICATION_TASK_GROUP = LifecycleBasePlugin.VERIFICATION_GROUP
|
||||||
const val VERIFICATION_BUILD_TASK_GROUP = "verification build"
|
const val VERIFICATION_BUILD_TASK_GROUP = "verification build"
|
||||||
|
|
||||||
@JvmField
|
const val MAIN_SOURCE_SET_NAME = "main"
|
||||||
val USAGE = "llvm-bitcode"
|
const val TEST_FIXTURES_SOURCE_SET_NAME = "testFixtures"
|
||||||
|
const val TEST_SOURCE_SET_NAME = "test"
|
||||||
@JvmField
|
|
||||||
val MODULE_ATTRIBUTE = Attribute.of("org.jetbrains.kotlin.bitcode.module", String::class.java)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -344,24 +601,22 @@ open class CompileToBitcodeExtension @Inject constructor(val project: Project) :
|
|||||||
* Creates [CompileToBitcodeExtension] extension named `bitcode`.
|
* Creates [CompileToBitcodeExtension] extension named `bitcode`.
|
||||||
*
|
*
|
||||||
* Creates the following [configurations][org.gradle.api.artifacts.Configuration]:
|
* Creates the following [configurations][org.gradle.api.artifacts.Configuration]:
|
||||||
* * `compileBitcodeMainElements` - like `apiElements` (sort of) from java plugin, or `{variant}LinkElements` from C++ plugin.
|
* * `compileBitcode{sourceSet}Elements` - like `apiElements` (sort of) from java plugin, or `{variant}LinkElements` from C++ plugin.
|
||||||
* Contains bitcode produced from main sources of all defined modules.
|
* Contains bitcode produced from `sourceSet` sources of all defined modules.
|
||||||
* * `{module}CompileBitcodeMainElements` - like `compileBitcodeMainElements` but for a single `module`.
|
* * `{module}CompileBitcode{sourceSet}Elements` - like `compileBitcode{sourceSet}Elements` but for a single `module`.
|
||||||
*
|
*
|
||||||
* Each of the defined configuration has [Usage attribute][Usage] set to [CompileToBitcodeExtension.USAGE]. Module-specific configurations
|
* Each of the defined configuration has [Usage attribute][Usage] set to [CppUsage.LLVM_BITCODE].
|
||||||
* additionally have a [CompileToBitcodeExtension.MODULE_ATTRIBUTE] set to the module name.
|
|
||||||
* Each `*Elements` configuration has variants with [TargetWithSanitizer.TARGET_ATTRIBUTE] values.
|
* Each `*Elements` configuration has variants with [TargetWithSanitizer.TARGET_ATTRIBUTE] values.
|
||||||
*
|
*
|
||||||
|
* To depend on a specific module, use [module][org.jetbrains.kotlin.cpp.module] and [moduleTestFixtures][org.jetbrains.kotlin.cpp.moduleTestFixtures].
|
||||||
|
*
|
||||||
* @see CompileToBitcodeExtension extension that this plugin creates.
|
* @see CompileToBitcodeExtension extension that this plugin creates.
|
||||||
*/
|
*/
|
||||||
open class CompileToBitcodePlugin : Plugin<Project> {
|
open class CompileToBitcodePlugin : Plugin<Project> {
|
||||||
override fun apply(project: Project) {
|
override fun apply(project: Project) {
|
||||||
|
project.apply<CppConsumerPlugin>()
|
||||||
project.apply<CompilationDatabasePlugin>()
|
project.apply<CompilationDatabasePlugin>()
|
||||||
project.apply<GitClangFormatPlugin>()
|
project.apply<GitClangFormatPlugin>()
|
||||||
project.dependencies.attributesSchema {
|
|
||||||
attribute(TargetWithSanitizer.TARGET_ATTRIBUTE)
|
|
||||||
attribute(CompileToBitcodeExtension.MODULE_ATTRIBUTE)
|
|
||||||
}
|
|
||||||
project.extensions.create<CompileToBitcodeExtension>("bitcode", project)
|
project.extensions.create<CompileToBitcodeExtension>("bitcode", project)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+4
-10
@@ -9,7 +9,6 @@ import org.gradle.api.Action
|
|||||||
import org.gradle.api.Plugin
|
import org.gradle.api.Plugin
|
||||||
import org.gradle.api.Project
|
import org.gradle.api.Project
|
||||||
import org.gradle.api.artifacts.Configuration
|
import org.gradle.api.artifacts.Configuration
|
||||||
import org.gradle.api.attributes.Usage
|
|
||||||
import org.gradle.api.file.ConfigurableFileCollection
|
import org.gradle.api.file.ConfigurableFileCollection
|
||||||
import org.gradle.api.file.DirectoryProperty
|
import org.gradle.api.file.DirectoryProperty
|
||||||
import org.gradle.api.provider.ListProperty
|
import org.gradle.api.provider.ListProperty
|
||||||
@@ -56,7 +55,7 @@ abstract class CompilationDatabaseExtension @Inject constructor(private val proj
|
|||||||
isCanBeConsumed = false
|
isCanBeConsumed = false
|
||||||
isCanBeResolved = false
|
isCanBeResolved = false
|
||||||
attributes {
|
attributes {
|
||||||
attribute(Usage.USAGE_ATTRIBUTE, project.objects.named(USAGE))
|
attribute(CppUsage.USAGE_ATTRIBUTE, project.objects.named(CppUsage.COMPILATION_DATABASE))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -68,7 +67,7 @@ abstract class CompilationDatabaseExtension @Inject constructor(private val proj
|
|||||||
isCanBeConsumed = false
|
isCanBeConsumed = false
|
||||||
isCanBeResolved = true
|
isCanBeResolved = true
|
||||||
attributes {
|
attributes {
|
||||||
attribute(Usage.USAGE_ATTRIBUTE, project.objects.named(USAGE))
|
attribute(CppUsage.USAGE_ATTRIBUTE, project.objects.named(CppUsage.COMPILATION_DATABASE))
|
||||||
}
|
}
|
||||||
extendsFrom(compilationDatabase)
|
extendsFrom(compilationDatabase)
|
||||||
}
|
}
|
||||||
@@ -81,7 +80,7 @@ abstract class CompilationDatabaseExtension @Inject constructor(private val proj
|
|||||||
isCanBeConsumed = true
|
isCanBeConsumed = true
|
||||||
isCanBeResolved = false
|
isCanBeResolved = false
|
||||||
attributes {
|
attributes {
|
||||||
attribute(Usage.USAGE_ATTRIBUTE, project.objects.named(USAGE))
|
attribute(CppUsage.USAGE_ATTRIBUTE, project.objects.named(CppUsage.COMPILATION_DATABASE))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -202,9 +201,6 @@ abstract class CompilationDatabaseExtension @Inject constructor(private val proj
|
|||||||
companion object {
|
companion object {
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
val TASK_GROUP = "development support"
|
val TASK_GROUP = "development support"
|
||||||
|
|
||||||
@JvmStatic
|
|
||||||
val USAGE = "compilationDatabase"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -221,9 +217,7 @@ abstract class CompilationDatabaseExtension @Inject constructor(private val proj
|
|||||||
*/
|
*/
|
||||||
open class CompilationDatabasePlugin : Plugin<Project> {
|
open class CompilationDatabasePlugin : Plugin<Project> {
|
||||||
override fun apply(project: Project) {
|
override fun apply(project: Project) {
|
||||||
project.dependencies.attributesSchema {
|
project.apply<CppConsumerPlugin>()
|
||||||
attribute(TargetWithSanitizer.TARGET_ATTRIBUTE)
|
|
||||||
}
|
|
||||||
project.extensions.create<CompilationDatabaseExtension>("compilationDatabase", project)
|
project.extensions.create<CompilationDatabaseExtension>("compilationDatabase", project)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+53
@@ -0,0 +1,53 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2022 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.cpp
|
||||||
|
|
||||||
|
import org.gradle.api.Plugin
|
||||||
|
import org.gradle.api.Project
|
||||||
|
import org.gradle.api.attributes.Attribute
|
||||||
|
import org.gradle.api.attributes.AttributeDisambiguationRule
|
||||||
|
import org.gradle.api.attributes.MultipleCandidatesDetails
|
||||||
|
import org.jetbrains.kotlin.bitcode.CompileToBitcodePlugin
|
||||||
|
import org.jetbrains.kotlin.konan.target.TargetWithSanitizer
|
||||||
|
|
||||||
|
private class TargetDisambiguationRule : AttributeDisambiguationRule<TargetWithSanitizer> {
|
||||||
|
override fun execute(details: MultipleCandidatesDetails<TargetWithSanitizer>) = details.run {
|
||||||
|
if (consumerValue == null) {
|
||||||
|
// If the consumer didn't want a specific target, provide host target if it's available.
|
||||||
|
val default = TargetWithSanitizer.host
|
||||||
|
if (candidateValues.contains(default)) {
|
||||||
|
closestMatch(default)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Plugin for projects that depend upon C++-built projects.
|
||||||
|
*
|
||||||
|
* For building C++ use [CompileToBitcodePlugin].
|
||||||
|
*
|
||||||
|
* @see CompileToBitcodePlugin
|
||||||
|
*/
|
||||||
|
// TODO: Consider doing CppBasePlugin like standard gradle plugins that also
|
||||||
|
// creates default configurations and lifecycle tasks.
|
||||||
|
class CppConsumerPlugin : Plugin<Project> {
|
||||||
|
override fun apply(project: Project) {
|
||||||
|
project.dependencies.attributesSchema {
|
||||||
|
attribute(TargetWithSanitizer.TARGET_ATTRIBUTE) {
|
||||||
|
disambiguationRules.add(TargetDisambiguationRule::class.java)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
internal fun moduleCapability(project: Project, moduleName: String) = "${project.group}:${project.name}-${moduleName}:${project.version}"
|
||||||
|
internal fun testFixturesCapability(project: Project) = "${project.group}:${project.name}-test-fixtures:${project.version}"
|
||||||
|
internal fun moduleTestFixturesCapability(project: Project, moduleName: String) = "${project.group}:${project.name}-${moduleName}-test-fixtures:${project.version}"
|
||||||
|
internal fun testCapability(project: Project) = "${project.group}:${project.name}-test:${project.version}"
|
||||||
|
internal fun moduleTestCapability(project: Project, moduleName: String) = "${project.group}:${project.name}-${moduleName}-test:${project.version}"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
package org.jetbrains.kotlin.cpp
|
||||||
|
|
||||||
|
import org.gradle.api.attributes.Attribute
|
||||||
|
import org.gradle.api.attributes.Usage
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extending [Usage] constants for C++ projects.
|
||||||
|
*/
|
||||||
|
object CppUsage {
|
||||||
|
/**
|
||||||
|
* LLVM bitcode of a component.
|
||||||
|
*/
|
||||||
|
@JvmField
|
||||||
|
val LLVM_BITCODE = "llvm-bitcode"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* [JSON Compilation Database](https://clang.llvm.org/docs/JSONCompilationDatabase.html) of a component.
|
||||||
|
*/
|
||||||
|
@JvmField
|
||||||
|
val COMPILATION_DATABASE = "llvm-compilation-database"
|
||||||
|
|
||||||
|
@JvmField
|
||||||
|
val USAGE_ATTRIBUTE: Attribute<Usage> = Usage.USAGE_ATTRIBUTE
|
||||||
|
}
|
||||||
+44
@@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2022 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.cpp
|
||||||
|
|
||||||
|
import org.gradle.api.Project
|
||||||
|
import org.gradle.api.artifacts.ProjectDependency
|
||||||
|
import org.gradle.api.artifacts.dsl.DependencyHandler
|
||||||
|
import org.jetbrains.kotlin.bitcode.CompileToBitcodePlugin
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Depend on [CompileToBitcodePlugin]'s module named [moduleName] defined in [dependency].
|
||||||
|
*/
|
||||||
|
fun DependencyHandler.module(dependency: ProjectDependency, moduleName: String): ProjectDependency = dependency.copy().apply {
|
||||||
|
capabilities {
|
||||||
|
requireCapability(CppConsumerPlugin.moduleCapability(dependencyProject, moduleName))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Depend on [CompileToBitcodePlugin]'s module (testFixtures part) named [moduleName] defined in [dependency].
|
||||||
|
*/
|
||||||
|
fun DependencyHandler.moduleTestFixtures(dependency: ProjectDependency, moduleName: String): ProjectDependency = dependency.copy().apply {
|
||||||
|
capabilities {
|
||||||
|
requireCapability(CppConsumerPlugin.moduleTestFixturesCapability(dependencyProject, moduleName))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Depend on [CompileToBitcodePlugin]'s module (test part) named [moduleName] defined in [dependency].
|
||||||
|
*/
|
||||||
|
fun DependencyHandler.moduleTest(dependency: ProjectDependency, moduleName: String): ProjectDependency = dependency.copy().apply {
|
||||||
|
capabilities {
|
||||||
|
requireCapability(CppConsumerPlugin.moduleTestCapability(dependencyProject, moduleName))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Remove when .gradle is gone from K/N build.
|
||||||
|
fun DependencyHandler.module(project: Project, moduleName: String): ProjectDependency = module(
|
||||||
|
dependency = this.project(mapOf("path" to project.path)) as ProjectDependency,
|
||||||
|
moduleName
|
||||||
|
)
|
||||||
+27
-19
@@ -55,29 +55,37 @@ open class RuntimeTestingPlugin : Plugin<Project> {
|
|||||||
val bitcodeExtension = project.extensions.getByType<CompileToBitcodeExtension>()
|
val bitcodeExtension = project.extensions.getByType<CompileToBitcodeExtension>()
|
||||||
|
|
||||||
bitcodeExtension.allTargets {
|
bitcodeExtension.allTargets {
|
||||||
module("googletest", outputGroup = "test") {
|
module("googletest") {
|
||||||
inputFiles.from(googleTestRoot.resolve("googletest/src"))
|
sourceSets {
|
||||||
inputFiles.include("*.cc")
|
testFixtures {
|
||||||
inputFiles.exclude("gtest-all.cc", "gtest_main.cc")
|
inputFiles.from(googleTestRoot.resolve("googletest/src"))
|
||||||
headersDirs.from(
|
inputFiles.include("*.cc")
|
||||||
googleTestRoot.resolve("googletest/include"),
|
inputFiles.exclude("gtest-all.cc", "gtest_main.cc")
|
||||||
googleTestRoot.resolve("googletest")
|
headersDirs.setFrom(
|
||||||
)
|
googleTestRoot.resolve("googletest/include"),
|
||||||
|
googleTestRoot.resolve("googletest")
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
compilerArgs.set(listOf("-std=c++17", "-O2"))
|
compilerArgs.set(listOf("-std=c++17", "-O2"))
|
||||||
dependsOn(dependencies)
|
this.dependencies.addAll(dependencies)
|
||||||
}
|
}
|
||||||
|
|
||||||
module("googlemock", outputGroup = "test") {
|
module("googlemock") {
|
||||||
inputFiles.from(googleTestRoot.resolve("googlemock/src"))
|
sourceSets {
|
||||||
inputFiles.include("*.cc")
|
testFixtures {
|
||||||
inputFiles.exclude("gmock-all.cc", "gmock_main.cc")
|
inputFiles.from(googleTestRoot.resolve("googlemock/src"))
|
||||||
headersDirs.from(
|
inputFiles.include("*.cc")
|
||||||
googleTestRoot.resolve("googlemock"),
|
inputFiles.exclude("gmock-all.cc", "gmock_main.cc")
|
||||||
googleTestRoot.resolve("googlemock/include"),
|
headersDirs.setFrom(
|
||||||
googleTestRoot.resolve("googletest/include"),
|
googleTestRoot.resolve("googlemock"),
|
||||||
)
|
googleTestRoot.resolve("googlemock/include"),
|
||||||
|
googleTestRoot.resolve("googletest/include"),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
compilerArgs.set(listOf("-std=c++17", "-O2"))
|
compilerArgs.set(listOf("-std=c++17", "-O2"))
|
||||||
dependsOn(dependencies)
|
this.dependencies.addAll(dependencies)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,8 +20,8 @@ import org.jetbrains.kotlin.CopySamples
|
|||||||
import org.jetbrains.kotlin.CopyCommonSources
|
import org.jetbrains.kotlin.CopyCommonSources
|
||||||
import org.jetbrains.kotlin.PlatformInfo
|
import org.jetbrains.kotlin.PlatformInfo
|
||||||
import org.jetbrains.kotlin.KotlinBuildPusher
|
import org.jetbrains.kotlin.KotlinBuildPusher
|
||||||
import org.jetbrains.kotlin.bitcode.CompileToBitcodeExtension
|
|
||||||
import org.jetbrains.kotlin.cpp.CompilationDatabasePlugin
|
import org.jetbrains.kotlin.cpp.CompilationDatabasePlugin
|
||||||
|
import org.jetbrains.kotlin.cpp.CppUsage
|
||||||
import org.jetbrains.kotlin.cpp.GitClangFormatPlugin
|
import org.jetbrains.kotlin.cpp.GitClangFormatPlugin
|
||||||
import org.jetbrains.kotlin.CompareDistributionSignatures
|
import org.jetbrains.kotlin.CompareDistributionSignatures
|
||||||
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
|
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
|
||||||
@@ -146,7 +146,7 @@ configurations {
|
|||||||
canBeConsumed = false
|
canBeConsumed = false
|
||||||
canBeResolved = true
|
canBeResolved = true
|
||||||
attributes {
|
attributes {
|
||||||
attribute(Usage.USAGE_ATTRIBUTE, objects.named(Usage, CompileToBitcodeExtension.USAGE))
|
attribute(Usage.USAGE_ATTRIBUTE, objects.named(Usage, CppUsage.LLVM_BITCODE))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,9 +12,15 @@ bitcode {
|
|||||||
hostTarget {
|
hostTarget {
|
||||||
module("files") {
|
module("files") {
|
||||||
headersDirs.from(layout.projectDirectory.dir("src/files/headers"))
|
headersDirs.from(layout.projectDirectory.dir("src/files/headers"))
|
||||||
|
sourceSets {
|
||||||
|
main {}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
module("env") {
|
module("env") {
|
||||||
headersDirs.from(layout.projectDirectory.dir("src/env/headers"))
|
headersDirs.from(layout.projectDirectory.dir("src/env/headers"))
|
||||||
|
sourceSets {
|
||||||
|
main {}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
*/
|
*/
|
||||||
import org.jetbrains.kotlin.*
|
import org.jetbrains.kotlin.*
|
||||||
import org.jetbrains.kotlin.bitcode.CompileToBitcodeExtension
|
import org.jetbrains.kotlin.bitcode.CompileToBitcodeExtension
|
||||||
|
import org.jetbrains.kotlin.cpp.CppUsage
|
||||||
import org.jetbrains.kotlin.gradle.plugin.konan.tasks.KonanCacheTask
|
import org.jetbrains.kotlin.gradle.plugin.konan.tasks.KonanCacheTask
|
||||||
import org.jetbrains.kotlin.konan.properties.loadProperties
|
import org.jetbrains.kotlin.konan.properties.loadProperties
|
||||||
import org.jetbrains.kotlin.konan.properties.saveProperties
|
import org.jetbrains.kotlin.konan.properties.saveProperties
|
||||||
@@ -38,14 +39,28 @@ val targetList: List<String> by project
|
|||||||
bitcode {
|
bitcode {
|
||||||
allTargets {
|
allTargets {
|
||||||
module("main") {
|
module("main") {
|
||||||
// TODO: Split out out `base` module and merge it together with `main` into `runtime.bc`
|
sourceSets {
|
||||||
if (sanitizer == null) {
|
main {
|
||||||
outputFile.set(layout.buildDirectory.file("bitcode/main/$target/runtime.bc"))
|
// TODO: Split out out `base` module and merge it together with `main` into `runtime.bc`
|
||||||
|
if (sanitizer == null) {
|
||||||
|
outputFile.set(layout.buildDirectory.file("bitcode/main/$target/runtime.bc"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
testFixtures {}
|
||||||
|
test {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module("mimalloc") {
|
module("mimalloc") {
|
||||||
val srcRoot = file("src/mimalloc")
|
sourceSets {
|
||||||
|
main {
|
||||||
|
inputFiles.from(srcRoot.dir("c"))
|
||||||
|
inputFiles.include("**/*.c")
|
||||||
|
inputFiles.exclude("**/alloc-override*.c", "**/page-queue.c", "**/static.c", "**/bitmap.inc.c")
|
||||||
|
headersDirs.setFrom(srcRoot.dir("c/include"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
compiler.set("clang")
|
compiler.set("clang")
|
||||||
compilerArgs.set(listOfNotNull(
|
compilerArgs.set(listOfNotNull(
|
||||||
"-std=gnu11",
|
"-std=gnu11",
|
||||||
@@ -58,16 +73,11 @@ bitcode {
|
|||||||
"-Wno-unused-parameter", /* for windows 32 */
|
"-Wno-unused-parameter", /* for windows 32 */
|
||||||
"-DMI_TSAN=1".takeIf { sanitizer == SanitizerKind.THREAD },
|
"-DMI_TSAN=1".takeIf { sanitizer == SanitizerKind.THREAD },
|
||||||
))
|
))
|
||||||
inputFiles.from("$srcRoot/c")
|
|
||||||
inputFiles.include("**/*.c")
|
|
||||||
inputFiles.exclude("**/alloc-override*.c", "**/page-queue.c", "**/static.c", "**/bitmap.inc.c")
|
|
||||||
headersDirs.setFrom("$srcRoot/c/include")
|
|
||||||
|
|
||||||
onlyIf { targetSupportsMimallocAllocator(target.name) }
|
onlyIf { target.supportsMimallocAllocator() }
|
||||||
}
|
}
|
||||||
|
|
||||||
module("libbacktrace") {
|
module("libbacktrace") {
|
||||||
val srcRoot = file("src/libbacktrace")
|
|
||||||
val elfSize = when (target.architecture) {
|
val elfSize = when (target.architecture) {
|
||||||
TargetArchitecture.X64, TargetArchitecture.ARM64 -> 64
|
TargetArchitecture.X64, TargetArchitecture.ARM64 -> 64
|
||||||
TargetArchitecture.X86, TargetArchitecture.ARM32,
|
TargetArchitecture.X86, TargetArchitecture.ARM32,
|
||||||
@@ -76,6 +86,29 @@ bitcode {
|
|||||||
}
|
}
|
||||||
val useMachO = target.family.isAppleFamily
|
val useMachO = target.family.isAppleFamily
|
||||||
val useElf = target.family in listOf(Family.LINUX, Family.ANDROID)
|
val useElf = target.family in listOf(Family.LINUX, Family.ANDROID)
|
||||||
|
|
||||||
|
sourceSets {
|
||||||
|
main {
|
||||||
|
inputFiles.from(srcRoot.dir("c"))
|
||||||
|
inputFiles.include(listOfNotNull(
|
||||||
|
"atomic.c",
|
||||||
|
"backtrace.c",
|
||||||
|
"dwarf.c",
|
||||||
|
"elf.c".takeIf { useElf },
|
||||||
|
"fileline.c",
|
||||||
|
"macho.c".takeIf { useMachO },
|
||||||
|
"mmap.c",
|
||||||
|
"mmapio.c",
|
||||||
|
"posix.c",
|
||||||
|
"print.c",
|
||||||
|
"simple.c",
|
||||||
|
"sort.c",
|
||||||
|
"state.c"
|
||||||
|
))
|
||||||
|
headersDirs.setFrom(srcRoot.dir("c/include"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
compiler.set("clang")
|
compiler.set("clang")
|
||||||
compilerArgs.set(listOfNotNull(
|
compilerArgs.set(listOfNotNull(
|
||||||
"-std=gnu11",
|
"-std=gnu11",
|
||||||
@@ -92,117 +125,193 @@ bitcode {
|
|||||||
"-DBACKTRACE_ELF_SIZE=$elfSize".takeIf { useElf },
|
"-DBACKTRACE_ELF_SIZE=$elfSize".takeIf { useElf },
|
||||||
"-Wno-atomic-alignment"
|
"-Wno-atomic-alignment"
|
||||||
))
|
))
|
||||||
inputFiles.from("$srcRoot/c")
|
|
||||||
inputFiles.include(listOfNotNull(
|
|
||||||
"atomic.c",
|
|
||||||
"backtrace.c",
|
|
||||||
"dwarf.c",
|
|
||||||
"elf.c".takeIf { useElf },
|
|
||||||
"fileline.c",
|
|
||||||
"macho.c".takeIf { useMachO },
|
|
||||||
"mmap.c",
|
|
||||||
"mmapio.c",
|
|
||||||
"posix.c",
|
|
||||||
"print.c",
|
|
||||||
"simple.c",
|
|
||||||
"sort.c",
|
|
||||||
"state.c"
|
|
||||||
))
|
|
||||||
headersDirs.setFrom("$srcRoot/c/include")
|
|
||||||
|
|
||||||
onlyIf { targetSupportsLibBacktrace(target.name) }
|
onlyIf { target.supportsLibBacktrace() }
|
||||||
}
|
}
|
||||||
|
|
||||||
module("compiler_interface") {
|
module("compiler_interface") {
|
||||||
headersDirs.from(files("src/main/cpp"))
|
headersDirs.from(files("src/main/cpp"))
|
||||||
|
sourceSets {
|
||||||
|
main {}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module("launcher") {
|
module("launcher") {
|
||||||
headersDirs.from(files("src/main/cpp"))
|
headersDirs.from(files("src/main/cpp"))
|
||||||
|
sourceSets {
|
||||||
|
main {}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module("debug") {
|
module("debug") {
|
||||||
headersDirs.from(files("src/main/cpp"))
|
headersDirs.from(files("src/main/cpp"))
|
||||||
|
sourceSets {
|
||||||
|
main {}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module("std_alloc") {
|
module("std_alloc") {
|
||||||
headersDirs.from(files("src/main/cpp"))
|
headersDirs.from(files("src/main/cpp"))
|
||||||
|
sourceSets {
|
||||||
|
main {}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module("custom_alloc") {
|
module("custom_alloc") {
|
||||||
headersDirs.from(files("src/main/cpp", "src/mm/cpp", "src/gc/common/cpp", "src/gc/cms/cpp"))
|
headersDirs.from(files("src/main/cpp", "src/mm/cpp", "src/gc/common/cpp", "src/gc/cms/cpp"))
|
||||||
|
sourceSets {
|
||||||
|
main {}
|
||||||
|
test {}
|
||||||
|
}
|
||||||
|
|
||||||
compilerArgs.add("-DCUSTOM_ALLOCATOR")
|
compilerArgs.add("-DCUSTOM_ALLOCATOR")
|
||||||
|
|
||||||
// Directly depends on cms which is only supported with threads.
|
// Directly depends on cms which is only supported with threads.
|
||||||
onlyIf { targetSupportsThreads(target.name) }
|
onlyIf { target.supportsThreads() }
|
||||||
}
|
}
|
||||||
|
|
||||||
module("opt_alloc") {
|
module("opt_alloc") {
|
||||||
headersDirs.from(files("src/main/cpp"))
|
headersDirs.from(files("src/main/cpp"))
|
||||||
|
sourceSets {
|
||||||
|
main {}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module("exceptionsSupport", file("src/exceptions_support")) {
|
module("exceptionsSupport") {
|
||||||
|
srcRoot.set(layout.projectDirectory.dir("src/exceptions_support"))
|
||||||
headersDirs.from(files("src/main/cpp"))
|
headersDirs.from(files("src/main/cpp"))
|
||||||
|
sourceSets {
|
||||||
|
main {}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module("source_info_core_symbolication", file("src/source_info/core_symbolication")) {
|
module("source_info_core_symbolication") {
|
||||||
|
srcRoot.set(layout.projectDirectory.dir("src/source_info/core_symbolication"))
|
||||||
headersDirs.from(files("src/main/cpp"))
|
headersDirs.from(files("src/main/cpp"))
|
||||||
onlyIf { targetSupportsCoreSymbolication(target.name) }
|
sourceSets {
|
||||||
|
main {}
|
||||||
|
}
|
||||||
|
|
||||||
|
onlyIf { target.supportsCoreSymbolication() }
|
||||||
}
|
}
|
||||||
module("source_info_libbacktrace", file("src/source_info/libbacktrace")) {
|
module("source_info_libbacktrace") {
|
||||||
|
srcRoot.set(layout.projectDirectory.dir("src/source_info/libbacktrace"))
|
||||||
headersDirs.from(files("src/main/cpp", "src/libbacktrace/c/include"))
|
headersDirs.from(files("src/main/cpp", "src/libbacktrace/c/include"))
|
||||||
onlyIf { targetSupportsLibBacktrace(target.name) }
|
sourceSets {
|
||||||
|
main {}
|
||||||
|
}
|
||||||
|
|
||||||
|
onlyIf { target.supportsLibBacktrace() }
|
||||||
}
|
}
|
||||||
|
|
||||||
module("strict") {
|
module("strict") {
|
||||||
headersDirs.from(files("src/main/cpp"))
|
headersDirs.from(files("src/main/cpp"))
|
||||||
|
sourceSets {
|
||||||
|
main {}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module("relaxed") {
|
module("relaxed") {
|
||||||
headersDirs.from(files("src/main/cpp"))
|
headersDirs.from(files("src/main/cpp"))
|
||||||
|
sourceSets {
|
||||||
|
main {}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module("profileRuntime", file("src/profile_runtime"))
|
module("profileRuntime") {
|
||||||
|
srcRoot.set(layout.projectDirectory.dir("src/profile_runtime"))
|
||||||
|
sourceSets {
|
||||||
|
main {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
module("objc") {
|
module("objc") {
|
||||||
headersDirs.from(files("src/main/cpp"))
|
headersDirs.from(files("src/main/cpp"))
|
||||||
|
sourceSets {
|
||||||
|
main {}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module("test_support", outputGroup = "test") {
|
module("test_support") {
|
||||||
headersDirs.from(files("src/main/cpp"), googletest.headersDirs)
|
|
||||||
dependsOn("downloadGoogleTest")
|
|
||||||
}
|
|
||||||
|
|
||||||
module("legacy_memory_manager", file("src/legacymm")) {
|
|
||||||
headersDirs.from(files("src/main/cpp"))
|
headersDirs.from(files("src/main/cpp"))
|
||||||
|
sourceSets {
|
||||||
|
testFixtures {
|
||||||
|
inputFiles.include("**/*.cpp", "**/*.mm")
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module("experimental_memory_manager", file("src/mm")) {
|
module("legacy_memory_manager") {
|
||||||
|
srcRoot.set(layout.projectDirectory.dir("src/legacymm"))
|
||||||
|
headersDirs.from(files("src/main/cpp"))
|
||||||
|
sourceSets {
|
||||||
|
main {}
|
||||||
|
testFixtures {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module("experimental_memory_manager") {
|
||||||
|
srcRoot.set(layout.projectDirectory.dir("src/mm"))
|
||||||
headersDirs.from(files("src/gc/common/cpp", "src/main/cpp"))
|
headersDirs.from(files("src/gc/common/cpp", "src/main/cpp"))
|
||||||
|
sourceSets {
|
||||||
|
main {}
|
||||||
|
testFixtures {}
|
||||||
|
test {}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module("common_gc", file("src/gc/common")) {
|
module("common_gc") {
|
||||||
|
srcRoot.set(layout.projectDirectory.dir("src/gc/common"))
|
||||||
headersDirs.from(files("src/mm/cpp", "src/main/cpp"))
|
headersDirs.from(files("src/mm/cpp", "src/main/cpp"))
|
||||||
|
sourceSets {
|
||||||
|
main {}
|
||||||
|
test {}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module("noop_gc", file("src/gc/noop")) {
|
module("noop_gc") {
|
||||||
|
srcRoot.set(layout.projectDirectory.dir("src/gc/noop"))
|
||||||
headersDirs.from(files("src/gc/noop/cpp", "src/gc/common/cpp", "src/mm/cpp", "src/main/cpp"))
|
headersDirs.from(files("src/gc/noop/cpp", "src/gc/common/cpp", "src/mm/cpp", "src/main/cpp"))
|
||||||
|
sourceSets {
|
||||||
|
main {}
|
||||||
|
testFixtures {}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module("same_thread_ms_gc", file("src/gc/stms")) {
|
module("same_thread_ms_gc") {
|
||||||
|
srcRoot.set(layout.projectDirectory.dir("src/gc/stms"))
|
||||||
headersDirs.from(files("src/gc/stms/cpp", "src/gc/common/cpp", "src/mm/cpp", "src/main/cpp"))
|
headersDirs.from(files("src/gc/stms/cpp", "src/gc/common/cpp", "src/mm/cpp", "src/main/cpp"))
|
||||||
|
sourceSets {
|
||||||
|
main {}
|
||||||
|
testFixtures {}
|
||||||
|
test {}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module("concurrent_ms_gc", file("src/gc/cms")) {
|
module("concurrent_ms_gc") {
|
||||||
|
srcRoot.set(layout.projectDirectory.dir("src/gc/cms"))
|
||||||
headersDirs.from(files("src/gc/cms/cpp", "src/gc/common/cpp", "src/mm/cpp", "src/main/cpp"))
|
headersDirs.from(files("src/gc/cms/cpp", "src/gc/common/cpp", "src/mm/cpp", "src/main/cpp"))
|
||||||
|
sourceSets {
|
||||||
|
main {}
|
||||||
|
testFixtures {}
|
||||||
|
test {}
|
||||||
|
}
|
||||||
|
|
||||||
onlyIf { targetSupportsThreads(target.name) }
|
onlyIf { target.supportsThreads() }
|
||||||
}
|
}
|
||||||
|
|
||||||
module("concurrent_ms_gc_custom", file("src/gc/cms")) {
|
module("concurrent_ms_gc_custom") {
|
||||||
|
srcRoot.set(layout.projectDirectory.dir("src/gc/cms"))
|
||||||
headersDirs.from(files("src/gc/cms/cpp", "src/gc/common/cpp", "src/mm/cpp", "src/main/cpp", "src/custom_alloc/cpp"))
|
headersDirs.from(files("src/gc/cms/cpp", "src/gc/common/cpp", "src/mm/cpp", "src/main/cpp", "src/custom_alloc/cpp"))
|
||||||
|
sourceSets {
|
||||||
|
main {}
|
||||||
|
testFixtures {}
|
||||||
|
test {}
|
||||||
|
}
|
||||||
|
|
||||||
compilerArgs.add("-DCUSTOM_ALLOCATOR")
|
compilerArgs.add("-DCUSTOM_ALLOCATOR")
|
||||||
|
|
||||||
onlyIf { targetSupportsThreads(target.name) }
|
onlyIf { target.supportsThreads() }
|
||||||
}
|
}
|
||||||
|
|
||||||
testsGroup("std_alloc_runtime_tests") {
|
testsGroup("std_alloc_runtime_tests") {
|
||||||
@@ -248,7 +357,7 @@ val runtimeBitcode by configurations.creating {
|
|||||||
isCanBeConsumed = false
|
isCanBeConsumed = false
|
||||||
isCanBeResolved = true
|
isCanBeResolved = true
|
||||||
attributes {
|
attributes {
|
||||||
attribute(Usage.USAGE_ATTRIBUTE, objects.named(CompileToBitcodeExtension.USAGE))
|
attribute(CppUsage.USAGE_ATTRIBUTE, objects.named(CppUsage.LLVM_BITCODE))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user