Skip to content

Commit 6d8bfd8

Browse files
committed
Massic desktop release build size and performance improvements
1 parent 97422d3 commit 6d8bfd8

3 files changed

Lines changed: 136 additions & 13 deletions

File tree

.github/workflows/android.yml

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -159,12 +159,12 @@ jobs:
159159
- name: Set execution flag for gradlew
160160
run: chmod +x gradlew
161161
- name: Build DMG
162-
run: bash ./gradlew :desktopApp:packageDmg --stacktrace
162+
run: bash ./gradlew :desktopApp:packageReleaseDmg --stacktrace
163163
- name: Upload DMG Artifact
164164
uses: actions/upload-artifact@v4
165165
with:
166166
name: dmg-package
167-
path: desktopApp/build/compose/binaries/main/dmg/*.dmg
167+
path: desktopApp/build/compose/binaries/main-release/dmg/*.dmg
168168

169169
msi:
170170
name: Generate MSI
@@ -178,12 +178,12 @@ jobs:
178178
distribution: temurin
179179
java-version: "17"
180180
- name: Build MSI
181-
run: ./gradlew :desktopApp:packageMsi --stacktrace
181+
run: ./gradlew :desktopApp:packageReleaseMsi --stacktrace
182182
- name: Upload MSI Artifact
183183
uses: actions/upload-artifact@v4
184184
with:
185185
name: msi-package
186-
path: desktopApp/build/compose/binaries/main/msi/*.msi
186+
path: desktopApp/build/compose/binaries/main-release/msi/*.msi
187187

188188
deb:
189189
name: Generate DEB
@@ -199,12 +199,12 @@ jobs:
199199
- name: Set execution flag for gradlew
200200
run: chmod +x gradlew
201201
- name: Build DEB
202-
run: ./gradlew :desktopApp:packageDeb --stacktrace
202+
run: ./gradlew :desktopApp:packageReleaseDeb --stacktrace
203203
- name: Upload DEB Artifact
204204
uses: actions/upload-artifact@v4
205205
with:
206206
name: deb-package
207-
path: desktopApp/build/compose/binaries/main/deb/*.deb
207+
path: desktopApp/build/compose/binaries/main-release/deb/*.deb
208208

209209
rpm:
210210
name: Generate RPM
@@ -222,12 +222,12 @@ jobs:
222222
- name: Install RPM build tools
223223
run: sudo apt-get update && sudo apt-get install -y rpm
224224
- name: Build RPM
225-
run: ./gradlew :desktopApp:packageRpm --stacktrace
225+
run: ./gradlew :desktopApp:packageReleaseRpm --stacktrace
226226
- name: Upload RPM Artifact
227227
uses: actions/upload-artifact@v4
228228
with:
229229
name: rpm-package
230-
path: desktopApp/build/compose/binaries/main/rpm/*.rpm
230+
path: desktopApp/build/compose/binaries/main-release/rpm/*.rpm
231231

232232
linux-tar:
233233
name: Generate Linux Tarball
@@ -243,12 +243,12 @@ jobs:
243243
- name: Set execution flag for gradlew
244244
run: chmod +x gradlew
245245
- name: Build application distribution
246-
run: ./gradlew :desktopApp:createDistributable --stacktrace
246+
run: ./gradlew :desktopApp:createReleaseDistributable --stacktrace
247247
- name: Copy icon into distributable
248-
run: cp desktopApp/icon.png desktopApp/build/compose/binaries/main/app/LinuxCommandLibrary/lib/LinuxCommandLibrary.png
248+
run: cp desktopApp/icon.png desktopApp/build/compose/binaries/main-release/app/LinuxCommandLibrary/lib/LinuxCommandLibrary.png
249249
- name: Package tarball
250250
run: |
251-
cd desktopApp/build/compose/binaries/main/app
251+
cd desktopApp/build/compose/binaries/main-release/app
252252
tar czf "$GITHUB_WORKSPACE/LinuxCommandLibrary-linux-x86_64.tar.gz" LinuxCommandLibrary
253253
- name: Upload Tarball Artifact
254254
uses: actions/upload-artifact@v4
@@ -276,7 +276,7 @@ jobs:
276276
wget -q https://github.com/AppImage/appimagetool/releases/download/continuous/appimagetool-x86_64.AppImage
277277
chmod +x appimagetool-x86_64.AppImage
278278
- name: Build application distribution
279-
run: ./gradlew :desktopApp:createDistributable --stacktrace
279+
run: ./gradlew :desktopApp:createReleaseDistributable --stacktrace
280280
- name: Create AppDir structure
281281
run: |
282282
mkdir -p AppDir/usr/bin
@@ -285,7 +285,7 @@ jobs:
285285
mkdir -p AppDir/usr/share/icons/hicolor/256x256/apps
286286
287287
# Copy distributable contents
288-
cp -r desktopApp/build/compose/binaries/main/app/LinuxCommandLibrary/* AppDir/usr/lib/
288+
cp -r desktopApp/build/compose/binaries/main-release/app/LinuxCommandLibrary/* AppDir/usr/lib/
289289
290290
# Copy icon
291291
cp desktopApp/icon.png AppDir/usr/share/icons/hicolor/256x256/apps/linuxcommandlibrary.png

desktopApp/build.gradle.kts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import org.jetbrains.compose.desktop.application.dsl.TargetFormat
2+
import org.jetbrains.compose.desktop.application.tasks.AbstractProguardTask
23
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
34

45
plugins {
@@ -10,6 +11,27 @@ plugins {
1011
group = "com.linuxcommandlibrary"
1112
version = libs.versions.appVersion.get()
1213

14+
// Replace the ProGuard tool classpath with one that resolves kotlin-metadata-jvm
15+
// at the Kotlin version we're building against. Compose Multiplatform 1.10.3 ships
16+
// ProGuard 7.7.0 with kotlin-metadata-jvm 2.1.0 (caps at metadata format 2.2) which
17+
// can't read `.kotlin_module` files from Kotlin 2.3.x builds, both ours and third
18+
// party deps like koin-compose 4.2.0. Letting Gradle resolve both deps together
19+
// avoids the split classpath we'd get from just prepending.
20+
val proguardClasspath =
21+
configurations.detachedConfiguration(
22+
dependencies.create("com.guardsquare:proguard-gradle:7.7.0"),
23+
dependencies.create("org.jetbrains.kotlin:kotlin-metadata-jvm:${libs.versions.kotlin.get()}"),
24+
).apply {
25+
resolutionStrategy.force("org.jetbrains.kotlin:kotlin-metadata-jvm:${libs.versions.kotlin.get()}")
26+
resolutionStrategy.force("org.jetbrains.kotlin:kotlin-stdlib:${libs.versions.kotlin.get()}")
27+
}
28+
29+
afterEvaluate {
30+
tasks.withType<AbstractProguardTask>().configureEach {
31+
proguardFiles.setFrom(proguardClasspath)
32+
}
33+
}
34+
1335
kotlin {
1436
jvm("desktop") {
1537
compilerOptions {
@@ -36,6 +58,12 @@ compose.desktop {
3658
application {
3759
mainClass = "com.linuxcommandlibrary.MainKt"
3860

61+
buildTypes.release.proguard {
62+
configurationFiles.from(project.file("desktop-rules.pro"))
63+
obfuscate.set(false)
64+
optimize.set(true)
65+
}
66+
3967
nativeDistributions {
4068
targetFormats(TargetFormat.Dmg, TargetFormat.Msi, TargetFormat.Deb, TargetFormat.Rpm, TargetFormat.AppImage)
4169
packageName = "LinuxCommandLibrary"

desktopApp/desktop-rules.pro

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
# =========================================================================
2+
# Linux Command Library - Compose Desktop ProGuard rules
3+
# Applied only to release builds via
4+
# compose.desktop.application.buildTypes.release.proguard
5+
# =========================================================================
6+
7+
# -------- Kotlin metadata / reflection hygiene --------
8+
-keep class kotlin.Metadata { *; }
9+
-keepattributes *Annotation*, Signature, InnerClasses, EnclosingMethod, RuntimeVisibleAnnotations, AnnotationDefault
10+
-dontwarn kotlin.**
11+
-dontwarn kotlinx.**
12+
13+
# -------- Kotlin Coroutines (upstream coroutines.pro) --------
14+
-keepnames class kotlinx.coroutines.internal.MainDispatcherFactory {}
15+
-keepnames class kotlinx.coroutines.CoroutineExceptionHandler {}
16+
-keepclassmembers class kotlinx.coroutines.** {
17+
volatile <fields>;
18+
}
19+
-keepclassmembers class kotlin.coroutines.SafeContinuation {
20+
volatile <fields>;
21+
}
22+
-dontwarn java.lang.instrument.ClassFileTransformer
23+
-dontwarn sun.misc.SignalHandler
24+
-dontwarn java.lang.instrument.Instrumentation
25+
-dontwarn sun.misc.Signal
26+
-dontwarn java.lang.ClassValue
27+
-dontwarn org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement
28+
29+
# -------- kotlinx.serialization (upstream rules/common.pro) --------
30+
-keepclassmembers @kotlinx.serialization.Serializable class ** {
31+
static ** Companion;
32+
}
33+
-if @kotlinx.serialization.internal.NamedCompanion class *
34+
-keepclassmembers class * {
35+
static <1> *;
36+
}
37+
-if @kotlinx.serialization.Serializable class ** {
38+
static **$* *;
39+
}
40+
-keepclassmembers class <2>$<3> {
41+
kotlinx.serialization.KSerializer serializer(...);
42+
}
43+
-if @kotlinx.serialization.Serializable class ** {
44+
public static ** INSTANCE;
45+
}
46+
-keepclassmembers class <1> {
47+
public static <1> INSTANCE;
48+
kotlinx.serialization.KSerializer serializer(...);
49+
}
50+
-keepclassmembers public class **$$serializer {
51+
private ** descriptor;
52+
}
53+
-dontnote kotlinx.serialization.**
54+
-dontwarn kotlinx.serialization.internal.ClassValueReferences
55+
56+
# -------- Type-safe navigation routes --------
57+
# Route.kt declares a @Serializable sealed class Route with data object/class
58+
# subtypes used as NavHost type-safe destinations. Navigation Compose looks up
59+
# the generated $serializer via reflection from the KClass, so the route types
60+
# and their generated serializers must survive shrinking.
61+
-keep @kotlinx.serialization.Serializable class com.linuxcommandlibrary.app.Route
62+
-keep @kotlinx.serialization.Serializable class com.linuxcommandlibrary.app.Route$* { *; }
63+
-keepclassmembers class com.linuxcommandlibrary.app.Route$* {
64+
*** Companion;
65+
kotlinx.serialization.KSerializer serializer(...);
66+
}
67+
68+
# -------- AndroidX Navigation (upstream navigation-common rules) --------
69+
-keepclassmembers class ** implements androidx.navigation.NavArgs {
70+
public static *** fromBundle(android.os.Bundle);
71+
}
72+
-keep class * extends androidx.navigation.Navigator
73+
-keep class androidx.navigation.NavType { *; }
74+
-keep class androidx.navigation.CollectionNavType { *; }
75+
-keep class androidx.navigation.serialization.** { *; }
76+
-keepclassmembers class androidx.navigation.serialization.** { *; }
77+
78+
# -------- Koin 4.x (no upstream rules file) --------
79+
-keep class org.koin.** { *; }
80+
-keepclassmembers class org.koin.** { *; }
81+
-dontwarn org.koin.**
82+
83+
# Keep our DI module declarations so Koin's factory lookups by KClass still work.
84+
-keep class com.linuxcommandlibrary.app.di.** { *; }
85+
-keep class com.linuxcommandlibrary.shared.platform.** { *; }
86+
-keep class com.linuxcommandlibrary.app.platform.** { *; }
87+
88+
# Keep ViewModels (Koin resolves by KClass; lifecycle ViewModel requires default ctor access).
89+
-keep class * extends androidx.lifecycle.ViewModel { <init>(...); }
90+
-keepnames class * extends androidx.lifecycle.ViewModel
91+
92+
# -------- Compose Material 3 / ProGuard Kotlin-2 metadata workaround --------
93+
# Harmless once version.set("7.5.0") is in place; kept as defence-in-depth.
94+
-dontwarn androidx.compose.material.**
95+
-keep class androidx.compose.material3.** { *; }

0 commit comments

Comments
 (0)