mirror of
https://github.com/jlengrand/kotlin.git
synced 2026-03-10 08:31:29 +00:00
[K/N] Use LLD 12.0.1 for MinGW targets
Clang-produced and GCC-produced binaries might be ABI-incompatible on MinGW. Explanation on GitHub: msys2/MINGW-packages/issues/6855#issuecomment-680859662. TL;DR: GCC-generated sections are 16-byte-padded, while Clang ones are not. It causes problems during merge of COMDAT sections. I observed the problem during compilation of runtime tests, but it is possible that the problem could affect main compilation pipeline as well. https://reviews.llvm.org/D86659 (which landed in LLVM 12) fixes the problem. So we have another motivation for switching to LLD besides https://youtrack.jetbrains.com/issue/KT-47605. The only known downside is unsupported defsym which causes slight binary size increase. I think it is doable.
This commit is contained in:
@@ -318,15 +318,6 @@ class K2Native : CLICompiler<K2NativeCompilerArguments>() {
|
||||
configuration.report(ERROR, "-Xgc-aggressive is only supported for -memory-model experimental")
|
||||
}
|
||||
put(GARBAGE_COLLECTOR_AGRESSIVE, arguments.gcAggressive)
|
||||
put(CHECK_LLD_COMPATIBILITY, when (val it = arguments.checkLldCompatibility) {
|
||||
"enable" -> true
|
||||
"disable" -> false
|
||||
null -> true
|
||||
else -> {
|
||||
configuration.report(ERROR, "Unsupported '-Xcheck-compatibility-with-lld' value: $it. Possible values are 'enable'/'disable'")
|
||||
true
|
||||
}
|
||||
})
|
||||
put(RUNTIME_ASSERTS_MODE, when (arguments.runtimeAssertsMode) {
|
||||
"ignore" -> RuntimeAssertsMode.IGNORE
|
||||
"log" -> RuntimeAssertsMode.LOG
|
||||
|
||||
@@ -317,13 +317,6 @@ class K2NativeCompilerArguments : CommonCompilerArguments() {
|
||||
@Argument(value = "-Xir-property-lazy-initialization", description = "Initialize top level properties lazily per file")
|
||||
var propertyLazyInitialization: Boolean = false
|
||||
|
||||
@Argument(
|
||||
value = "-Xcheck-compatibility-with-lld",
|
||||
valueDescription = "{disable|enable}",
|
||||
description = "Check that linker flags are compatible with LLD."
|
||||
)
|
||||
var checkLldCompatibility: String? = null
|
||||
|
||||
@Argument(value="-Xruntime-asserts-mode", valueDescription = "<mode>", description = "Enable asserts in runtime. Possible values: 'ignore', 'log', 'panic'")
|
||||
var runtimeAssertsMode: String? = "ignore"
|
||||
|
||||
|
||||
@@ -146,7 +146,6 @@ internal class Linker(val context: Context) {
|
||||
linkerInput.caches.dynamic +
|
||||
libraryProvidedLinkerFlags + additionalLinkerArgs
|
||||
|
||||
checkLldCompatibility()
|
||||
val finalOutputCommands = linker.finalLinkCommands(
|
||||
objectFiles = linkerInput.objectFiles,
|
||||
executable = executable,
|
||||
@@ -178,23 +177,6 @@ internal class Linker(val context: Context) {
|
||||
return executable
|
||||
}
|
||||
|
||||
private fun checkLldCompatibility() {
|
||||
if (linker is MingwLinker && config.getBoolean(KonanConfigKeys.CHECK_LLD_COMPATIBILITY)) {
|
||||
linker.lldCompatibilityChecker = { command ->
|
||||
command.logWith(context::log)
|
||||
val result = command.getResult(withErrors = true)
|
||||
if (result.exitCode != 0) {
|
||||
val message = """
|
||||
Kotlin/Native will switch from ld to LLD linker in future releases and this warning will become an error.
|
||||
See https://youtrack.jetbrains.com/issue/KT-47605 for details.
|
||||
${result.outputLines.joinToString("\n")}
|
||||
""".lineSequence().map { it.trim() }.joinToString("\n")
|
||||
context.reportCompilationWarning(message)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun shouldPerformPreLink(caches: CachesToLink, linkerOutputKind: LinkerOutputKind): Boolean {
|
||||
// Pre-link is only useful when producing static library. Otherwise its just a waste of time.
|
||||
val isStaticLibrary = linkerOutputKind == LinkerOutputKind.STATIC_LIBRARY &&
|
||||
|
||||
@@ -4441,48 +4441,6 @@ interopTest("interop_cppSkiaSignature") {
|
||||
UtilsKt.dependsOnPlatformLibs(it)
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that compiler properly reports linker options that aren't supported by LLD.
|
||||
* @param withImportLibrary create an import library if true. Thus, LLD shoudn't complain.
|
||||
* @param shouldShowWarning compiler should show warning from LLD if true.
|
||||
* @param compilerFlags additional flags that will be passed to Kotlin/Native.
|
||||
*/
|
||||
void driverCheckLldCompatibilityTest(String taskName, boolean withImportLibrary, boolean shouldShowWarning, List<String> compilerFlags) {
|
||||
tasks.register(taskName, KonanDriverTest) {
|
||||
source = "interop/mingw_dll_linkage/main.kt"
|
||||
|
||||
flags = ["-linker-option", "-lrary", "-linker-option", "-L", "-linker-option", "$buildDir/$taskName"] +
|
||||
compilerFlags
|
||||
|
||||
compilerMessages = true
|
||||
goldValue = "lld doesn't support linking directly against"
|
||||
outputChecker = { out ->
|
||||
shouldShowWarning ? out.contains(goldValue) : !out.contains(goldValue)
|
||||
}
|
||||
|
||||
doBeforeBuild {
|
||||
mkdir("$buildDir/$taskName")
|
||||
execClangForCompilerTests(project.target) {
|
||||
args "$projectDir/interop/mingw_dll_linkage/library.c"
|
||||
args '-shared', '-o', "$buildDir/$taskName/library.dll"
|
||||
if (withImportLibrary) {
|
||||
args "-Wl,--out-implib", "-Wl,$buildDir/$taskName/library.dll.a"
|
||||
}
|
||||
}
|
||||
copy {
|
||||
from("$buildDir/$taskName/library.dll")
|
||||
into("$testOutputLocal/$name/$target/")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isWindowsTarget(project)) {
|
||||
driverCheckLldCompatibilityTest("driver_lld_with_import_library", true, false, [])
|
||||
driverCheckLldCompatibilityTest("driver_lld_without_import_library", false, true, [])
|
||||
driverCheckLldCompatibilityTest("driver_lld_without_import_library_no_check", false, false, ["-Xcheck-compatibility-with-lld=disable"])
|
||||
}
|
||||
|
||||
/*
|
||||
TODO: This test isn't run automatically
|
||||
task interop_echo_server(type: RunInteropKonanTest) {
|
||||
|
||||
@@ -875,7 +875,7 @@ targetToolchain.mingw_x64 = msys2-mingw-w64-x86_64-clang-llvm-lld-compiler_rt-8.
|
||||
libffiDir.mingw_x64 = libffi-3.3-windows-x64-1
|
||||
windowsKitParts.mingw_x64 = windows-kit-x64-v1-alpha2
|
||||
msvcParts.mingw_x64 = msvc-x64-v1-alpha2
|
||||
lldLocation.mingw_x64 = lld-11.1.0-windows-x64/ld.lld.exe
|
||||
lldLocation.mingw_x64 = lld-12.0.1-windows-x64/ld.lld.exe
|
||||
|
||||
windows-kit-x64-v1-alpha2.default = \
|
||||
remote:internal
|
||||
@@ -888,7 +888,7 @@ targetToolchain.macos_x64-mingw_x64 = msys2-mingw-w64-x86_64-clang-llvm-lld-comp
|
||||
# for Windows we are currently using LLDB 9
|
||||
dependencies.mingw_x64 = \
|
||||
lldb-2-windows \
|
||||
lld-11.1.0-windows-x64 \
|
||||
lld-12.0.1-windows-x64 \
|
||||
msys2-mingw-w64-x86_64-clang-llvm-lld-compiler_rt-8.0.1
|
||||
|
||||
targetTriple.mingw_x64 = x86_64-pc-windows-gnu
|
||||
@@ -904,8 +904,7 @@ linkerNoDebugFlags.mingw_x64 = -Wl,-S
|
||||
linkerDynamicFlags.mingw_x64 = -shared
|
||||
linkerKonanFlags.mingw_x64 =-static-libgcc -static-libstdc++ \
|
||||
-Wl,--dynamicbase \
|
||||
-Wl,-Bstatic,--whole-archive -lwinpthread -Wl,--no-whole-archive,-Bdynamic \
|
||||
-Wl,--defsym,__cxa_demangle=Konan_cxa_demangle
|
||||
-Wl,-Bstatic,--whole-archive -lwinpthread -Wl,--no-whole-archive,-Bdynamic
|
||||
linkerOptimizationFlags.mingw_x64 = -Wl,--gc-sections
|
||||
mimallocLinkerDependencies.mingw_x64 = -lbcrypt
|
||||
runtimeDefinitions.mingw_x64 = USE_GCC_UNWIND=1 USE_PE_COFF_SYMBOLS=1 KONAN_WINDOWS=1 \
|
||||
@@ -913,10 +912,10 @@ runtimeDefinitions.mingw_x64 = USE_GCC_UNWIND=1 USE_PE_COFF_SYMBOLS=1 KONAN_WIND
|
||||
|
||||
# Windows i686, based on mingw-w64.
|
||||
targetToolchain.mingw_x64-mingw_x86 = msys2-mingw-w64-i686-clang-llvm-lld-compiler_rt-8.0.1
|
||||
lldLocation.mingw_x86 = lld-11.1.0-windows-x64/ld.lld.exe
|
||||
lldLocation.mingw_x86 = lld-12.0.1-windows-x64/ld.lld.exe
|
||||
dependencies.mingw_x64-mingw_x86 = \
|
||||
msys2-mingw-w64-i686-clang-llvm-lld-compiler_rt-8.0.1 \
|
||||
lld-11.1.0-windows-x64
|
||||
lld-12.0.1-windows-x64
|
||||
targetToolchain.linux_x64-mingw_x86 = msys2-mingw-w64-i686-clang-llvm-lld-compiler_rt-8.0.1
|
||||
targetToolchain.macos_x64-mingw_x86 = msys2-mingw-w64-i686-clang-llvm-lld-compiler_rt-8.0.1
|
||||
dependencies.linux_x64-mingw_x86 = \
|
||||
@@ -941,8 +940,7 @@ linkerNoDebugFlags.mingw_x86 = -Wl,-S
|
||||
linkerDynamicFlags.mingw_x86 = -shared
|
||||
linkerKonanFlags.mingw_x86 = -static-libgcc -static-libstdc++ \
|
||||
-Wl,--dynamicbase \
|
||||
-Wl,-Bstatic,--whole-archive -lwinpthread -Wl,--no-whole-archive,-Bdynamic \
|
||||
-Wl,--defsym,__cxa_demangle=_Konan_cxa_demangle
|
||||
-Wl,-Bstatic,--whole-archive -lwinpthread -Wl,--no-whole-archive,-Bdynamic
|
||||
mimallocLinkerDependencies.mingw_x86 = -lbcrypt
|
||||
linkerOptimizationFlags.mingw_x86 = -Wl,--gc-sections
|
||||
runtimeDefinitions.mingw_x86 = USE_GCC_UNWIND=1 USE_PE_COFF_SYMBOLS=1 KONAN_WINDOWS=1 \
|
||||
|
||||
@@ -441,11 +441,6 @@ class MingwLinker(targetProperties: MingwConfigurables)
|
||||
return if (dir != null) "$dir/lib/windows/libclang_rt.$libraryName-$targetSuffix.a" else null
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle to command that runs LLD -### (i.e. without actual linkage) with arguments from [finalLinkCommands].
|
||||
*/
|
||||
var lldCompatibilityChecker: ((Command) -> Unit)? = null
|
||||
|
||||
override fun finalLinkCommands(objectFiles: List<ObjectFile>, executable: ExecutableFile,
|
||||
libraries: List<String>, linkerArgs: List<String>,
|
||||
optimize: Boolean, debug: Boolean,
|
||||
@@ -482,29 +477,11 @@ class MingwLinker(targetProperties: MingwConfigurables)
|
||||
+additionalArguments
|
||||
}
|
||||
|
||||
if (HostManager.hostIsMingw) {
|
||||
lldCompatibilityChecker?.let { checkLldCompatibiity ->
|
||||
// -### flag allows to avoid actual linkage process.
|
||||
val konanCxaDemangleSymbol = when (target) {
|
||||
KonanTarget.MINGW_X64 -> "Konan_cxa_demangle"
|
||||
KonanTarget.MINGW_X86 -> "_Konan_cxa_demangle"
|
||||
else -> error("Unexpected target: $target")
|
||||
}
|
||||
val lldCommand = Command(linker).constructLinkerArguments(
|
||||
// Add -fuse-ld to the end of the list to override previous appearances.
|
||||
additionalArguments = listOf("-fuse-ld=$absoluteLldLocation", "-Wl,-###"),
|
||||
// LLD doesn't support defsym.
|
||||
skipDefaultArguments = listOf("-Wl,--defsym,__cxa_demangle=$konanCxaDemangleSymbol")
|
||||
)
|
||||
checkLldCompatibiity(lldCommand)
|
||||
}
|
||||
}
|
||||
|
||||
return listOf(when {
|
||||
HostManager.hostIsMingw -> Command(linker)
|
||||
else -> Command("wine64", "$linker.exe")
|
||||
}.constructLinkerArguments(
|
||||
additionalArguments = listOf("-fuse-ld=${absoluteTargetToolchain}/bin/ld.exe")
|
||||
additionalArguments = listOf("-fuse-ld=$absoluteLldLocation")
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user