Skip to content

Commit df7cdf8

Browse files
committed
build(cli): Support building a GraalVM native image
1 parent efe6fa7 commit df7cdf8

File tree

2 files changed

+60
-0
lines changed

2 files changed

+60
-0
lines changed

cli/build.gradle.kts

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,13 @@
1+
import java.nio.file.Files
2+
3+
import org.graalvm.buildtools.gradle.tasks.BuildNativeImageTask
4+
15
plugins {
26
id("stan-kotlin-conventions")
37

48
application
9+
10+
alias(libs.plugins.graalvm)
511
}
612

713
application {
@@ -19,3 +25,55 @@ dependencies {
1925
implementation(libs.koinCore)
2026
implementation(libs.kotlinReflect)
2127
}
28+
29+
graalvmNative {
30+
toolchainDetection = System.getenv("GRAALVM_HOME") == null
31+
32+
metadataRepository {
33+
enabled = true
34+
}
35+
36+
// For options see https://graalvm.github.io/native-build-tools/latest/gradle-plugin.html.
37+
binaries {
38+
named("main") {
39+
imageName = provider { application.applicationName }
40+
41+
buildArgs.addAll(
42+
"--report-unsupported-elements-at-runtime",
43+
"--parallelism=8",
44+
"-J-Xmx16g"
45+
)
46+
}
47+
}
48+
}
49+
50+
tasks.named<BuildNativeImageTask>("nativeCompile") {
51+
// Gradle's "Copy" task cannot handle symbolic links, see https://github.com/gradle/gradle/issues/3982. That is why
52+
// links contained in the GraalVM distribution archive get broken during provisioning and are replaced by empty
53+
// files. Address this by recreating the links in the toolchain directory.
54+
val toolchainDir = System.getenv("GRAALVM_HOME")?.let { File(it) }
55+
?: options.get().javaLauncher.get().executablePath.asFile.parentFile.run {
56+
if (name == "bin") parentFile else this
57+
}
58+
59+
val toolchainFiles = toolchainDir.walkTopDown().filter { it.isFile }
60+
val emptyFiles = toolchainFiles.filter { it.length() == 0L }
61+
62+
// Find empty toolchain files that are named like other toolchain files and assume these should have been links.
63+
val links = toolchainFiles.mapNotNull { file ->
64+
emptyFiles.singleOrNull { it != file && it.name == file.name }?.let {
65+
file to it
66+
}
67+
}
68+
69+
// Fix up symbolic links.
70+
links.forEach { (target, link) ->
71+
logger.quiet("Fixing up '$link' to link to '$target'.")
72+
73+
if (link.delete()) {
74+
Files.createSymbolicLink(link.toPath(), target.toPath())
75+
} else {
76+
logger.warn("Unable to delete '$link'.")
77+
}
78+
}
79+
}

gradle/libs.versions.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
[versions]
22
composePlugin = "1.7.3"
33
detektPlugin = "1.23.8"
4+
graalvmPlugin = "0.10.6"
45
kotlinPlugin = "2.1.20"
56
versionsPlugin = "0.52.0"
67

@@ -17,6 +18,7 @@ poiOoxml = "5.4.0"
1718
[plugins]
1819
compose = { id = "org.jetbrains.compose", version.ref = "composePlugin" }
1920
compose-compiler = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlinPlugin" }
21+
graalvm = { id = "org.graalvm.buildtools.native", version.ref = "graalvmPlugin" }
2022
kotlinSerialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlinPlugin" }
2123
versions = { id = "com.github.ben-manes.versions", version.ref = "versionsPlugin" }
2224

0 commit comments

Comments
 (0)