Make ClangFrontend cacheable
Co-authored-by: Alexander Shabalin <Alexander.Shabalin@jetbrains.com> Merge-request: KT-MR-11479 Merged-by: Cristian Garcia <Cristian.Garcia-Marin@jetbrains.com>
This commit is contained in:
committed by
Space Team
parent
b3e13fb2c2
commit
03ad981dea
+39
-20
@@ -11,6 +11,7 @@ import org.gradle.api.model.ObjectFactory
|
||||
import org.gradle.api.provider.ListProperty
|
||||
import org.gradle.api.provider.Property
|
||||
import org.gradle.api.provider.Provider
|
||||
import org.gradle.api.provider.ProviderFactory
|
||||
import org.gradle.api.tasks.*
|
||||
import org.gradle.kotlin.dsl.getByType
|
||||
import org.gradle.workers.WorkAction
|
||||
@@ -18,6 +19,8 @@ import org.gradle.workers.WorkParameters
|
||||
import org.gradle.workers.WorkerExecutor
|
||||
import org.jetbrains.kotlin.ExecClang
|
||||
import org.jetbrains.kotlin.bitcode.CompileToBitcodePlugin
|
||||
import org.jetbrains.kotlin.konan.target.Family
|
||||
import org.jetbrains.kotlin.konan.target.HostManager
|
||||
import org.jetbrains.kotlin.konan.target.PlatformManager
|
||||
import java.io.File
|
||||
import javax.inject.Inject
|
||||
@@ -57,13 +60,19 @@ private abstract class ClangFrontendJob : WorkAction<ClangFrontendJob.Parameters
|
||||
*
|
||||
* @see CompileToBitcodePlugin
|
||||
*/
|
||||
abstract class ClangFrontend : DefaultTask() {
|
||||
@CacheableTask
|
||||
abstract class ClangFrontend @Inject constructor(
|
||||
private val workerExecutor: WorkerExecutor,
|
||||
private val objects: ObjectFactory,
|
||||
private val layout: ProjectLayout,
|
||||
providers: ProviderFactory,
|
||||
) : DefaultTask() {
|
||||
private data class WorkUnit(
|
||||
val inputFile: File,
|
||||
val outputFile: File,
|
||||
)
|
||||
|
||||
private val workUnits: Provider<List<WorkUnit>> = project.provider {
|
||||
private val workUnits: Provider<List<WorkUnit>> = providers.provider {
|
||||
val result = mutableListOf<WorkUnit>()
|
||||
inputFiles.visit {
|
||||
if (!isDirectory) {
|
||||
@@ -87,13 +96,14 @@ abstract class ClangFrontend : DefaultTask() {
|
||||
*/
|
||||
@get:SkipWhenEmpty
|
||||
@get:InputFiles
|
||||
@get:PathSensitive(PathSensitivity.RELATIVE)
|
||||
abstract val inputFiles: ConfigurableFileTree
|
||||
|
||||
/**
|
||||
* Bitcode files generated by clang.
|
||||
*/
|
||||
@get:OutputFiles
|
||||
val outputFiles: FileCollection = project.files(workUnits.map { it.map { workUnit -> workUnit.outputFile } })
|
||||
val outputFiles: FileCollection = layout.files(workUnits.map { it.map { workUnit -> workUnit.outputFile } })
|
||||
|
||||
/**
|
||||
* Will select the appropriate compiler and additional flags.
|
||||
@@ -108,13 +118,12 @@ abstract class ClangFrontend : DefaultTask() {
|
||||
* Currently only `clang` and `clang++` are supported.
|
||||
*/
|
||||
@get:Input
|
||||
abstract val compiler: Property<String>
|
||||
val compiler: Property<String> = objects.property(String::class.java)
|
||||
|
||||
/**
|
||||
* Extra arguments for [compiler].
|
||||
*/
|
||||
// Marked as input via [compilerFlags].
|
||||
@get:Internal
|
||||
@get:Input
|
||||
abstract val arguments: ListProperty<String>
|
||||
|
||||
/**
|
||||
@@ -122,15 +131,16 @@ abstract class ClangFrontend : DefaultTask() {
|
||||
*
|
||||
* Will be passed to the compiler as `-I…` and will also be used to compute task dependencies: recompile if the headers change.
|
||||
*/
|
||||
// Marked as input via [headers] and [compilerFlags].
|
||||
// Marked as input via [headers].
|
||||
@get:Internal
|
||||
abstract val headersDirs: ConfigurableFileCollection
|
||||
|
||||
/**
|
||||
* Final computed compiler arguments.
|
||||
*/
|
||||
@get:Input
|
||||
val compilerFlags: Provider<List<String>> = project.provider {
|
||||
// Marked as input via [headers] and [arguments].
|
||||
@get:Internal
|
||||
val compilerFlags: Provider<List<String>> = providers.provider {
|
||||
listOfNotNull(
|
||||
"-c",
|
||||
"-emit-llvm"
|
||||
@@ -143,18 +153,19 @@ abstract class ClangFrontend : DefaultTask() {
|
||||
* All inputs will be passed to the compiler as relative paths to this directory.
|
||||
*/
|
||||
@get:Internal
|
||||
abstract val workingDirectory: DirectoryProperty
|
||||
val workingDirectory: DirectoryProperty = objects.directoryProperty()
|
||||
|
||||
@get:Input
|
||||
protected val workingDirectoryPath: Provider<String> = project.provider {
|
||||
workingDirectory.get().asFile.absolutePath
|
||||
protected val workingDirectoryPath: Provider<String> = workingDirectory.map {
|
||||
it.asFile.toRelativeString(layout.projectDirectory.asFile)
|
||||
}
|
||||
|
||||
/**
|
||||
* Computed header files used for task dependencies tracking.
|
||||
*/
|
||||
@get:InputFiles
|
||||
protected val headers: Provider<List<File>> = project.provider {
|
||||
@get:PathSensitive(PathSensitivity.RELATIVE)
|
||||
protected val headers: Provider<FileTree> = providers.provider {
|
||||
// Not using clang's -M* flags because there's a problem with our current include system:
|
||||
// We allow includes relative to the current directory and also pass -I for each imported module
|
||||
// Given file tree:
|
||||
@@ -177,17 +188,25 @@ abstract class ClangFrontend : DefaultTask() {
|
||||
}
|
||||
// Now add manually given header dirs.
|
||||
dirs.addAll(headersDirs.files)
|
||||
dirs.flatMap { dir ->
|
||||
project.fileTree(dir) {
|
||||
include("**/*.h", "**/*.hpp")
|
||||
}.files
|
||||
layout.files(dirs).asFileTree.matching {
|
||||
include("**/*.h", "**/*.hpp")
|
||||
}
|
||||
}
|
||||
|
||||
@get:Inject
|
||||
protected abstract val workerExecutor: WorkerExecutor
|
||||
|
||||
private val platformManager = project.extensions.getByType<PlatformManager>()
|
||||
private val execClang by lazy { ExecClang.create(objects, platformManager) }
|
||||
|
||||
// TODO: Consider configuring full clang execution from the plugin instead.
|
||||
@get:InputFile
|
||||
@get:PathSensitive(PathSensitivity.NONE)
|
||||
val executable: Provider<RegularFile> = layout.file(compiler.map {
|
||||
val executable = execClang.resolveExecutable(it)
|
||||
val executableSuffix = when (HostManager.host.family) {
|
||||
Family.MINGW -> ".exe"
|
||||
else -> ""
|
||||
}
|
||||
File("$executable$executableSuffix")
|
||||
})
|
||||
|
||||
@TaskAction
|
||||
fun compile() {
|
||||
|
||||
Reference in New Issue
Block a user