[Runtime testing] Fix link errors caused by duplicated symbol __throw_length_error
This commit is contained in:
committed by
Ilya Matveev
parent
a452346385
commit
788dd1c210
@@ -9,6 +9,7 @@ import groovy.lang.Closure
|
|||||||
import java.io.File
|
import java.io.File
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import org.gradle.api.*
|
import org.gradle.api.*
|
||||||
|
import org.gradle.api.file.ConfigurableFileCollection
|
||||||
import org.gradle.api.tasks.*
|
import org.gradle.api.tasks.*
|
||||||
import org.jetbrains.kotlin.ExecClang
|
import org.jetbrains.kotlin.ExecClang
|
||||||
import org.jetbrains.kotlin.bitcode.CompileToBitcode
|
import org.jetbrains.kotlin.bitcode.CompileToBitcode
|
||||||
@@ -17,7 +18,7 @@ import org.jetbrains.kotlin.konan.target.*
|
|||||||
open class CompileNativeTest @Inject constructor(
|
open class CompileNativeTest @Inject constructor(
|
||||||
@InputFile val inputFile: File,
|
@InputFile val inputFile: File,
|
||||||
@Input val target: String
|
@Input val target: String
|
||||||
) : DefaultTask () {
|
) : DefaultTask() {
|
||||||
@OutputFile
|
@OutputFile
|
||||||
var outputFile = project.buildDir.resolve("bin/test/$target/${inputFile.nameWithoutExtension}.o")
|
var outputFile = project.buildDir.resolve("bin/test/$target/${inputFile.nameWithoutExtension}.o")
|
||||||
|
|
||||||
@@ -27,10 +28,54 @@ open class CompileNativeTest @Inject constructor(
|
|||||||
@TaskAction
|
@TaskAction
|
||||||
fun compile() {
|
fun compile() {
|
||||||
val plugin = project.convention.getPlugin(ExecClang::class.java)
|
val plugin = project.convention.getPlugin(ExecClang::class.java)
|
||||||
plugin.execBareClang(Action {
|
plugin.execBareClang {
|
||||||
it.executable = "clang++"
|
it.executable = "clang++"
|
||||||
it.args = clangArgs + listOf(inputFile.absolutePath, "-o", outputFile.absolutePath)
|
it.args = clangArgs + listOf(inputFile.absolutePath, "-o", outputFile.absolutePath)
|
||||||
})
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
open class LlvmLinkNativeTest @Inject constructor(
|
||||||
|
val baseName: String,
|
||||||
|
@Input val target: String,
|
||||||
|
@InputFile val mainFile: File
|
||||||
|
) : DefaultTask() {
|
||||||
|
|
||||||
|
@SkipWhenEmpty
|
||||||
|
@InputFiles
|
||||||
|
var inputFiles: ConfigurableFileCollection = project.files()
|
||||||
|
|
||||||
|
@OutputFile
|
||||||
|
var outputFile: File = project.buildDir.resolve("bitcode/test/$target/$baseName.bc")
|
||||||
|
|
||||||
|
@TaskAction
|
||||||
|
fun llvmLink() {
|
||||||
|
val llvmDir = project.property("llvmDir")
|
||||||
|
val tmpOutput = File.createTempFile("runtimeTests", ".bc").apply {
|
||||||
|
deleteOnExit()
|
||||||
|
}
|
||||||
|
|
||||||
|
// The runtime provides our implementations for some standard functions (see StdCppStubs.cpp).
|
||||||
|
// We need to internalize these symbols to avoid clashes with symbols provided by the C++ stdlib.
|
||||||
|
// But llvm-link -internalize is kinda broken: it links modules one by one and can't see usages
|
||||||
|
// of a symbol in subsequent modules. So it will mangle such symbols causing "unresolved symbol"
|
||||||
|
// errors at the link stage. So we have to run llvm-link twice: the first one links all modules
|
||||||
|
// except the one containing the entry point to a single *.bc without internalization. The second
|
||||||
|
// run internalizes this big module and links it with a module containing the entry point.
|
||||||
|
project.exec {
|
||||||
|
it.executable = "$llvmDir/bin/llvm-link"
|
||||||
|
it.args = listOf("-o", tmpOutput.absolutePath) + inputFiles.map { it.absolutePath }
|
||||||
|
}
|
||||||
|
|
||||||
|
project.exec {
|
||||||
|
it.executable = "$llvmDir/bin/llvm-link"
|
||||||
|
it.args = listOf(
|
||||||
|
"-o", outputFile.absolutePath,
|
||||||
|
mainFile.absolutePath,
|
||||||
|
tmpOutput.absolutePath,
|
||||||
|
"-internalize"
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -106,15 +151,6 @@ open class LinkNativeTest @Inject constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
|
||||||
private fun <T: Task> T.configure(f: T.() -> Unit): T =
|
|
||||||
this.configure(object: Closure<Unit>(this) {
|
|
||||||
// Dynamically invoked by Groovy
|
|
||||||
fun doCall() {
|
|
||||||
f()
|
|
||||||
}
|
|
||||||
}) as T
|
|
||||||
|
|
||||||
fun createTestTask(
|
fun createTestTask(
|
||||||
project: Project,
|
project: Project,
|
||||||
testTaskName: String,
|
testTaskName: String,
|
||||||
@@ -137,7 +173,7 @@ fun createTestTask(
|
|||||||
it.srcRoot,
|
it.srcRoot,
|
||||||
"${it.folderName}Tests",
|
"${it.folderName}Tests",
|
||||||
target, "test"
|
target, "test"
|
||||||
).configure {
|
).apply {
|
||||||
excludeFiles = emptyList()
|
excludeFiles = emptyList()
|
||||||
includeFiles = listOf("**/*Test.cpp", "**/*Test.mm")
|
includeFiles = listOf("**/*Test.cpp", "**/*Test.mm")
|
||||||
dependsOn(it)
|
dependsOn(it)
|
||||||
@@ -153,29 +189,42 @@ fun createTestTask(
|
|||||||
project.tasks.getByName("${target}Googletest") as CompileToBitcode,
|
project.tasks.getByName("${target}Googletest") as CompileToBitcode,
|
||||||
project.tasks.getByName("${target}Googlemock") as CompileToBitcode
|
project.tasks.getByName("${target}Googlemock") as CompileToBitcode
|
||||||
)
|
)
|
||||||
val compileToObjectFileTasks = (compileToBitcodeTasks + testedTasks + testFrameworkTasks).map {
|
|
||||||
val name = "${it.name}Object"
|
val testSupportTask = project.tasks.getByName("${target}TestSupport") as CompileToBitcode
|
||||||
val clangFlags = platformManager.platform(konanTarget).configurables as ClangFlags
|
|
||||||
project.tasks.findByName(name) as? CompileNativeTest ?:
|
// TODO: It may make sense to merge llvm-link, compile and link to a single task.
|
||||||
project.tasks.create(name,
|
val llvmLinkTask = project.tasks.create(
|
||||||
CompileNativeTest::class.java,
|
"${testTaskName}LlvmLink",
|
||||||
it.outFile,
|
LlvmLinkNativeTest::class.java,
|
||||||
target
|
testTaskName, target, testSupportTask.outFile
|
||||||
).configure {
|
).apply {
|
||||||
dependsOn(it)
|
val tasksToLink = (compileToBitcodeTasks + testedTasks + testFrameworkTasks)
|
||||||
clangArgs.addAll(clangFlags.clangFlags)
|
inputFiles = project.files(tasksToLink.map { it.outFile })
|
||||||
clangArgs.addAll(clangFlags.clangNooptFlags)
|
dependsOn(testSupportTask)
|
||||||
}
|
dependsOn(tasksToLink)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val clangFlags = platformManager.platform(konanTarget).configurables as ClangFlags
|
||||||
|
val compileTask = project.tasks.create(
|
||||||
|
"${testTaskName}Compile",
|
||||||
|
CompileNativeTest::class.java,
|
||||||
|
llvmLinkTask.outputFile,
|
||||||
|
target
|
||||||
|
).apply {
|
||||||
|
dependsOn(llvmLinkTask)
|
||||||
|
clangArgs.addAll(clangFlags.clangFlags)
|
||||||
|
clangArgs.addAll(clangFlags.clangNooptFlags)
|
||||||
|
}
|
||||||
|
|
||||||
val linkTask = LinkNativeTest.create(
|
val linkTask = LinkNativeTest.create(
|
||||||
project,
|
project,
|
||||||
platformManager,
|
platformManager,
|
||||||
"${testTaskName}Link",
|
"${testTaskName}Link",
|
||||||
compileToObjectFileTasks.map { it.outputFile },
|
listOf(compileTask.outputFile),
|
||||||
target,
|
target,
|
||||||
testTaskName
|
testTaskName
|
||||||
).configure {
|
).apply {
|
||||||
dependsOn(compileToObjectFileTasks)
|
dependsOn(compileTask)
|
||||||
}
|
}
|
||||||
|
|
||||||
return project.tasks.create(testTaskName, Exec::class.java).apply {
|
return project.tasks.create(testTaskName, Exec::class.java).apply {
|
||||||
|
|||||||
@@ -100,7 +100,6 @@ targetList.forEach { targetName ->
|
|||||||
"${targetName}StdAllocRuntimeTests",
|
"${targetName}StdAllocRuntimeTests",
|
||||||
listOf(
|
listOf(
|
||||||
"${targetName}Runtime",
|
"${targetName}Runtime",
|
||||||
"${targetName}TestSupport",
|
|
||||||
"${targetName}Strict",
|
"${targetName}Strict",
|
||||||
"${targetName}Release",
|
"${targetName}Release",
|
||||||
"${targetName}StdAlloc"
|
"${targetName}StdAlloc"
|
||||||
@@ -112,7 +111,6 @@ targetList.forEach { targetName ->
|
|||||||
"${targetName}MimallocRuntimeTests",
|
"${targetName}MimallocRuntimeTests",
|
||||||
listOf(
|
listOf(
|
||||||
"${targetName}Runtime",
|
"${targetName}Runtime",
|
||||||
"${targetName}TestSupport",
|
|
||||||
"${targetName}Strict",
|
"${targetName}Strict",
|
||||||
"${targetName}Release",
|
"${targetName}Release",
|
||||||
"${targetName}Mimalloc",
|
"${targetName}Mimalloc",
|
||||||
|
|||||||
Reference in New Issue
Block a user