A GraalVM-compiled native image of kotlin-compiler-embeddable that runs as a standalone executable. Behaves like the regular kotlinc but with some limitations — mainly, no support for plugins. Produces a native image distribution which is similar in its structure to the standard kotlinc distribution.
The distribution is produced in prepare/compiler-native-image/build/dist directory and has the following structure:
bin/kotlinc-native-image[.exe] — native binary;bin/kotlinc-native-image.[sh|bat] — launcher wrappers;lib/ — runtime classpath jars;license/ — license information.Produce a native image binary:
./gradlew :kotlin-compiler-native-image:kotlincNativeImage
The task requires a GraalVM JDK 25 toolchain, which is automatically resolved via Gradle.
Produce a native image distribution:
./gradlew :kotlin-compiler-native-image:kotlincNativeImageDist
You can also produce native image distribution release artifacts in prepare/compiler-native-image/build/artifacts via:
./gradlew :kotlin-compiler-native-image:kotlincNativeImageArtifacts
Similar to JVM kotlinc, the native image binary requires some configuration. To simplify the user experience, the distribution also provides kotlinc-native-image.[sh|bat] wrapper scripts that do all the necessary configuration of the binary. Namely, they configure:
-Djava.home — resolved to the JAVA_HOME environment variable;-Dkotlin.home — resolved to the location of the distribution root.These wrapper scripts may be used as a drop-in replacement for the JVM kotlinc:
dist/kotlinc-native-image/bin/kotlinc-native-image.sh path/to/Foo.kt -d out/
For a quick sanity check, use:
./gradlew :kotlin-compiler-native-image:nativeImageSmokeTest
It compiles a “Hello World” with the native image compiler and verifies that the compilation succeeds.
For the full suite, run:
./gradlew :kotlin-compiler-native-image:nativeImageBoxTest
The test suite mirrors the compiler's JVM box-codegen tests: it is generated from the same test data under compiler/testData/codegen/box and behaves similarly to the JVM tests. The goal is to ensure that the behavior of the native image compiler is the same as its JVM counterpart.
The current setup is quite ad-hoc:
compilerTest aggregate and run only via the dedicated nativeImageBoxTest task; the main goal is to not intervene with pre-existing workflows while still ensuring that the native image works correctly;JVM_IR is treated as the target backend, so a test is skipped if it contains // IGNORE_BACKEND: JVM_IR directive (or its equivalent);helpers.*) are skipped.GraalVM reachability metadata is stored in prepare/compiler-native-image/resources/META-INF/native-image.
Initial metadata was collected by running the Kotlin Compiler Embeddable JAR with the GraalVM Tracing Agent on the same set of compiler box tests compiler/testData/codegen/box.
Metadata can be regenerated when necessary. For a quick update, use:
./gradlew :kotlin-compiler-native-image:generateReachabilityMetadataSmoke
It will run the reachability metadata collection on the sample “Hello World” program.
For a full regeneration over all the box test data, use (takes ~3–4 hours):
./gradlew :kotlin-compiler-native-image:generateReachabilityMetadataBox
IDE run configurations are available both for running native image tests and collecting reachability metadata. You can find them in the “Compiler Native Image” run configuration folder.