[K/N] Compile each cpp file separately.

Merge-request: KT-MR-6711
Merged-by: Alexander Shabalin <Alexander.Shabalin@jetbrains.com>
This commit is contained in:
Alexander Shabalin
2022-08-01 14:13:22 +00:00
committed by Space
parent 9b925efdaf
commit 8b2f761c75
3 changed files with 53 additions and 15 deletions
@@ -29,6 +29,11 @@ import org.jetbrains.kotlin.utils.Maybe
import java.io.File
import javax.inject.Inject
private data class CompilerWorkUnit(
val input: File,
val output: File,
) : java.io.Serializable
private abstract class CompileToBitcodeJob : WorkAction<CompileToBitcodeJob.Parameters> {
interface Parameters : WorkParameters {
val workingDirectory: DirectoryProperty
@@ -36,7 +41,7 @@ private abstract class CompileToBitcodeJob : WorkAction<CompileToBitcodeJob.Para
// so object identity matters, and platform managers are different between project and worker sides.
val targetName: Property<String>
val compilerExecutable: Property<String>
val compilerInputFiles: ConfigurableFileCollection
val compilerWorkUnits: ListProperty<CompilerWorkUnit>
val compilerArgs: ListProperty<String>
val llvmLinkOutputFile: RegularFileProperty
val llvmLinkArgs: ListProperty<String>
@@ -51,22 +56,23 @@ private abstract class CompileToBitcodeJob : WorkAction<CompileToBitcodeJob.Para
override fun execute() {
with(parameters) {
workingDirectory.asFile.get().mkdirs()
val execClang = ExecClang.create(objects, platformManager.get())
// TODO: Compile each input separately and make workingDir point to src root.
execClang.execKonanClang(targetName.get()) {
workingDir = workingDirectory.asFile.get()
executable = compilerExecutable.get()
args = compilerArgs.get() + compilerInputFiles.map { it.absolutePath }
}
val baseDir = workingDirectory.asFile.get()
val compilerOutputFiles = compilerInputFiles.map { workingDirectory.file("${it.nameWithoutExtension}.bc").get().asFile }
compilerWorkUnits.get().forEach { workUnit ->
workUnit.output.parentFile.mkdirs()
val inputRelativePath = baseDir.toPath().relativize(workUnit.input.toPath())
execClang.execKonanClang(targetName.get()) {
workingDir = baseDir
executable = compilerExecutable.get()
args = compilerArgs.get() + listOf(inputRelativePath.toString(), "-o", workUnit.output.absolutePath)
}
}
// TODO: Extract llvm-link out. This will allow parallelizing clang compilation.
execOperations.execLlvmUtility(platformManager.get(), "llvm-link") {
args = listOf("-o", llvmLinkOutputFile.asFile.get().absolutePath) + llvmLinkArgs.get() + compilerOutputFiles.map { it.absolutePath }
args = listOf("-o", llvmLinkOutputFile.asFile.get().absolutePath) + llvmLinkArgs.get() + compilerWorkUnits.get().map { it.output.absolutePath }
}
}
}
@@ -102,7 +108,6 @@ abstract class CompileToBitcode @Inject constructor(
/**
* Where to put bitcode files generated by clang.
*/
// TODO: Generate output files for this.
@get:Internal
abstract val outputDirectory: DirectoryProperty
@@ -162,6 +167,37 @@ abstract class CompileToBitcode @Inject constructor(
@get:InputFiles
abstract val inputFiles: ConfigurableFileTree
/**
* Working directory for the compiler.
*
* All inputs will be passed to the compiler as relative paths to this directory.
*/
@get:Internal
abstract val compilerWorkingDirectory: DirectoryProperty
@get:Input
protected val compilerWorkingDirectoryPath: Provider<String> = project.provider {
compilerWorkingDirectory.get().asFile.absolutePath
}
private val compilerWorkUnits: Provider<List<CompilerWorkUnit>> = project.provider {
val workUnits = mutableListOf<CompilerWorkUnit>()
inputFiles.visit {
if (!isDirectory) {
val output = outputDirectory.file(relativePath.parent.append(true, "${file.nameWithoutExtension}.bc").pathString)
workUnits.add(CompilerWorkUnit(file, output.get().asFile))
}
}
workUnits
}
/**
* Output files from the [compiler].
*/
// TODO: Make it OutputFiles. Currently clashes with `kotlinNativeInterop` `linkOutputs` in kotlin-native/backend.native/build.gradle Can be fixed when the task is split into clang and llvm-link.
@get:Internal
val compilerOutputFiles = compilerWorkUnits.map { it.map { it.output } }
/**
* Computed header files used for task dependencies tracking.
*/
@@ -206,11 +242,11 @@ abstract class CompileToBitcode @Inject constructor(
val workQueue = workerExecutor.noIsolation()
workQueue.submit(CompileToBitcodeJob::class.java) {
workingDirectory.set(this@CompileToBitcode.outputDirectory)
workingDirectory.set(this@CompileToBitcode.compilerWorkingDirectory)
targetName.set(this@CompileToBitcode.target.name)
compilerExecutable.set(this@CompileToBitcode.compiler)
compilerArgs.set(this@CompileToBitcode.compilerFlags)
compilerInputFiles.from(this@CompileToBitcode.inputFiles)
compilerWorkUnits.set(this@CompileToBitcode.compilerWorkUnits)
llvmLinkOutputFile.set(this@CompileToBitcode.outputFile)
llvmLinkArgs.set(this@CompileToBitcode.linkerArgs)
platformManager.set(this@CompileToBitcode.platformManager)
@@ -110,7 +110,7 @@ open class CompileToBitcodeExtension @Inject constructor(val project: Project) {
compilationDatabase.target(konanTarget) {
entry {
val args = listOf(execClang.resolveExecutable(compileTask.compiler.get())) + compileTask.compilerFlags.get() + execClang.clangArgsForCppRuntime(konanTarget.name)
directory.set(compileTask.outputDirectory)
directory.set(compileTask.compilerWorkingDirectory)
files.setFrom(compileTask.inputFiles)
arguments.set(args)
output.set(compileTask.outputFile.asFile.map { it.absolutePath })
@@ -135,6 +135,7 @@ open class CompileToBitcodeExtension @Inject constructor(val project: Project) {
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
@@ -188,6 +189,7 @@ open class CompileToBitcodeExtension @Inject constructor(val project: Project) {
this.inputFiles.include("**/*Test.cpp", "**/*TestSupport.cpp", "**/*Test.mm", "**/*TestSupport.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}"