Release builds and optimization
AwakeKt publishes its libraries as plain, unshrunk artifacts. Shrinking and obfuscation happen when your app's release is built, and AwakeKt ships the keep rules that build needs.
Where optimization happens
AwakeKt does not minify, shrink or obfuscate the libraries it publishes. Class names, method names
and Kotlin metadata in a published jar, AAR or klib are the ones in the source, so stack traces,
IDE navigation and debugging against a dependency work as usual. Each artifact also has a sources
jar, which IDEs read for KDoc, and a placeholder documentation jar that Maven Central requires.
The API reference is built by ./gradlew developerDocs and published on this site, not as a
javadoc jar.
Your app's release build does the optimizing, on the whole program: your code and every library it uses together. That is what lets it remove classes nothing reaches and rename the rest.
| Artifact | Published as | Optimized when AwakeKt publishes it? | What your release build does | Keep rules AwakeKt ships |
|---|---|---|---|---|
Desktop JVM (*-desktop) |
A jar with classes, a sources jar and an empty documentation jar. The Vulkan bindings (vulkan-kmp) and shader compiler jars also hold their native libraries under natives/<platform>/. |
No | ProGuard through Compose Desktop's buildTypes.release.proguard, or any other jar shrinker you use. |
A module whose native code finds classes by name holds its rules in the jar at META-INF/proguard/, named for the module, such as awake-engine-window.pro. |
Android (*-android) |
A release AAR. The shader compiler's AAR holds jni/<abi>/libawake_naga.so, and vulkan-kmp-android-native holds the Vulkan bindings' Android library. |
No | R8, when the app sets isMinifyEnabled = true, plus resource shrinking when it sets isShrinkResources = true. |
The same rules, as the AAR's proguard.txt. R8 applies them with no setup. |
iOS (iosArm64, iosSimulatorArm64) |
A Kotlin/Native klib. | No | The Kotlin/Native compiler links the klibs into your app's framework. | None. Keep rules are for JNI, which iOS does not have. |
Web (wasmJs) |
A Kotlin/Wasm klib. | No | The production executable (wasmJsBrowserDistribution) is built by the Kotlin Gradle plugin, which optimizes it with Binaryen. AwakeKt sets no optimization options of its own. |
None. There is no JNI in the browser. |
Platform BOM (com.awakekt.awake:bom) |
A POM and Gradle module metadata. | Not applicable | Nothing. It only constrains versions. | None. |
The Kotlin Multiplatform root publication (com.awakekt.awake.<group>:<module>) holds metadata that
points Gradle at the platform artifacts above; a Gradle build picks the one for each target.
If published size matters to you, the sources jar and the placeholder documentation jar are not part of what an app ships, and your release build removes what it does not reach. AwakeKt has not measured per-platform changes to what it publishes; a change to the published artifacts would need that measurement and a compatibility check first.
Keep rules
Native code finds some classes by name: JNI binds each Java_… function to a class and method
name, and calls such as FindClass name a class directly. A release build that renames such a
class fails at launch, or the first time that path runs. These modules keep what their native code
names:
| Module | Rules file | What it keeps |
|---|---|---|
com.awakekt.awake.engine:window |
awake/engine/window/consumer-rules.pro |
The native methods of GlfwWindow and GlfwGamepad. |
com.awakekt.awake:vulkan-kmp |
awake/backend/vulkan/bindings/consumer-rules.pro |
The bindings' types, which the native library builds and reads by name. |
com.awakekt.awake.asset:shader-compiler |
awake/asset/shader-compiler/consumer-rules.pro |
The Naga bindings' native methods and NagaException. |
com.awakekt.awake.backend:jolt |
awake/backend/jolt/consumer-rules.pro |
The backend's classes and all of jolt-jni's, whose native library calls back into them by name. |
You add nothing for these. Add a rule only for a class that your own code, or a library AwakeKt does
not ship, finds by name, in proguard-rules.pro of your Android app and of your desktop app.
Compose Desktop's ProGuard does not read META-INF/proguard from your dependencies, as R8 does.
The starter templates collect the rules from your runtime classpath and pass them on; copy the
libraryKeepRules task from templates/project/app/desktopApp/build.gradle.kts into a desktop app
that shrinks with Compose Desktop.
What checks this
| Check | What it proves | When it runs |
|---|---|---|
./gradlew verifyKeepRules, part of awakeVerify |
Every class that an AwakeKt module's native sources name is kept by that module's consumer-rules.pro. It cannot see what a third-party native library reaches. |
Every pull request |
./gradlew verifyPublishedArtifacts |
A published vulkan-kmp desktop jar holds its native libraries, and the shader compiler's Android AAR holds libawake_naga.so for each ABI. It does not check for optimization. |
Release publication |
Obfuscated templates workflow, tools/check_obfuscated_template.sh |
Both starter templates' release builds, shrunk and obfuscated as above, run against the Core published from the same commit. The desktop release is checked to be obfuscated, then plays frames in a window and renders a frame with no window. The Android release launches on an emulator. The web build is produced. A control run without the window's keep rules must fail at its native call, so a missing rule fails the check. | Nightly, and on a pull request that touches the templates or the check |
The Android release of the showcase sample (samples/engine-showcase/androidApp) also sets
isMinifyEnabled = true with no keep rules of its own, and the nightly device tests launch it.
Configure a release build
The starter project template is the working example of all three:
| Target | Where to look |
|---|---|
| Android | release in templates/project/app/androidApp/build.gradle.kts: isMinifyEnabled = true, isShrinkResources = true, and proguard-android-optimize.txt plus your proguard-rules.pro. |
| Desktop | buildTypes.release.proguard in templates/project/app/desktopApp/build.gradle.kts: obfuscate, ProGuard 7.10.0, your proguard-rules.pro and the collected library rules. |
| Web | wasmJsBrowserDistribution in templates/project/app/webApp, with no optimization settings of its own. |
Build them with the commands in the template's "Ship it" section:
./gradlew :app:desktopApp:packageReleaseDistributionForCurrentOS # desktop installer
./gradlew :app:androidApp:assembleRelease # Android APK
./gradlew :app:webApp:wasmJsBrowserDistribution # web
Test the shrunk build, not just the debug build
A missing keep rule shows up only in the release. Run it, as the Obfuscated templates check does. Vulkan backend lists the two system properties that play a fixed number of frames, or render one frame with no window, for a CI job.