ajalt / mordant

Multiplatform text styling for Kotlin command-line applications
https://ajalt.github.io/mordant/
Apache License 2.0
935 stars 33 forks source link

EmojiseqtableKt.class is too big #160

Closed madisp closed 4 months ago

madisp commented 4 months ago

Hi, we're using mordant through clikt together with R8 minifier to produce a single minified jar file.

Running R8 version 8.3.37 on Mordant fails due to EmojiseqtableKt class being too big, maybe there's a way to split it into multiple class files?

Error in /home/gh-actions0/actions-runner/_work/warp-speed/warp-speed/cli/build/libs/cli-all.jar:com/github/ajalt/mordant/internal/gen/EmojiseqtableKt.class at Lq/c;a()Lq/d;:
> Task :cli:minify
Method Lq/c;a()Lq/d; too large for class file. Code size was 67349.

> Task :cli:minify FAILED
FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':cli:minify'.
> com.android.tools.r8.CompilationFailedException: Compilation failed to complete, position: Lq/c;a()Lq/d;, origin: /home/gh-actions0/actions-runner/_work/warp-speed/warp-speed/cli/build/libs/cli-all.jar:com/github/ajalt/mordant/internal/gen/EmojiseqtableKt.class
ajalt commented 4 months ago

Hm, that's strange. We build an r8 jar on CI, which succeeds on r8 version 8.1.72. I wonder what changed in r8 to start failing.

JakeWharton commented 4 months ago

It's highly unlikely that anything changed with regard to the int array or object array initialization, so perhaps something changed that actually enabled more optimization around this snippet:

https://github.com/ajalt/mordant/blob/b0eb5928b4d8802d29c63643be3071f8b51405b7/mordant/src/commonMain/kotlin/com/github/ajalt/mordant/internal/gen/emojiseqtable.kt#L2827-L2835

and it resulted in code being inlined and blowing the limit.

It sounds like you're already dangerously close to the limit anyway, so future unicode updates could push the regular classfile compilation over. Probably best to preemptively shard the array initialization into a couple partitioned functions rather than having it inline.

TWiStErRob commented 4 months ago

Reported to R8: https://issuetracker.google.com/issues/329678175 I think R8-ing shouldn't "break" on otherwise working code, right?

@ajalt do you have plans to release Clikt with Mordant 2.4.0?

Until then, workaround is easy:

implementation("com.github.ajalt.clikt:clikt:4.2.2")
// TODO delete when https://github.com/ajalt/mordant/issues/160 is released in Clikt.
implementation("com.github.ajalt.mordant:mordant:2.4.0")

Update: fixed in com.android.tools:r8:8.4.21 to be released when AGP 8.4 is stable, until then, we can use from maven { url = uri("https://storage.googleapis.com/r8-releases/raw") }