Kotlin Help

Kotlin/Native libraries

Library compilation

You can use your project's build file or the Kotlin/Native compiler to produce a *.klib artifact for your library.

Using Gradle build file

You can compile a *.klib library artifact by specifying a Kotlin/Native target in your Gradle build file:

  1. In your build.gradle(.kts) file, declare at least one Kotlin/Native target. For example:

    // build.gradle.kts plugins { kotlin("multiplatform") version "2.2.21" } kotlin { macosArm64() // on macOS // linuxArm64() // on Linux // mingwX64() // on Windows }
  2. Run the <target>Klib task. For example:

    ./gradlew macosArm64Klib

Gradle automatically compiles source files for that target and produces the .klib artifact in the project's build/libs directory.

Using Kotlin/Native compiler

To produce a library with the Kotlin/Native compiler:

  1. Download and install the Kotlin/Native compiler.

  2. To compile a Kotlin/Native source file into a library, use the -produce library or -p library option:

    kotlinc-native foo.kt -p library -o bar

    This command compiles the contents of the foo.kt file into a library with the name bar, producing a bar.klib artifact.

  3. To link another file to a library, use the -library <name> or -l <name> option. For example:

    kotlinc-native qux.kt -l bar

    This command compiles the contents of the qux.kt source file and the bar.klib library and produces the program.kexe final executable binary.

klib utility

The klib library management utility allows you to inspect libraries using the following syntax:

klib <command> <library path> [<option>]

The following commands are currently available:

Command

Description

info

General information about the library.

dump-abi

Dump the ABI snapshot of the library. Each line in the snapshot corresponds to one declaration. In case an ABI-incompatible change happens to a declaration, it'll be visible in the corresponding line of the snapshot.

dump-ir

Dump the intermediate representation (IR) of library declarations to the output. Use it only for debugging.

dump-ir-signatures

Dump IR signatures of all non-private library declarations and all non-private declarations consumed by this library (as two separate lists). This command relies purely on the data in IR.

dump-ir-inlinable-functions

Dump the IR of inlinable functions in the library to the output. Use it only for debugging.

dump-metadata

Dump the metadata of all library declarations to the output. Use it only for debugging.

dump-metadata-signatures

Dump IR signatures of all non-private library declarations based on the library metadata. In most cases, the output is the same as for the dump-ir-signatures command, which renders signatures based on IR. However, if IR-transforming compiler plugins (such as Compose) are used during compilation, patched declarations may have different signatures.

All the above dumping commands accept an additional -signature-version {N} argument that instructs the klib utility which IR signature version to render when dumping signatures. If not provided, it uses the most up‑to‑date version supported by the library. For example:

klib dump-metadata-signatures mylib.klib -signature-version 1

In addition, the dump-metadata command accepts the -print-signatures {true|false} argument that instructs the klib utility to print the IR signatures for every declaration in the output.

Creating and using a library

  1. Create a library by placing the source code into kotlinizer.kt:

    package kotlinizer val String.kotlinized get() = "Kotlin $this"
  2. Compile the library into a .klib:

    kotlinc-native kotlinizer.kt -p library -o kotlinizer
  3. Check the current directory for the created library:

    ls kotlinizer.klib
  4. Check out general information about the library:

    klib info kotlinizer.klib
  5. Create a short program in the use.kt file:

    import kotlinizer.* fun main(args: Array<String>) { println("Hello, ${"world".kotlinized}!") }
  6. Compile the program, linking the use.kt source file to your library:

    kotlinc-native use.kt -l kotlinizer -o kohello
  7. Run the program:

    ./kohello.kexe

You should see Hello, Kotlin world! in the output.

Library search sequence

When given a -library foo option, the compiler searches the foo library in the following order:

  1. Current compilation directory or an absolute path.

  2. Libraries installed in the default repository.

  3. Libraries installed in the $installation/klib directory.

Library format

Kotlin/Native libraries are zip files containing a predefined directory structure, with the following layout:

foo.klib when unpacked as foo/ gives us:

- foo/ - $component_name/ - ir/ - Serialized Kotlin IR. - targets/ - $platform/ - kotlin/ - Kotlin compiled to LLVM bitcode. - native/ - Bitcode files of additional native objects. - $another_platform/ - There can be several platform specific kotlin and native pairs. - linkdata/ - A set of ProtoBuf files with serialized linkage metadata. - resources/ - General resources such as images. (Not used yet). - manifest - A file in the java property format describing the library.

You can find an example layout in the klib/common/stdlib directory of your Kotlin/Native compiler installation.

Using relative paths in klibs

A serialized IR representation of source files is a part of a klib library. It includes paths of files for generating proper debug information. By default, stored paths are absolute.

With the -Xklib-relative-path-base compiler option, you can change the format and use only relative paths in the artifact. To make it work, pass one or multiple base paths of source files as an argument:

import org.jetbrains.kotlin.gradle.tasks.KotlinCompilationTask // ... tasks.named<KotlinCompilationTask<*>>("compileKotlin").configure { // $base is a base path of source files compilerOptions.freeCompilerArgs.add("-Xklib-relative-path-base=$base") }
import org.jetbrains.kotlin.gradle.tasks.KotlinCompilationTask // ... tasks.named('compileKotlin', KotlinCompilationTask) { compilerOptions { // $base is a base path of source files freeCompilerArgs.add("-Xklib-relative-path-base=$base") } }

What's next?

Learn how to use the cinterop tool to produce *.klib artifacts

21 October 2025