[K/N] Introduce LLD compatibility checker for MinGW

We are going to switch to LLD linker for MinGW targets.
Right now LLD for MinGW doesn't support all features
of ld.bfd and thus this change might be breaking for some users.
To make transition smoother, we run lld -### to show a warning to user
so they can update their compilation options before LLD will be turned
on by default.

More details: https://youtrack.jetbrains.com/issue/KT-47605
This commit is contained in:
Sergey Bogolepov
2021-07-06 14:53:59 +07:00
committed by Space
parent 30d0fea003
commit 9ed97a27f1
7 changed files with 78 additions and 10 deletions
@@ -104,7 +104,10 @@ interface AppleConfigurables : Configurables, ClangFlags {
val absoluteAdditionalToolsDir get() = absolute(additionalToolsDir)
}
interface MingwConfigurables : Configurables, ClangFlags
interface MingwConfigurables : Configurables, ClangFlags {
val lldLocation get() = targetString("lldLocation")!!
val absoluteLldLocation get() = absolute(lldLocation)
}
interface GccConfigurables : Configurables, ClangFlags {
val gccToolchain get() = targetString("gccToolchain")
@@ -438,6 +438,11 @@ 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,
@@ -451,10 +456,11 @@ class MingwLinker(targetProperties: MingwConfigurables)
return staticGnuArCommands(ar, executable, objectFiles, libraries)
val dynamic = kind == LinkerOutputKind.DYNAMIC_LIBRARY
return listOf(when {
HostManager.hostIsMingw -> Command(linker)
else -> Command("wine64", "$linker.exe")
}.apply {
fun Command.constructLinkerArguments(
additionalArguments: List<String> = listOf(),
skipDefaultArguments: List<String> = listOf()
): Command = apply {
+listOf("-o", executable)
+objectFiles
// --gc-sections flag may affect profiling.
@@ -466,9 +472,28 @@ class MingwLinker(targetProperties: MingwConfigurables)
+libraries
if (needsProfileLibrary) +profileLibrary!!
+linkerArgs
+linkerKonanFlags
+linkerKonanFlags.filterNot { it in skipDefaultArguments }
if (mimallocEnabled) +mimallocLinkerDependencies
})
+additionalArguments
}
if (HostManager.hostIsMingw) {
lldCompatibilityChecker?.let { checkLldCompatibiity ->
// -### flag allows to avoid actual linkage process.
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=Konan_cxa_demangle")
)
checkLldCompatibiity(lldCommand)
}
}
return listOf(when {
HostManager.hostIsMingw -> Command(linker)
else -> Command("wine64", "$linker.exe")
}.constructLinkerArguments())
}
}