Skip to content

Commit a7ff738

Browse files
phraktleclaude
andauthored
build(deps): bump Gradle wrapper to 9.4.1 and LWJGL to 3.4.1 (#383)
* build(deps): bump Gradle wrapper 8.14.3 -> 9.4.1 and LWJGL 3.3.6 -> 3.4.1 Gradle 9.x is required for local builds on JDK 25+ -- Gradle 8.14.3's bundled Kotlin fails to parse recent JDK version strings (IllegalArgumentException: 26). Gradle 9.4.1's Kotlin 2.x handles all current JDKs. LWJGL 3.4.1 is a minor bump with no binding-visible API breaks. Verified: binding compile, native generateLibs, and :example:run (with the existing ImPlot showcase) all green on JDK 26 + macOS arm64. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * build: make build.gradle Gradle 9 configuration-cache compatible Paired with the Gradle 9.4.1 wrapper bump: make the root and imgui-binding build scripts usable under Gradle 9's configuration cache (the default for downstream consumers on Gradle 9+). Three changes: - build.gradle: replace Groovy 'git describe'.execute() with providers.exec (cache-aware external process API). Same for 'git rev-parse HEAD' in the jar manifest block. - imgui-binding/build.gradle: capture project.version.toString() into a local at configuration time, and pass that through the processResources filesMatching closure rather than letting the closure resolve `version` against the live Project model at execution time. Without this, any downstream consumer running Gradle 9 with configuration cache on (including `includeBuild` composite builds) hits: - Starting an external process 'git describe --tags --always' during configuration time is unsupported. - Invocation of 'version' references a Gradle script object from a Groovy closure at execution time, which is unsupported with the configuration cache. Verified: `./gradlew :imgui-binding:compileJava --configuration-cache` now stores a configuration cache entry cleanly on Gradle 9.4.1. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix(buildSrc): make generateApi work under Gradle 9 / Kotlin 2 K2 Kotlin 2.x's K2 compiler emits a runtime CHECKCAST to java.lang.Void at generic call sites where the type argument is specified as Nothing. That checkcast was elided under K1, but K1 is gone in Kotlin 2.0. The codegen used `<Nothing>` extensively on Spoon's builder-style setters (setType, setSimpleName, setParent, addParameter, etc.) as a "don't care" type argument, since Nothing is the bottom type and therefore a subtype of every bound. Under K2 those calls throw ClassCastException because Spoon returns concrete CtMethodImpl etc., not Void. Replace each <Nothing> with the bound-appropriate type so no Void checkcast is emitted: setType -> CtTypedElement<Any> setSimpleName -> CtNamedElement (or CtReference on type refs) setParent -> CtElement setDocComment -> CtElement setAnnotations -> CtElement addAnnotation -> CtElement addModifier -> CtModifiable setModifiers -> CtModifiable addParameter -> CtMethod<Any> addParameterAt -> CtMethod<Any> setParameters -> CtMethod<Any> setBody -> CtBodyHolder addStatement -> CtStatementList setTags -> CtJavaDoc removeTag -> CtJavaDoc setValue -> CtCodeSnippet addValue -> CtAnnotation<Annotation> setAssignment -> CtRHSReceiver<Any> createMethod -> Any (unbounded) createField -> Any createParameter -> Any createTypeReference -> Any (or Annotation for createAnnotation chain) `method.clone()` sites cast to CtMethod<Any> with @Suppress because CtMethod<*>.setParameters<T : CtExecutable<captured *>> has no T that Kotlin can infer or accept. * build: bump build toolchain to JDK 17, keep Java 8 bytecode target Gradle 9's default checkstyle toolVersion (~10.21+) requires Java 11+ to run, but every module pinned a Java 8 toolchain, so Gradle routed the Checkstyle task's launcher through JDK 8 and the Ant task class (class file version 55) failed to load on the JDK 8 runtime. Rather than pin an old checkstyle or splice a separate launcher just for Checkstyle, bump the build toolchain to JDK 17 in every module and set `options.release = 8` on the library modules. Net effect: - compile/checkstyle/javadoc all run on the same modern JVM - published jars still contain class file version 52 (Java 8) — the library's consumer baseline is unchanged (verified on ImGui.class) - CI only needs to install JDK 17 (dropped the dual 8+17 setup) Also bump foojay-resolver-convention 0.10.0 -> 1.0.0. Gradle 9 removed JvmVendorSpec.IBM_SEMERU; the 0.10.0 plugin references it in its <clinit>, so any local build that has to download a toolchain (no matching JDK already installed) crashes with NoSuchFieldError before reaching the task graph. CI didn't hit this because setup-java pre-installs the JDKs. Verified: ./gradlew buildAll green on JDK 25 / macOS arm64; javap on the produced ImGui.class reports major version 52. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 2fcd517 commit a7ff738

14 files changed

Lines changed: 323 additions & 275 deletions

File tree

.github/workflows/ci.yml

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,7 @@ jobs:
2424
uses: actions/setup-java@v5
2525
with:
2626
distribution: liberica
27-
java-version: |
28-
8
29-
17
27+
java-version: 17
3028

3129
- name: Setup Gradle
3230
uses: gradle/actions/setup-gradle@v5
@@ -73,9 +71,7 @@ jobs:
7371
uses: actions/setup-java@v5
7472
with:
7573
distribution: liberica
76-
java-version: |
77-
8
78-
17
74+
java-version: 17
7975

8076
- name: Setup Gradle
8177
uses: gradle/actions/setup-gradle@v5
@@ -162,9 +158,7 @@ jobs:
162158
uses: actions/setup-java@v5
163159
with:
164160
distribution: liberica
165-
java-version: |
166-
8
167-
17
161+
java-version: 17
168162

169163
- name: Setup Gradle
170164
uses: gradle/actions/setup-gradle@v5

build.gradle

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,24 @@ import tool.generator.ast.task.GenerateAst
33
import java.text.SimpleDateFormat
44

55
ext {
6-
lwjglVersion = '3.3.6'
6+
lwjglVersion = '3.4.1'
77
}
88

9+
// Gradle 9's configuration cache forbids starting external processes at
10+
// configuration time via Groovy's '...'.execute() (the cache can't know
11+
// if the result would be different next time). Use providers.exec, which
12+
// is cache-aware.
13+
def gitDescribeProvider = providers.exec {
14+
commandLine 'git', 'describe', '--tags', '--always'
15+
}.standardOutput.asText.map { it.trim().startsWith('v') ? it.trim().substring(1) : it.trim() }.orElse('unknown')
16+
17+
def gitRevProvider = providers.exec {
18+
commandLine 'git', 'rev-parse', 'HEAD'
19+
}.standardOutput.asText.map { it.trim() }.orElse('unknown')
20+
921
allprojects {
1022
group = 'imgui-java'
11-
version = 'git describe --tags --always'.execute().text.trim().substring(1)
23+
version = gitDescribeProvider.get()
1224

1325
repositories {
1426
mavenCentral()
@@ -23,13 +35,14 @@ allprojects {
2335

2436
def jdkMetadata = tasks.withType(JavaCompile).find().javaCompiler.get().metadata
2537
def buildJdk = "${jdkMetadata.javaRuntimeVersion} (${jdkMetadata.vendor})".toString()
38+
def buildRev = gitRevProvider.get()
2639

2740
manifest {
2841
attributes (
2942
'Implementation-Title': project.name,
3043
'Implementation-Version': project.version,
3144
'Build-Timestamp': new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ").format(System.currentTimeMillis()),
32-
'Build-Revision': 'git rev-parse HEAD'.execute().text.trim(),
45+
'Build-Revision': buildRev,
3346
'Build-Jdk': buildJdk,
3447
'Source-Compatibility': tasks.withType(JavaCompile).find().sourceCompatibility,
3548
'Target-Compatibility': tasks.withType(JavaCompile).find().targetCompatibility,

buildSrc/src/main/kotlin/tool/generator/api/BindingSourceProcessor.kt

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@ import spoon.reflect.code.CtJavaDoc
44
import spoon.reflect.declaration.CtElement
55
import spoon.reflect.declaration.CtField
66
import spoon.reflect.declaration.CtMethod
7+
import spoon.reflect.declaration.CtNamedElement
78
import spoon.reflect.declaration.CtType
9+
import spoon.reflect.declaration.CtTypedElement
810
import kotlin.math.max
911

1012
class BindingSourceProcessor(
@@ -135,13 +137,13 @@ class BindingSourceProcessor(
135137

136138
for (i in 0 until variantsCount) {
137139
val m = method.clone()
138-
m.setParent<Nothing>(method.parent)
140+
m.setParent<CtElement>(method.parent)
139141
variantsMap.values.forEach { vList ->
140142
val v = vList[i]
141143
val p = m.parameters[v.idx]
142-
p.setAnnotations<Nothing>(p.annotations.filterNot { it.name == A_NAME_ARG_VARIANT })
143-
p.setType<Nothing>(m.factory.createTypeParameterReference(v.type))
144-
p.setSimpleName<Nothing>(v.name)
144+
p.setAnnotations<CtElement>(p.annotations.filterNot { it.name == A_NAME_ARG_VARIANT })
145+
p.setType<CtTypedElement<Any>>(m.factory.createTypeParameterReference(v.type))
146+
p.setSimpleName<CtNamedElement>(v.name)
145147
}
146148
content += jvmMethodContent(m) + jniMethodContent(m)
147149
}

buildSrc/src/main/kotlin/tool/generator/api/ast_content.kt

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
package tool.generator.api
22

3+
import spoon.reflect.code.CtRHSReceiver
34
import spoon.reflect.declaration.CtAnnotation
5+
import spoon.reflect.declaration.CtElement
6+
import spoon.reflect.declaration.CtModifiable
7+
import spoon.reflect.declaration.CtNamedElement
8+
import spoon.reflect.declaration.CtTypedElement
49
import spoon.reflect.declaration.ModifierKind
510
import tool.generator.ast.AstEnumConstantDecl
611
import tool.generator.ast.AstParser
@@ -19,11 +24,11 @@ fun astEnumContent(markerAnnotation: CtAnnotation<*>): List<String> {
1924
val factory = markerAnnotation.factory
2025

2126
enums.forEach { e ->
22-
val f = factory.createField<Nothing>()
27+
val f = factory.createField<Any>()
2328

24-
f.setModifiers<Nothing>(setOf(ModifierKind.PUBLIC, ModifierKind.STATIC, ModifierKind.FINAL))
25-
f.setType<Nothing>(factory.createTypeParam("int"))
26-
f.setSimpleName<Nothing>(sanitizeName(markerAnnotation.getValueSanitizeName(qualType), e.name))
29+
f.setModifiers<CtModifiable>(setOf(ModifierKind.PUBLIC, ModifierKind.STATIC, ModifierKind.FINAL))
30+
f.setType<CtTypedElement<Any>>(factory.createTypeParam("int"))
31+
f.setSimpleName<CtNamedElement>(sanitizeName(markerAnnotation.getValueSanitizeName(qualType), e.name))
2732
buildString {
2833
if (e.docComment != null) {
2934
appendLine(e.docComment)
@@ -37,10 +42,10 @@ fun astEnumContent(markerAnnotation: CtAnnotation<*>): List<String> {
3742
}
3843
}.let {
3944
if (it.isNotEmpty()) {
40-
f.setDocComment<Nothing>(sanitizeDocComment(it))
45+
f.setDocComment<CtElement>(sanitizeDocComment(it))
4146
}
4247
}
43-
f.setAssignment<Nothing>(factory.createCodeSnippetExpression((e.evaluatedValue ?: e.order).toString()))
48+
f.setAssignment<CtRHSReceiver<Any>>(factory.createCodeSnippetExpression((e.evaluatedValue ?: e.order).toString()))
4449

4550
result += f.prettyprint()
4651
}

0 commit comments

Comments
 (0)