Add quick workaround for https://bugs.swift.org/browse/SR-10177
This commit is contained in:
committed by
SvyatoslavScherbina
parent
e6a391f024
commit
31892bd82e
+3
-1
@@ -44,6 +44,8 @@ internal class LinkStage(val context: Context) {
|
||||
private val bitcodeLibraries = context.llvm.bitcodeToLink
|
||||
private val nativeDependencies = context.llvm.nativeDependenciesToLink
|
||||
|
||||
private val additionalBitcodeFilesToLink = context.llvm.additionalProducedBitcodeFiles
|
||||
|
||||
private fun MutableList<String>.addNonEmpty(elements: List<String>) {
|
||||
addAll(elements.filter { !it.isEmpty() })
|
||||
}
|
||||
@@ -223,7 +225,7 @@ internal class LinkStage(val context: Context) {
|
||||
|
||||
fun makeObjectFiles() {
|
||||
|
||||
val bitcodeFiles = listOf(emitted) +
|
||||
val bitcodeFiles = listOf(emitted) + additionalBitcodeFilesToLink +
|
||||
bitcodeLibraries.map { it.bitcodePaths }.flatten().filter { it.isBitcode }
|
||||
|
||||
objectFiles.add(when (platform.configurables) {
|
||||
|
||||
+2
@@ -380,6 +380,8 @@ internal class Llvm(val context: Context, val llvmModule: LLVMModuleRef) {
|
||||
.filter { (!it.isDefault && !context.config.purgeUserLibs) || imports.bitcodeIsUsed(it) }
|
||||
}
|
||||
|
||||
val additionalProducedBitcodeFiles = mutableListOf<String>()
|
||||
|
||||
val staticData = StaticData(context)
|
||||
|
||||
private val target = context.config.target
|
||||
|
||||
+50
-3
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.backend.konan.objcexport
|
||||
|
||||
import org.jetbrains.kotlin.backend.konan.Context
|
||||
import org.jetbrains.kotlin.backend.konan.descriptors.getPackageFragments
|
||||
import org.jetbrains.kotlin.backend.konan.descriptors.isInterface
|
||||
import org.jetbrains.kotlin.backend.konan.getExportedDependencies
|
||||
import org.jetbrains.kotlin.backend.konan.isNativeBinary
|
||||
import org.jetbrains.kotlin.backend.konan.llvm.CodeGenerator
|
||||
@@ -15,11 +16,13 @@ import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.SourceFile
|
||||
import org.jetbrains.kotlin.konan.exec.Command
|
||||
import org.jetbrains.kotlin.konan.file.File
|
||||
import org.jetbrains.kotlin.konan.target.CompilerOutputKind
|
||||
import org.jetbrains.kotlin.konan.target.KonanTarget
|
||||
import org.jetbrains.kotlin.konan.target.Family
|
||||
import org.jetbrains.kotlin.konan.file.createTempFile
|
||||
import org.jetbrains.kotlin.konan.target.AppleConfigurables
|
||||
import org.jetbrains.kotlin.konan.target.CompilerOutputKind
|
||||
import org.jetbrains.kotlin.konan.target.Family
|
||||
import org.jetbrains.kotlin.konan.target.KonanTarget
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.name.isSubpackageOf
|
||||
@@ -87,6 +90,8 @@ internal class ObjCExport(val context: Context) {
|
||||
categoryMembers = exportedInterface.categoryMembers,
|
||||
topLevel = exportedInterface.topLevel
|
||||
)
|
||||
|
||||
exportedInterface.generateWorkaroundForSwiftSR10177()
|
||||
}
|
||||
|
||||
objCCodeGenerator.emitRtti()
|
||||
@@ -226,6 +231,48 @@ internal class ObjCExport(val context: Context) {
|
||||
|
||||
file.writeBytes(contents.toString().toByteArray())
|
||||
}
|
||||
|
||||
// See https://bugs.swift.org/browse/SR-10177
|
||||
private fun ObjCExportedInterface.generateWorkaroundForSwiftSR10177() {
|
||||
// Code for all protocols from the header should get into the binary.
|
||||
// Objective-C protocols ABI is complicated (consider e.g. undocumented extended type encoding),
|
||||
// so the easiest way to achieve this (quickly) is to compile a stub by clang.
|
||||
|
||||
val protocolsStub = listOf(
|
||||
"__attribute__((used)) static void __workaroundSwiftSR10177() {",
|
||||
buildString {
|
||||
append(" ")
|
||||
generatedClasses.forEach {
|
||||
if (it.isInterface) {
|
||||
val protocolName = namer.getClassOrProtocolName(it).objCName
|
||||
append("@protocol($protocolName); ")
|
||||
}
|
||||
}
|
||||
},
|
||||
"}"
|
||||
)
|
||||
|
||||
val source = createTempFile("protocols", ".m").deleteOnExit()
|
||||
source.writeLines(headerLines + protocolsStub)
|
||||
|
||||
val bitcode = createTempFile("protocols", ".bc").deleteOnExit()
|
||||
|
||||
val clangCommand = context.config.clang.clangC(
|
||||
source.absolutePath,
|
||||
"-O2",
|
||||
"-emit-llvm",
|
||||
"-c", "-o", bitcode.absolutePath
|
||||
)
|
||||
|
||||
val result = Command(clangCommand).getResult(withErrors = true)
|
||||
|
||||
if (result.exitCode == 0) {
|
||||
context.llvm.additionalProducedBitcodeFiles += bitcode.absolutePath
|
||||
} else {
|
||||
// Note: ignoring compile errors intentionally.
|
||||
// In this case resulting framework will likely be unusable due to compile errors when importing it.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal fun ModuleDescriptor.guessMainPackage(): FqName {
|
||||
|
||||
Reference in New Issue
Block a user