JetBrains/kotlin
Native backend
Active contributors: Alexander Shabalin, Igor Chevdar, Svyatoslav Scherbina
Kotlin/Native compiles Kotlin to native binaries through LLVM. Unlike the JVM/JS/Wasm backends, the Native backend does not live entirely under compiler/ir/. It is split between kotlin-native/ (the LLVM-driven backend, the C/C++ runtime, and Native-specific build tooling) and native/ (cross-cutting Native infrastructure: commonizer, Swift export, tests). It also has its own build configuration and its own hacking guide.
Purpose
Take lowered Kotlin IR, run Native-specific lowerings, emit LLVM IR via the LLVM C API, link against the C/C++ runtime, and produce an executable or library for one of the supported Native targets (macOS, iOS, Linux, Windows, Android, watchOS, tvOS — currently around a dozen).
Directory layout
kotlin-native/ (the backend itself)
kotlin-native/
├── backend.native/ IR lowerings + LLVM emission (Kotlin code)
├── runtime/ C/C++ runtime: GC, exceptions, ObjC interop
├── llvmDebugInfoC/ Debug-info bridges to LLVM
├── llvmInterop/ Kotlin interop with libLLVM
├── libllvmext/ Patched LLVM utilities
├── libclangInterop/ Bindings to libclang (used for header parsing)
├── libclangext/ Patched libclang utilities
├── platformLibs/ Pre-built klibs for platform APIs (UIKit, ...)
├── endorsedLibraries/ Bundled additional libraries
├── Interop/ C interop (cinterop) tooling
├── cmd/ kotlinc-native command-line driver
├── tools/ Native dev tools (klib inspect, ...)
├── utilities/ Build utilities
├── samples/ Native sample projects
├── HACKING.md Onboarding for the Native backend
└── README.md High-level overviewnative/ (cross-cutting Native code)
native/
├── commonizer/ Tool that merges per-platform klibs into a "common" klib
├── commonizer-api/, commonizer-embeddable/
├── swift/ Swift export: produce a Swift API from a Kotlin module
├── objcexport-header-generator/ Objective-C header generator
├── frontend/ Native-specific FE bits
├── cli-native/ kotlinc-native frontend → Native backend glue
├── native.config/ Native-specific compiler config
├── native.tests/ Native end-to-end tests
├── kotlin-test-native-xctest/ Bridge from kotlin-test to XCTest (iOS)
├── unsafe-mem/ Unsafe memory APIs for Native
├── binary-options/ Native-specific binary options
├── analysis-api-based-export-common/ Analysis API based exports
├── analysis-api-based-test-utils/ Analysis API based test utilities
├── external-projects-test-utils/ Test utils for external projects
├── base/, executors/, utils/ Shared utilities
└── analysis-api-based-test-utils/Key abstractions
| Type | Where | Role |
|---|---|---|
KonanBackendContext |
kotlin-native/backend.native/... |
Native backend state. (Konan is the historical Native project name; you'll see "konan" throughout.) |
LLVMValueRef, LLVMTypeRef, ... |
kotlin-native/llvmInterop/ |
Bindings to the LLVM C API. |
RuntimeAware |
kotlin-native/runtime/... |
C/C++ runtime entry points (alloc, GC, exceptions). |
Commonizer |
native/commonizer/... |
Produces "common" klibs by merging per-platform variants. |
How Native compilation works
graph LR
IR["Lowered Kotlin IR"] --> NativeLower["Native lowerings<br/>kotlin-native/backend.native"]
NativeLower --> LLVMIR["LLVM IR"]
LLVMIR --> LLVM["LLVM optimizer + codegen"]
LLVM --> Obj["Object files"]
Obj --> Link["Native linker (ld/lld/...)"]
Runtime["Kotlin/Native runtime<br/>(kotlin-native/runtime)"] --> Link
Link --> Bin["Native binary / .framework"]Each compilation unit becomes a klib (Kotlin Library) — same format as JS/Wasm, just with different runtime. Klibs are linked into a final binary by the Native linker, with the Kotlin/Native runtime statically linked in.
The runtime
kotlin-native/runtime/ is a substantial body of C++ code implementing:
- The garbage collector (mostly a concurrent mark-and-sweep with a young generation).
- Exception handling.
- Workers (the Kotlin/Native concurrency primitive).
- Memory model machinery (atomic ops, freeze/thaw — the latter for the legacy memory model).
- Objective-C interop (the bridge that lets Kotlin classes implement ObjC protocols, and vice versa).
This is one of the few large C++ pieces in the repo (~37,000 LOC of .cpp, plus ~70,000 LOC of .h).
C interop (cinterop)
kotlin-native/Interop/ and kotlin-native/libclangInterop/ together implement cinterop, the tool that converts a C/Objective-C header into a Kotlin klib. This is how Kotlin/Native binds to UIKit, AppKit, the C standard library, third-party C libraries, etc. It uses libclang to parse the headers and emits a klib with external Kotlin declarations.
Commonizer
native/commonizer/ solves a Multiplatform problem: when you target several platforms (e.g., iosX64, iosArm64, iosSimulatorArm64), each ships a slightly different platform klib (different signatures for pthread_*, different sizes of types). The commonizer compares the per-platform klibs and produces a single "common" klib whose declarations match those that are identical across all platforms. User Multiplatform code can then expect/actual against the common klib.
Swift export
native/swift/ and native/objcexport-header-generator/ produce Swift/Objective-C headers from a Kotlin module so iOS/macOS apps can call Kotlin code natively. This is the path Kotlin Multiplatform Mobile (KMM) uses on Apple platforms.
Build environment
kotlin-native/ builds with Groovy Gradle, not the Kotlin DSL — see kotlin-native/build.gradle. It pulls in a vendored LLVM (under kotlin-native/dependencies/) and requires platform-specific toolchains (Xcode, Visual Studio, glibc/musl) to produce binaries for each supported target. Read kotlin-native/HACKING.md and kotlin-native/BUILDING_LLVM.md before your first build.
Integration points
- Input: lowered Kotlin IR + Kotlin/Native frontend additions.
- Output: Native binaries (
.kexe),.frameworkbundles,.dylib/.so/.dlllibraries, klibs. - Used by:
compiler/cli/cli-native-klib/,kotlin-native/cmd/kotlinc-native, KGP'skotlin("multiplatform")Native targets. - Tested by:
native/native.tests/andkotlin-native/backend.native/tests/.
Where to start
For a Kotlin-side change, kotlin-native/backend.native/ (under its compiler/ subdirectory) is the analog of compiler/ir/backend.jvm/. For a runtime-level concern (GC, exception handling), kotlin-native/runtime/. For C interop, kotlin-native/Interop/. The HACKING.md file is required reading.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.