docs/swift-export/architecture.md
This document provides a high-level overview on how Swift export fits into the bigger "Kotlin" picture.
❗️ Swift export is in very early stages of development. Things change very quickly, and documentation might not catch up at times.
Objective-C export was developed back in 2017 as a part of the Kotlin/Native compiler. It was pretty fine at the moment, given that
Kotlin/Native was developed in a separate repository and the API surface of different Kotlin parts was pretty cumbersome.
Effectively, it consists of several global compiler passes:
And it works pretty well! However, this approach has a number of drawbacks:
It integrates poorly with an IDE.
Objective-C export was written as a global "batch" tool while good IDE integration requires the local-first approach.
Effectively, Kotlin/Native has 2 LLVM IR generators: one for Kotlin IR, and another for Objective-C bridges. Keeping these things in sync requires additional efforts.
Objective-C export is tied to descriptors that are a K1 legacy, and moving it to K2 requires additional efforts.
Integration with artifact kinds other than framework/xcframework might be tricky.
Given Objective-C experience, we wanted to try something else in Swift export. Luckily, when we started Swift export in 2023, we had more tools at our disposal:
So after a few approaches, we settled down with a relatively simple architecture of Swift export: Swift export is a separate tool that acts as a lazy Analysis API to Swift translator. Additionally, it generates thin Kotlin bridges with a C header which effectively provides C API to Kotlin binary. These bridges are compiled by the Kotlin/Native compiler like any other sources and require little support in the compiler.
---
title: Swift export overview
---
flowchart TD
Klib["Kotlin Module (klib)"] --> AA("Analysis API")
subgraph Swift export
AA --> SwiftSession["SirSession"]
SwiftSession --> SIR["Swift IR"]
SIR --> SirPrinter("SIR Printer")
SIR --> SirBridges("SIR compiler bridges generator")
end
SirPrinter --> SwiftSources[Swift sources]
SirBridges --> HeaderBridges[C header for Kotlin bridges]
SirBridges --> KotlinBridges[Kotlin bridges]
SwiftSources -.-> HeaderBridges
HeaderBridges -.-> KotlinBridges
Klib --> Compiler(Kotlin/Native compiler)
KotlinBridges --> Compiler
Compiler --> Binary[Kotlin Dynamic/Static library]
SwiftSources --> ExternalTooling("Gradle / Other build system")
HeaderBridges --> ExternalTooling
Binary --> ExternalTooling
ExternalTooling --> Artifact["Framework / XCFramework / Swift Package / ..."]
We consider this approach nice for a few reasons: