Skip to content

Commit 1badb18

Browse files
committed
feat: java/graalvm 21+ support
- feat: support for jvm21+/gvm jdk 23, latest truffle - feat: flag support for gvm, native arch, use new `-Os` optimization mode - feat: initial transitive native image flag support - fix: support up to graalvm/jdk 23 (latest) - fix: don't use `gu` tool for modern graalvm versions - fix: coordinate change for `shadow` plugin (`com.gradleup.shadow`) - fix: build with `--add-modules=jdk.unsupported` where needed - fix: use jdk21 to run the tests (needed for `Unsafe.ensureInitialized`) - fix: truffle svm dependency is required after graalvm `24.0.0` - fix: warnings for gvm flag usage, renamed truffle svm macro - chore: bump graalvm → `24.1.0` - chore: bump shadow → `8.3.5` - chore: update gradle → `8.12` Signed-off-by: Sam Gammon <sam@elide.dev>
1 parent 467e64f commit 1badb18

File tree

13 files changed

+115
-37
lines changed

13 files changed

+115
-37
lines changed

buildSrc/src/main/kotlin/BuildInfo.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,10 @@ open class BuildInfo(project: Project) {
8080

8181
val isReleaseBuild: Boolean by lazy { java.lang.Boolean.getBoolean("releaseBuild") }
8282

83+
val isNativeArch: Boolean by lazy { java.lang.Boolean.getBoolean("nativeArch") }
84+
85+
val isEnableOracleGraalvm: Boolean by lazy { java.lang.Boolean.getBoolean("oracleGraalvm") }
86+
8387
val hasMuslToolchain: Boolean by lazy {
8488
// see "install musl" in .circleci/jobs/BuildNativeJob.pkl
8589
File(System.getProperty("user.home"), "staticdeps/bin/x86_64-linux-musl-gcc").exists()

buildSrc/src/main/kotlin/InstallGraalVm.kt

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -58,10 +58,16 @@ constructor(
5858
if (os.isMacOsX) distroDir.resolve("Contents/Home/bin") else distroDir.resolve("bin")
5959

6060
println("Installing native-image into $distroDir")
61-
execOperations.exec {
62-
val executableName = if (os.isWindows) "gu.cmd" else "gu"
63-
executable = distroBinDir.resolve(executableName).toString()
64-
args("install", "--no-progress", "native-image")
61+
val gvmVersionMajor =
62+
requireNotNull(graalVm.get().version.split(".").first().toIntOrNull()) {
63+
"Invalid GraalVM JDK version: ${graalVm.get().graalVmJdkVersion}"
64+
}
65+
if (gvmVersionMajor < 24) {
66+
execOperations.exec {
67+
val executableName = if (os.isWindows) "gu.cmd" else "gu"
68+
executable = distroBinDir.resolve(executableName).toString()
69+
args("install", "--no-progress", "native-image")
70+
}
6571
}
6672

6773
println("Creating symlink ${graalVm.get().installDir} for $distroDir")

buildSrc/src/main/kotlin/pklFatJar.gradle.kts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ import org.gradle.kotlin.dsl.*
2424
plugins {
2525
`java-library`
2626
`maven-publish`
27-
id("com.github.johnrengelman.shadow")
27+
id("com.gradleup.shadow")
2828
}
2929

3030
// make fat Jar available to other subprojects
@@ -40,8 +40,6 @@ val relocations =
4040
mapOf(
4141
// pkl-core dependencies
4242
"org.antlr.v4." to "org.pkl.thirdparty.antlr.v4.",
43-
"com.oracle.truffle" to "org.pkl.thirdparty.truffle",
44-
"org.graalvm." to "org.pkl.thirdparty.graalvm.",
4543
"org.organicdesign.fp." to "org.pkl.thirdparty.paguro.",
4644
"org.snakeyaml.engine." to "org.pkl.thirdparty.snakeyaml.engine.",
4745
"org.msgpack." to "org.pkl.thirdparty.msgpack.",
@@ -71,7 +69,11 @@ val relocations =
7169
"com.squareup.kotlinpoet." to "org.pkl.thirdparty.kotlinpoet.",
7270
)
7371

74-
val nonRelocations = listOf("com/oracle/truffle/")
72+
val nonRelocations =
73+
listOf(
74+
"com/oracle/truffle/",
75+
"org/graalvm/",
76+
)
7577

7678
tasks.shadowJar {
7779
inputs.property("relocations", relocations)

buildSrc/src/main/kotlin/pklJavaLibrary.gradle.kts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,3 +86,27 @@ tasks.compileJava {
8686
// (see https://graalvm.slack.com/archives/CNQSB2DHD/p1712380902746829)
8787
options.compilerArgs.add("-Atruffle.dsl.SuppressWarnings=truffle-limit")
8888
}
89+
90+
//
91+
// JPMS Support
92+
//
93+
94+
fun Project.ifJpms(block: Project.() -> Unit) {
95+
// if current java is over 17...
96+
if (JavaVersion.current().majorVersion.toInt() >= 17) {
97+
block()
98+
}
99+
}
100+
101+
val jpmsJavacArgs =
102+
listOf(
103+
"--add-modules=jdk.unsupported",
104+
)
105+
106+
val jpmsJvmArgs = jpmsJavacArgs.plus(listOf())
107+
108+
tasks.withType<JavaCompile>().configureEach {
109+
ifJpms { options.compilerArgumentProviders.add(CommandLineArgumentProvider { jpmsJavacArgs }) }
110+
}
111+
112+
tasks.withType<JavaExec>().configureEach { ifJpms { jvmArgs(jpmsJvmArgs) } }

gradle/libs.versions.toml

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,14 @@ geantyref = "1.+"
99
googleJavaFormat = "1.21.0"
1010
# must not use `+` because used in download URL
1111
# 23.1.x requires JDK 20+
12-
graalVm = "23.0.6"
13-
graalVmJdkVersion = "17.0.12"
12+
graalVm = "24.1.1"
13+
graalVmJdkVersion = "23.0.1"
1414
# slightly hacky but convenient place so we remember to update the checksum
15-
graalVmSha256-macos-x64 = "3ecac1471f3fa95a56c5b75c65db9e60ac4551f56eda09eb9da95e6049ea77d7"
16-
graalVmSha256-macos-aarch64 = "4cdfdc6c9395f6773efcd191b6605f1b7c8e1b78ab900ab5cff34720a3feffc5"
17-
graalVmSha256-linux-x64 = "b6f3dace24cf1960ec790216f4c86f00d4f43df64e4e8b548f6382f04894713f"
18-
graalVmSha256-linux-aarch64 = "bd991d486b92deb74337b881e0f13a764c9c1e90fc358819080f7321fa5175e8"
19-
graalVmSha256-windows-x64 = "8b978e56dddc0edc60db99794b56975740d9c52293b31549cfc3f7516fc18b43"
15+
graalVmSha256-macos-x64 = "539699d8ff4979623bc7bdf8282ac6f76cd2560f47d14ec5438bada24f136f96"
16+
graalVmSha256-macos-aarch64 = "c00a7a62ce453aa026bff65e5a18c63464f725c01e5a71771856226928ba5b0f"
17+
graalVmSha256-linux-x64 = "46ec9582ebe114f93470403f2cc123238ac0c7982129c358af7d8e1de52dd663"
18+
graalVmSha256-linux-aarch64 = "1835a98b87c439c8c654d97956c22d409855952e5560a8127f56c50f3f919d7d"
19+
graalVmSha256-windows-x64 = "e758646504cfaf23cf218a22691ad70491f3196448a77d03d78e50dff2145533"
2020
ideaExtPlugin = "1.1.9"
2121
javaPoet = "0.+"
2222
javaxInject = "1"
@@ -44,7 +44,7 @@ msgpack = "0.9.8"
4444
nexusPublishPlugin = "2.0.0"
4545
nuValidator = "20.+"
4646
paguro = "3.+"
47-
shadowPlugin = "8.1.1"
47+
shadowPlugin = "8.3.5"
4848
slf4j = "1.+"
4949
snakeYaml = "2.+"
5050
spotlessPlugin = "6.25.0"
@@ -88,14 +88,16 @@ nuValidator = { group = "nu.validator", name = "validator", version.ref = "nuVal
8888
# to be replaced with https://github.com/usethesource/capsule or https://github.com/lacuna/bifurcan
8989
paguro = { group = "org.organicdesign", name = "Paguro", version.ref = "paguro" }
9090
pklConfigJavaAll025 = { group = "org.pkl-lang", name = "pkl-config-java-all", version = "0.25.0" }
91-
shadowPlugin = { group = "com.github.johnrengelman", name = "shadow", version.ref = "shadowPlugin" }
91+
shadowPlugin = { group = "com.gradleup.shadow", name = "shadow-gradle-plugin", version.ref = "shadowPlugin" }
9292
slf4jApi = { group = "org.slf4j", name = "slf4j-api", version.ref = "slf4j" }
9393
slf4jSimple = { group = "org.slf4j", name = "slf4j-simple", version.ref = "slf4j" }
9494
snakeYaml = { group = "org.snakeyaml", name = "snakeyaml-engine", version.ref = "snakeYaml" }
9595
spotlessPlugin = { group = "com.diffplug.spotless", name = "spotless-plugin-gradle", version.ref = "spotlessPlugin"}
9696
svm = { group = "org.graalvm.nativeimage", name = "svm", version.ref = "graalVm" }
9797
truffleApi = { group = "org.graalvm.truffle", name = "truffle-api", version.ref = "graalVm" }
9898
truffleDslProcessor = { group = "org.graalvm.truffle", name = "truffle-dsl-processor", version.ref = "graalVm" }
99+
truffleSvm = { group = "org.graalvm.nativeimage", name = "truffle-runtime-svm", version.ref = "graalVm" }
100+
truffleRuntime = { group = "org.graalvm.truffle", name = "truffle-runtime", version.ref = "graalVm" }
99101
wiremock = { group = "org.wiremock", name = "wiremock", version.ref = "wiremock" }
100102

101103
[plugins] # ordered alphabetically
@@ -104,4 +106,4 @@ ideaExt = { id = "org.jetbrains.gradle.plugin.idea-ext", version.ref = "ideaExtP
104106
jmh = { id = "me.champeau.jmh", version.ref = "jmhPlugin" }
105107
kotlinxSerialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" }
106108
nexusPublish = { id = "io.github.gradle-nexus.publish-plugin", version.ref = "nexusPublishPlugin" }
107-
shadow = { id = "com.github.johnrengelman.shadow", version.ref = "shadowPlugin" }
109+
shadow = { id = "com.gradleup.shadow", version.ref = "shadowPlugin" }

gradle/wrapper/gradle-wrapper.properties

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
distributionBase=GRADLE_USER_HOME
22
distributionPath=wrapper/dists
3-
distributionSha256Sum=57dafb5c2622c6cc08b993c85b7c06956a2f53536432a30ead46166dbca0f1e9
4-
distributionUrl=https\://services.gradle.org/distributions/gradle-8.11-bin.zip
3+
distributionSha256Sum=7a00d51fb93147819aab76024feece20b6b84e420694101f276be952e08bef03
4+
distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-bin.zip
55
networkTimeout=10000
66
validateDistributionUrl=true
77
zipStoreBase=GRADLE_USER_HOME

gradlew

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,8 +86,7 @@ done
8686
# shellcheck disable=SC2034
8787
APP_BASE_NAME=${0##*/}
8888
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
89-
APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s
90-
' "$PWD" ) || exit
89+
APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit
9190

9291
# Use the maximum available, or set MAX_FD != -1 to use that value.
9392
MAX_FD=maximum

pkl-cli/pkl-cli.gradle.kts

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,12 +50,16 @@ val stagedWindowsAmd64Executable: Configuration by configurations.creating
5050

5151
dependencies {
5252
compileOnly(libs.svm)
53+
compileOnly(libs.truffleSvm)
54+
implementation(libs.truffleRuntime)
5355

5456
// CliEvaluator exposes PClass
5557
api(projects.pklCore)
5658
// CliEvaluatorOptions exposes CliBaseOptions
5759
api(projects.pklCommonsCli)
5860

61+
compileOnly(libs.graalSdk)
62+
5963
implementation(projects.pklCommons)
6064
implementation(libs.jansi)
6165
implementation(libs.jlineReader)
@@ -107,12 +111,19 @@ val javaExecutable by
107111
inJar.set(tasks.shadowJar.flatMap { it.archiveFile })
108112
outJar.set(layout.buildDirectory.file("executable/jpkl"))
109113

114+
jvmArgs.addAll("--add-modules=jdk.unsupported")
115+
110116
// uncomment for debugging
111117
// jvmArgs.addAll("-ea", "-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=5005")
112118
}
113119

114120
val testJavaExecutable by
115121
tasks.registering(Test::class) {
122+
javaLauncher =
123+
javaToolchains.launcherFor {
124+
languageVersion = JavaLanguageVersion.of(21)
125+
vendor = JvmVendorSpec.GRAAL_VM
126+
}
116127
testClassesDirs = tasks.test.get().testClassesDirs
117128
classpath =
118129
// compiled test classes
@@ -179,7 +190,7 @@ fun Exec.configureExecutable(
179190
executable = "${graalVm.baseDir}/bin/$nativeImageCommandName"
180191

181192
// JARs to exclude from the class path for the native-image build.
182-
val exclusions = listOf(libs.truffleApi, libs.graalSdk).map { it.get().module.name }
193+
val exclusions = listOf(libs.graalSdk).map { it.get().module.name }
183194
// https://www.graalvm.org/22.0/reference-manual/native-image/Options/
184195
argumentProviders.add(
185196
CommandLineArgumentProvider {
@@ -190,13 +201,15 @@ fun Exec.configureExecutable(
190201
// needed for messagepack-java (see https://github.com/msgpack/msgpack-java/issues/600)
191202
add("--initialize-at-run-time=org.msgpack.core.buffer.DirectBufferAccess")
192203
add("--no-fallback")
204+
// must be emitted before any experimental options are used
205+
add("-H:+UnlockExperimentalVMOptions")
193206
add("-H:IncludeResources=org/pkl/core/stdlib/.*\\.pkl")
194207
add("-H:IncludeResources=org/jline/utils/.*")
195208
add("-H:IncludeResourceBundles=org.pkl.core.errorMessages")
196209
add("-H:IncludeResources=org/pkl/commons/cli/PklCARoots.pem")
197-
add("--macro:truffle")
198210
add("-H:Class=org.pkl.cli.Main")
199-
add("-H:Name=${outputFile.get().asFile.name}")
211+
add("-o")
212+
add(outputFile.get().asFile.name)
200213
// the actual limit (currently) used by native-image is this number + 1400 (idea is to
201214
// compensate for Truffle's own nodes)
202215
add("-H:MaxRuntimeCompileMethods=1800")
@@ -210,8 +223,20 @@ fun Exec.configureExecutable(
210223
// executable
211224
if (!buildInfo.isReleaseBuild) {
212225
add("-Ob")
226+
} else {
227+
add("-Os")
228+
}
229+
if (buildInfo.isNativeArch) {
230+
add("-march=native")
231+
} else {
232+
add("-march=compatibility")
233+
}
234+
if (buildInfo.isEnableOracleGraalvm) {
235+
add("--gc=G1")
236+
add("--enable-sbom=cyclonedx")
237+
} else {
238+
add("--gc=serial")
213239
}
214-
add("-march=compatibility")
215240
// native-image rejects non-existing class path entries -> filter
216241
add("--class-path")
217242
val pathInput =
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
2+
Args = --initialize-at-build-time=org.pkl.core

0 commit comments

Comments
 (0)