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 bitcodeLibraries = context.llvm.bitcodeToLink
|
||||||
private val nativeDependencies = context.llvm.nativeDependenciesToLink
|
private val nativeDependencies = context.llvm.nativeDependenciesToLink
|
||||||
|
|
||||||
|
private val additionalBitcodeFilesToLink = context.llvm.additionalProducedBitcodeFiles
|
||||||
|
|
||||||
private fun MutableList<String>.addNonEmpty(elements: List<String>) {
|
private fun MutableList<String>.addNonEmpty(elements: List<String>) {
|
||||||
addAll(elements.filter { !it.isEmpty() })
|
addAll(elements.filter { !it.isEmpty() })
|
||||||
}
|
}
|
||||||
@@ -223,7 +225,7 @@ internal class LinkStage(val context: Context) {
|
|||||||
|
|
||||||
fun makeObjectFiles() {
|
fun makeObjectFiles() {
|
||||||
|
|
||||||
val bitcodeFiles = listOf(emitted) +
|
val bitcodeFiles = listOf(emitted) + additionalBitcodeFilesToLink +
|
||||||
bitcodeLibraries.map { it.bitcodePaths }.flatten().filter { it.isBitcode }
|
bitcodeLibraries.map { it.bitcodePaths }.flatten().filter { it.isBitcode }
|
||||||
|
|
||||||
objectFiles.add(when (platform.configurables) {
|
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) }
|
.filter { (!it.isDefault && !context.config.purgeUserLibs) || imports.bitcodeIsUsed(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val additionalProducedBitcodeFiles = mutableListOf<String>()
|
||||||
|
|
||||||
val staticData = StaticData(context)
|
val staticData = StaticData(context)
|
||||||
|
|
||||||
private val target = context.config.target
|
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.Context
|
||||||
import org.jetbrains.kotlin.backend.konan.descriptors.getPackageFragments
|
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.getExportedDependencies
|
||||||
import org.jetbrains.kotlin.backend.konan.isNativeBinary
|
import org.jetbrains.kotlin.backend.konan.isNativeBinary
|
||||||
import org.jetbrains.kotlin.backend.konan.llvm.CodeGenerator
|
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.ClassDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.SourceFile
|
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.file.File
|
||||||
import org.jetbrains.kotlin.konan.target.CompilerOutputKind
|
import org.jetbrains.kotlin.konan.file.createTempFile
|
||||||
import org.jetbrains.kotlin.konan.target.KonanTarget
|
|
||||||
import org.jetbrains.kotlin.konan.target.Family
|
|
||||||
import org.jetbrains.kotlin.konan.target.AppleConfigurables
|
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.FqName
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.name.isSubpackageOf
|
import org.jetbrains.kotlin.name.isSubpackageOf
|
||||||
@@ -87,6 +90,8 @@ internal class ObjCExport(val context: Context) {
|
|||||||
categoryMembers = exportedInterface.categoryMembers,
|
categoryMembers = exportedInterface.categoryMembers,
|
||||||
topLevel = exportedInterface.topLevel
|
topLevel = exportedInterface.topLevel
|
||||||
)
|
)
|
||||||
|
|
||||||
|
exportedInterface.generateWorkaroundForSwiftSR10177()
|
||||||
}
|
}
|
||||||
|
|
||||||
objCCodeGenerator.emitRtti()
|
objCCodeGenerator.emitRtti()
|
||||||
@@ -226,6 +231,48 @@ internal class ObjCExport(val context: Context) {
|
|||||||
|
|
||||||
file.writeBytes(contents.toString().toByteArray())
|
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 {
|
internal fun ModuleDescriptor.guessMainPackage(): FqName {
|
||||||
|
|||||||
Reference in New Issue
Block a user