Skip to content

Commit

Permalink
chore: use jsonc config file for gvm class init config
Browse files Browse the repository at this point in the history
Signed-off-by: Sam Gammon <sam@elide.dev>
  • Loading branch information
sgammon committed Jan 24, 2025
1 parent 44fa960 commit cd6e20d
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 0 deletions.
6 changes: 6 additions & 0 deletions buildSrc/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,14 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
@file:Suppress("UnstableApiUsage")

import org.jetbrains.kotlin.gradle.dsl.JvmTarget

plugins {
`kotlin-dsl`
`jvm-toolchains`
embeddedKotlin("plugin.serialization")
}

// Keep this in sync with the constants in `BuildInfo.kt` (those are not addressable here).
Expand All @@ -30,6 +33,9 @@ dependencies {
implementation(libs.kotlinPlugin) { exclude(module = "kotlin-android-extensions") }
implementation(libs.shadowPlugin)

// used to load graalvm configs
implementation(libs.kotlinxSerializationJson)

// fix from the Gradle team: makes version catalog symbols available in build scripts
// see here for more: https://github.com/gradle/gradle/issues/15383
implementation(files(libs.javaClass.superclass.protectionDomain.codeSource.location))
Expand Down
14 changes: 14 additions & 0 deletions buildSrc/src/main/kotlin/BuildInfo.kt
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,15 @@
*/
@file:Suppress("MemberVisibilityCanBePrivate")

import kotlinx.serialization.json.Json
import kotlinx.serialization.json.decodeFromStream
import java.io.File
import org.gradle.api.Project
import org.gradle.api.Task
import org.gradle.api.artifacts.VersionCatalog
import org.gradle.api.artifacts.VersionCatalogsExtension
import org.gradle.api.attributes.Category
import org.gradle.api.file.RegularFile
import org.gradle.api.provider.Provider
import org.gradle.api.tasks.TaskProvider
import org.gradle.api.tasks.testing.Test
Expand All @@ -31,6 +34,7 @@ import org.gradle.kotlin.dsl.getByType
import org.gradle.kotlin.dsl.register
import org.gradle.kotlin.dsl.support.serviceOf
import org.gradle.process.CommandLineArgumentProvider
import java.nio.charset.StandardCharsets

/**
* JVM bytecode target; this is pinned at a reasonable version, because downstream JVM projects
Expand Down Expand Up @@ -178,6 +182,16 @@ open class BuildInfo(private val project: Project) {
JavaVersionRange.inclusive(jdkTestFloor, jdkTestCeiling)
}

/**
* Read a configuration file for GraalVM initialization.
*/
fun graalvmConfig(file: RegularFile): GraalVmInitializationConfig =
file.asFile.reader(StandardCharsets.UTF_8).use {
Json.decodeFromString(it.readText().lineSequence().filter { line ->
!line.trim().startsWith("//") // filter out comments
}.joinToString("\n"))
}

private fun JavaToolchainSpec.pklJdkToolchain() {
languageVersion.set(jdkToolchainVersion)
vendor.set(jdkVendor)
Expand Down
27 changes: 27 additions & 0 deletions buildSrc/src/main/kotlin/GraalVmInitializationConfig.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import kotlinx.serialization.Serializable

/**
* Models the structure of a simple JSON config file for classes and packages which should be
* initialized at build time or run time by the GraalVM Native Image compiler.
*
* @property initializeAtBuildTime A list of fully qualified class names or package names which
* should be initialized at build time.
* @property initializeAtRunTime A list of fully qualified class names or package names which
* should be initialized at run time.
*/
@JvmRecord
@Serializable
data class GraalVmInitializationConfig(
val initializeAtBuildTime: List<String> = emptyList(),
val initializeAtRunTime: List<String> = emptyList(),
) {
/**
* Return as a serialized list of string arguments that can be supplied to the Native Image
* compiler.
*/
val asArgs: List<String> get() =
buildList {
addAll(initializeAtBuildTime.map { "--initialize-at-build-time=$it" })
addAll(initializeAtRunTime.map { "--initialize-at-run-time=$it" })
}
}
10 changes: 10 additions & 0 deletions pkl-cli/pkl-cli.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
* limitations under the License.
*/
import org.gradle.kotlin.dsl.support.serviceOf
import java.nio.file.Path

plugins {
pklAllProjects
Expand Down Expand Up @@ -200,11 +201,16 @@ tasks.check {
)
}

val classInitConfig = layout.projectDirectory.file(Path.of("config", "classinit.jsonc").toString())

fun Exec.configureExecutable(
graalVm: BuildInfo.GraalVm,
outputFile: Provider<RegularFile>,
extraArgs: List<String> = listOf(),
) {
inputs.file(classInitConfig)
val classinit = buildInfo.graalvmConfig(classInitConfig)

inputs
.files(sourceSets.main.map { it.output })
.withPropertyName("mainSourceSets")
Expand Down Expand Up @@ -235,6 +241,10 @@ fun Exec.configureExecutable(
// currently gives a deprecation warning, but we've been told
// that the "initialize everything at build time" *CLI* option is likely here to stay
add("--initialize-at-build-time=")
if (JavaVersion.current() == JavaVersion.VERSION_21)
add("--strict-image-heap")
// load, compute, and configure class initialization
addAll(classinit.asArgs)
// needed for messagepack-java (see https://github.com/msgpack/msgpack-java/issues/600)
add("--initialize-at-run-time=org.msgpack.core.buffer.DirectBufferAccess")
add("--no-fallback")
Expand Down

0 comments on commit cd6e20d

Please sign in to comment.