mirror of
https://github.com/meshtastic/Meshtastic-Android.git
synced 2026-05-11 16:15:24 -04:00
fix(desktop): unbreak release crash via correct ProGuard rules (#5236)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -44,17 +44,16 @@ internal fun Project.configureAndroidCompose(commonExtension: CommonExtension) {
|
||||
"androidx.compose.runtime",
|
||||
"androidx.compose.ui",
|
||||
)
|
||||
|
||||
// The BOM exclusion above strips versions from transitive material deps
|
||||
// (e.g. maps-compose-widgets, datadog). Pin the material group to the
|
||||
// AndroidX version that matches this CMP release.
|
||||
// The BOM exclusion above strips the version from `androidx.compose.material:material`
|
||||
// requested by maps-compose-widgets (google flavor). Pin only that artifact — the
|
||||
// group also contains `material-ripple`, which CMP publishes at the bom-aligned
|
||||
// version and must not be force-downgraded.
|
||||
val materialVersion = libs.version("androidx-compose-material")
|
||||
|
||||
configurations.configureEach {
|
||||
resolutionStrategy.eachDependency {
|
||||
if (requested.group in cmpAlignedGroups) {
|
||||
useVersion(androidxComposeVersion)
|
||||
} else if (requested.group == "androidx.compose.material") {
|
||||
} else if (requested.group == "androidx.compose.material" && requested.name == "material") {
|
||||
useVersion(materialVersion)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,166 +1,135 @@
|
||||
# ============================================================================
|
||||
# Meshtastic — Shared ProGuard / R8 rules
|
||||
# ============================================================================
|
||||
# Cross-platform keep and dontwarn rules applied to BOTH the Android app
|
||||
# release build (R8) and the Desktop distribution (ProGuard). Host-specific
|
||||
# rules live in the per-module proguard-rules.pro file.
|
||||
# Cross-platform keep rules applied to BOTH the Android app release (R8) and
|
||||
# the Desktop distribution (ProGuard 7.7 invoked by compose-jb).
|
||||
#
|
||||
# Rule of thumb: anything describing a library shared between Android and
|
||||
# Desktop (Koin, kotlinx-serialization, Wire, Room KMP, Ktor, Coil 3, Kable,
|
||||
# Kermit, Okio, DataStore, Paging, Lifecycle / Navigation 3, AboutLibraries,
|
||||
# Markdown renderer, QRCode, Compose Multiplatform resources, core modules)
|
||||
# belongs here. Anything platform-specific (AWT/Skiko/JNA, AIDL, Android
|
||||
# framework, JDK-version quirks, flavor specifics) stays in the host file.
|
||||
# IMPORTANT: compose-jb's standalone ProGuard task does NOT auto-include
|
||||
# `META-INF/proguard/*.pro` consumer rules from dependency jars (only R8 on
|
||||
# Android does — https://github.com/Guardsquare/proguard/issues/423).
|
||||
# So this file inlines all the consumer rules we depend on for desktop. On
|
||||
# Android these are duplicates of what R8 already auto-discovers, which is
|
||||
# harmless. Per JetBrains compose-multiplatform docs: keep it as a single
|
||||
# static .pro file and add rules as shrinking surfaces problems.
|
||||
# ============================================================================
|
||||
|
||||
# ---- Attributes -------------------------------------------------------------
|
||||
-keepattributes SourceFile,LineNumberTable,*Annotation*,Signature,InnerClasses,EnclosingMethod,Exceptions,RuntimeVisibleAnnotations,AnnotationDefault
|
||||
|
||||
# Preserve line numbers for meaningful stack traces, plus metadata needed for
|
||||
# reflective serializer/DI/Room lookups.
|
||||
-keepattributes SourceFile,LineNumberTable,*Annotation*,Signature,InnerClasses,EnclosingMethod,Exceptions,RuntimeVisibleAnnotations
|
||||
# ---- Compose Multiplatform 1.11 optimizer defense (#5146) -------------------
|
||||
# CMP 1.11 ships consumer rules with `-assumenosideeffects` on
|
||||
# Composer.<clinit>() / ComposerImpl.<clinit>() and `-assumevalues` on
|
||||
# ComposeRuntimeFlags / ComposeStackTraceMode. The primary defence is
|
||||
# `-dontoptimize` (set per-host in app/desktop proguard-rules.pro), which
|
||||
# disables rewriting of these directives. Broad package-wide keeps below have
|
||||
# been removed per R8_Configuration_Analysis.md as they are redundant — rely
|
||||
# instead on CMP's own consumer rules + @DoNotInline annotations. If animations
|
||||
# freeze in a future CMP/KGP release, replace with class-level keeps on the
|
||||
# specific failure points (Composer, ComposerImpl, ComposeRuntimeFlags,
|
||||
# ComposeStackTraceMode) rather than package-wide wildcards.
|
||||
|
||||
# ---- Kotlin / Coroutines ----------------------------------------------------
|
||||
# Kotlin stdlib and kotlinx-coroutines ship their own consumer ProGuard rules
|
||||
# (kotlin-stdlib and kotlinx-coroutines-core consumer-rules.pro) which keep
|
||||
# Metadata, Continuation, kotlin.reflect internals, and debug metadata. No
|
||||
# explicit wildcards needed here.
|
||||
# ---- Compose Multiplatform resources ----------------------------------------
|
||||
-keep class org.meshtastic.core.resources.Res { *; }
|
||||
-keepclassmembers class org.meshtastic.core.resources.Res$* { *; }
|
||||
|
||||
# ---- Koin DI (reflection-based injection) -----------------------------------
|
||||
|
||||
# Prevent R8 from merging exception classes (observed as io.ktor.http.URLDecodeException
|
||||
# replacing Koin's InstanceCreationException in stack traces, making crashes
|
||||
# undiagnosable). Broadened to all of koin core to cover the KSP-generated graph.
|
||||
-keep class org.koin.** { *; }
|
||||
-dontwarn org.koin.**
|
||||
|
||||
# Keep Koin-annotated modules/components so Koin Annotations (KSP) output
|
||||
# survives tree-shaking.
|
||||
# ---- Koin Annotations (KSP-generated DI graph) ------------------------------
|
||||
-keep @org.koin.core.annotation.Module class * { *; }
|
||||
-keep @org.koin.core.annotation.ComponentScan class * { *; }
|
||||
-keep @org.koin.core.annotation.Single class * { *; }
|
||||
-keep @org.koin.core.annotation.Factory class * { *; }
|
||||
-keep @org.koin.core.annotation.KoinViewModel class * { *; }
|
||||
|
||||
# ---- kotlinx-serialization --------------------------------------------------
|
||||
# ---- kotlinx.coroutines (inlined from coroutines.pro consumer rules) --------
|
||||
-keepnames class kotlinx.coroutines.internal.MainDispatcherFactory {}
|
||||
-keepnames class kotlinx.coroutines.CoroutineExceptionHandler {}
|
||||
-keepclassmembers class kotlinx.coroutines.** {
|
||||
volatile <fields>;
|
||||
}
|
||||
-keepclassmembers class kotlin.coroutines.SafeContinuation {
|
||||
volatile <fields>;
|
||||
}
|
||||
-dontwarn java.lang.instrument.ClassFileTransformer
|
||||
-dontwarn sun.misc.SignalHandler
|
||||
-dontwarn java.lang.instrument.Instrumentation
|
||||
-dontwarn sun.misc.Signal
|
||||
-dontwarn java.lang.ClassValue
|
||||
-dontwarn org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement
|
||||
|
||||
-keep class kotlinx.serialization.** { *; }
|
||||
-dontwarn kotlinx.serialization.**
|
||||
|
||||
# Keep @Serializable classes and their generated $serializer companions
|
||||
# ---- kotlinx.serialization (inlined from kotlinx-serialization-common.pro) --
|
||||
-keepclassmembers @kotlinx.serialization.Serializable class ** {
|
||||
static ** Companion;
|
||||
}
|
||||
-if @kotlinx.serialization.internal.NamedCompanion class *
|
||||
-keepclassmembers class * {
|
||||
static <1> *;
|
||||
}
|
||||
-if @kotlinx.serialization.Serializable class ** {
|
||||
static **$* *;
|
||||
}
|
||||
-keepclassmembers class <2>$<3> {
|
||||
kotlinx.serialization.KSerializer serializer(...);
|
||||
}
|
||||
-keep class **.$serializer { *; }
|
||||
-keepclassmembers class **.$serializer { *; }
|
||||
-keepclasseswithmembers class ** {
|
||||
-if @kotlinx.serialization.Serializable class ** {
|
||||
public static ** INSTANCE;
|
||||
}
|
||||
-keepclassmembers class <1> {
|
||||
public static <1> INSTANCE;
|
||||
kotlinx.serialization.KSerializer serializer(...);
|
||||
}
|
||||
-dontnote kotlinx.serialization.**
|
||||
-dontwarn kotlinx.serialization.internal.ClassValueReferences
|
||||
-keepclassmembers public class **$$serializer {
|
||||
private ** descriptor;
|
||||
}
|
||||
|
||||
# ---- Wire Protobuf ----------------------------------------------------------
|
||||
# ---- kotlinx.datetime (inlined from datetime.pro consumer rules) ------------
|
||||
-dontwarn kotlinx.serialization.KSerializer
|
||||
-dontwarn kotlinx.serialization.Serializable
|
||||
|
||||
# Wire generates an ADAPTER static field on every Message subclass accessed
|
||||
# reflectively during encoding/decoding. Keep those fields and the
|
||||
# ProtoAdapter subclasses themselves; Wire's bundled consumer rules preserve
|
||||
# the runtime itself.
|
||||
# ---- Ktor (inlined from ktor.pro + ServiceLoader gap) -----------------------
|
||||
-keepclassmembers class io.ktor.** {
|
||||
volatile <fields>;
|
||||
}
|
||||
-keepclassmembernames class io.ktor.** {
|
||||
volatile <fields>;
|
||||
}
|
||||
-keep class io.ktor.client.engine.** implements io.ktor.client.HttpClientEngineContainer
|
||||
# ktor consumer rules preserve the ServiceLoader META-INF/services file but not
|
||||
# the impl classes; ContentNegotiation discovers KotlinxSerializationJsonExtensionProvider
|
||||
# reflectively and crashes with ServiceConfigurationError without these.
|
||||
-keep class * implements io.ktor.serialization.kotlinx.KotlinxSerializationExtensionProvider { *; }
|
||||
-keep class io.ktor.serialization.kotlinx.json.** { *; }
|
||||
|
||||
# ---- androidx.annotation.Keep (inlined from androidx-annotations.pro) -------
|
||||
-keep,allowobfuscation @interface androidx.annotation.Keep
|
||||
-keep @androidx.annotation.Keep class * {*;}
|
||||
-keepclasseswithmembers class * { @androidx.annotation.Keep <methods>; }
|
||||
-keepclasseswithmembers class * { @androidx.annotation.Keep <fields>; }
|
||||
-keepclasseswithmembers class * { @androidx.annotation.Keep <init>(...); }
|
||||
-keepclassmembers,allowobfuscation class * {
|
||||
@androidx.annotation.DoNotInline <methods>;
|
||||
}
|
||||
|
||||
# ---- androidx.datastore (inlined from datastore-preferences-core.pro) -------
|
||||
-keepclassmembers class * extends androidx.datastore.preferences.protobuf.GeneratedMessageLite {
|
||||
<fields>;
|
||||
}
|
||||
|
||||
# ---- Wire Protobuf (no consumer rules shipped) ------------------------------
|
||||
-keepclassmembers class * extends com.squareup.wire.Message {
|
||||
public static *** ADAPTER;
|
||||
}
|
||||
-keepclassmembers class * extends com.squareup.wire.ProtoAdapter { *; }
|
||||
|
||||
# Suppress warnings about missing Android Parcelable (Wire cross-platform stubs
|
||||
# when compiling for non-Android JVM targets; harmless on Android).
|
||||
-dontwarn android.os.Parcel**
|
||||
-dontwarn android.os.Parcelable**
|
||||
# ---- androidx.sqlite bundled driver (JNI native bridge) ---------------------
|
||||
# androidx.sqlite-bundled's consumer rule keeps native methods only — but the
|
||||
# bundled JNI library calls back into JVM methods on the driver class
|
||||
# (e.g. `nativeThreadSafeMode`). Keep the whole driver package.
|
||||
-keep class androidx.sqlite.driver.bundled.** { *; }
|
||||
-keepclassmembers class androidx.sqlite.driver.bundled.** { native <methods>; *; }
|
||||
|
||||
# ---- Room KMP (room3) -------------------------------------------------------
|
||||
|
||||
# Preserve generated database constructors (Room uses reflection to instantiate)
|
||||
-keep class * extends androidx.room3.RoomDatabase { <init>(); }
|
||||
-keep class * implements androidx.room3.RoomDatabaseConstructor { *; }
|
||||
|
||||
# Keep the expect/actual MeshtasticDatabaseConstructor + database surface
|
||||
-keep class org.meshtastic.core.database.MeshtasticDatabaseConstructor { *; }
|
||||
-keep class org.meshtastic.core.database.MeshtasticDatabase { *; }
|
||||
|
||||
# Room's own consumer rules (from androidx.room3) keep DAOs, entities,
|
||||
# generated _Impl classes, and TypeConverters referenced from the database.
|
||||
|
||||
# ---- SQLite bundled --------------------------------------------------------
|
||||
# androidx.sqlite ships consumer rules.
|
||||
|
||||
# ---- Ktor (ServiceLoader + plugin discovery) --------------------------------
|
||||
|
||||
# Keep ServiceLoader metadata files (ktor discovers HttpClientEngineFactory
|
||||
# implementations reflectively via ServiceLoader).
|
||||
-keepclassmembers class * implements io.ktor.client.HttpClientEngineFactory { *; }
|
||||
|
||||
# ---- Coil 3 (image loading) -------------------------------------------------
|
||||
# coil3 ships consumer rules.
|
||||
|
||||
# ---- Kable BLE --------------------------------------------------------------
|
||||
# com.juul.kable ships consumer rules; if release builds fail with missing
|
||||
# Kable classes, restore a narrow keep for the specific reflection-loaded type.
|
||||
|
||||
# ---- Compose Multiplatform resources ----------------------------------------
|
||||
|
||||
# Generated resource accessor classes (Res.string.*, Res.drawable.*, etc.).
|
||||
# Without these the fdroid flavor has crashed at startup with a misleading
|
||||
# URLDecodeException due to R8 exception-class merging.
|
||||
-keep class org.jetbrains.compose.resources.** { *; }
|
||||
-keep class org.meshtastic.core.resources.Res { *; }
|
||||
-keepclassmembers class org.meshtastic.core.resources.Res$* { *; }
|
||||
|
||||
# ---- AboutLibraries ---------------------------------------------------------
|
||||
# com.mikepenz.aboutlibraries ships consumer rules.
|
||||
|
||||
# ---- Multiplatform Markdown Renderer ----------------------------------------
|
||||
# com.mikepenz.markdown ships consumer rules.
|
||||
|
||||
# ---- QR Code Kotlin ---------------------------------------------------------
|
||||
|
||||
-keep class io.github.g0dkar.qrcode.** { *; }
|
||||
-dontwarn io.github.g0dkar.qrcode.**
|
||||
-keep class qrcode.** { *; }
|
||||
-dontwarn qrcode.**
|
||||
|
||||
# ---- Kermit logging ---------------------------------------------------------
|
||||
# co.touchlab.kermit ships consumer rules.
|
||||
|
||||
# ---- Okio -------------------------------------------------------------------
|
||||
# okio ships consumer rules.
|
||||
|
||||
# ---- DataStore --------------------------------------------------------------
|
||||
# androidx.datastore ships consumer rules.
|
||||
|
||||
# ---- Paging -----------------------------------------------------------------
|
||||
# androidx.paging ships consumer rules.
|
||||
|
||||
# ---- Lifecycle / Navigation 3 / ViewModel (JetBrains forks) -----------------
|
||||
# androidx.lifecycle and androidx.navigation3 ship consumer rules.
|
||||
|
||||
# ---- Meshtastic shared model ------------------------------------------------
|
||||
# core.model types are reached via static references from Koin-wired graphs,
|
||||
# Room entities, and kotlinx-serialization @Serializable companions — all of
|
||||
# which have their own keep rules above.
|
||||
|
||||
# ---- Compose Runtime & Animation --------------------------------------------
|
||||
|
||||
# Defence-in-depth: prevent tree-shaking of Compose infrastructure classes that
|
||||
# are referenced indirectly through compiler-generated state machines. Applies
|
||||
# to BOTH R8 (Android app) and ProGuard (desktop distribution).
|
||||
#
|
||||
# Why shared: CMP 1.11 ships consumer rules with -assumenosideeffects on
|
||||
# Composer.<clinit>() / ComposerImpl.<clinit>() and -assumevalues on
|
||||
# ComposeRuntimeFlags / ComposeStackTraceMode. If the optimizer runs (R8 full
|
||||
# mode on Android, ProGuard with optimize.set(true) on desktop) these call
|
||||
# sites can be rewritten even when the target classes are kept, causing the
|
||||
# recomposer / frame-clock / animation state machines to silently freeze on
|
||||
# the first frame. -dontoptimize (set per-host) is the primary defence; these
|
||||
# keep rules are a safety net against future toolchain changes. See #5146.
|
||||
-keep class androidx.compose.runtime.** { *; }
|
||||
-keep class androidx.compose.ui.** { *; }
|
||||
-keep class androidx.compose.animation.core.** { *; }
|
||||
-keep class androidx.compose.animation.** { *; }
|
||||
-keep class androidx.compose.foundation.** { *; }
|
||||
-keep class androidx.compose.material3.** { *; }
|
||||
|
||||
@@ -99,6 +99,12 @@ val generateBuildConfig =
|
||||
|
||||
sourceSets.main { kotlin.srcDir(generateBuildConfig.map { buildConfigOutputDir }) }
|
||||
|
||||
// ── ProGuard configuration ───────────────────────────────────────────────────
|
||||
// compose-jb's standalone ProGuard 7.7 task does NOT auto-include
|
||||
// `META-INF/proguard/*.pro` consumer rules from dependency jars (only R8 on
|
||||
// Android does). We therefore inline every keep rule we need into the two
|
||||
// static .pro files referenced below.
|
||||
|
||||
kotlin {
|
||||
jvmToolchain {
|
||||
languageVersion.set(JavaLanguageVersion.of(21))
|
||||
|
||||
133
desktop/proguard-rules.pro
vendored
133
desktop/proguard-rules.pro
vendored
@@ -1,113 +1,64 @@
|
||||
# ============================================================================
|
||||
# Meshtastic Desktop — ProGuard rules for release minification
|
||||
# ============================================================================
|
||||
# Open-source project: we rely on tree-shaking (unused code removal) for size
|
||||
# reduction. Obfuscation is disabled in build.gradle.kts (obfuscate.set(false)).
|
||||
# Open-source: obfuscation is OFF (build.gradle.kts: obfuscate.set(false)).
|
||||
# Tree-shaking still runs.
|
||||
#
|
||||
# Cross-platform library rules (Koin, kotlinx-serialization, Wire, Room,
|
||||
# Ktor, Coil, Kable, Kermit, Okio, DataStore, Paging, Lifecycle, Navigation 3,
|
||||
# AboutLibraries, Markdown, QRCode, CMP resources, core model) live in
|
||||
# config/proguard/shared-rules.pro and are wired in by this module's
|
||||
# build.gradle.kts. This file holds only desktop/JVM-specific rules.
|
||||
# Two rule sources are merged into the ProGuard run:
|
||||
# 1. JetBrains' bundled `default-compose-desktop-rules.pro` (auto-injected
|
||||
# by the compose.desktop Gradle plugin).
|
||||
# 2. Cross-platform project keeps in config/proguard/shared-rules.pro,
|
||||
# which inlines every dependency consumer rule we need on desktop —
|
||||
# compose-jb's standalone ProGuard task does NOT auto-discover
|
||||
# `META-INF/proguard/*.pro` consumer rules from dependency jars (only
|
||||
# R8 on Android does — https://github.com/Guardsquare/proguard/issues/423).
|
||||
#
|
||||
# This file only holds desktop/JVM-specific rules that aren't covered above.
|
||||
# ============================================================================
|
||||
|
||||
# ---- General ----------------------------------------------------------------
|
||||
|
||||
# Suppress notes about duplicate resource files (common in fat JARs)
|
||||
-dontnote **
|
||||
|
||||
# Disable ProGuard optimization passes. Tree-shaking (unused code removal) still
|
||||
# runs — only method-body rewrites and call-site transformations are suppressed.
|
||||
#
|
||||
# Why: CMP 1.11 ships consumer rules with -assumenosideeffects on
|
||||
# Composer.<clinit>() and ComposerImpl.<clinit>(), plus -assumevalues on
|
||||
# ComposeRuntimeFlags and ComposeStackTraceMode. These optimization directives
|
||||
# let the optimizer rewrite *call sites* (class-init triggers, flag reads) even
|
||||
# when the target classes are preserved by -keep rules. The result is that the
|
||||
# Compose recomposer/frame-clock/animation state machines silently freeze on
|
||||
# their first frame in release builds. -dontoptimize is the only directive that
|
||||
# disables processing of -assumenosideeffects/-assumevalues. The desktop compose
|
||||
# build sets optimize.set(true), so this applies here as well as to R8. See #5146.
|
||||
-dontoptimize
|
||||
|
||||
# Do not parse/rewrite Kotlin metadata during shrinking/optimization.
|
||||
# ProGuard's KotlinShrinker cannot handle the metadata produced by Compose
|
||||
# Multiplatform 1.11.x + Kotlin 2.3.x, causing a NullPointerException.
|
||||
# Since we disable obfuscation (class names remain stable), metadata references
|
||||
# stay valid and do not need rewriting. The annotations themselves are preserved
|
||||
# by -keepattributes *Annotation*.
|
||||
#
|
||||
# NOTE: -dontprocesskotlinmetadata is a ProGuard-only directive; R8 does not
|
||||
# recognize it, which is why it lives in the desktop-only file.
|
||||
# ---- ProGuard 7.7 + Kotlin 2.3 metadata workaround --------------------------
|
||||
# ProGuard 7.7's KotlinShrinker NPEs on metadata produced by CMP 1.11 +
|
||||
# Kotlin 2.3.x. Because we don't obfuscate, class names stay stable and
|
||||
# metadata references remain valid without rewriting. Annotations themselves
|
||||
# are preserved by `-keepattributes *Annotation*` in shared-rules.pro.
|
||||
# (R8-only directive equivalent does not exist; this is ProGuard-only.)
|
||||
-dontprocesskotlinmetadata
|
||||
|
||||
# ---- Disable optimizer (CMP 1.11 -assumenosideeffects defense) --------------
|
||||
# See shared-rules.pro for full rationale. Even though build.gradle.kts sets
|
||||
# `optimize.set(true)` so compose-jb wires the optimization step, this rule
|
||||
# turns it into a no-op — keeping CMP's `-assumenosideeffects` directives from
|
||||
# rewriting Composer call sites and freezing the runtime. See #5146.
|
||||
-dontoptimize
|
||||
|
||||
# ---- Entry point ------------------------------------------------------------
|
||||
# (org.meshtastic.desktop.MainKt is covered by the package-wide keep below.)
|
||||
|
||||
# ---- Meshtastic desktop host shell ------------------------------------------
|
||||
|
||||
# Keep all desktop module classes (thin host shell — not worth tree-shaking)
|
||||
# Keep the desktop host shell (thin module — not worth tree-shaking).
|
||||
-keep class org.meshtastic.desktop.** { *; }
|
||||
|
||||
# ---- JVM runtime suppression ------------------------------------------------
|
||||
|
||||
-dontwarn java.lang.reflect.**
|
||||
-dontwarn sun.misc.Unsafe
|
||||
-dontwarn java.lang.invoke.**
|
||||
|
||||
# ---- jSerialComm (cross-platform serial library with Android stubs) ---------
|
||||
|
||||
# ---- jSerialComm Android stubs (cross-platform serial library) --------------
|
||||
# jSerialComm bundles Android shims that reference android.* classes; harmless
|
||||
# on JVM/desktop but ProGuard fails the build on unresolved program classes
|
||||
# unless suppressed.
|
||||
-dontwarn com.fazecast.jSerialComm.android.**
|
||||
|
||||
# ---- Kotlin stdlib atomics (Kotlin 2.3+ intrinsics, not on JDK 17) ----------
|
||||
# Wire ships AndroidMessage in its common runtime; on desktop classpath there is
|
||||
# no android.os.Parcelable. We never use AndroidMessage on desktop.
|
||||
-dontwarn com.squareup.wire.AndroidMessage
|
||||
-dontwarn com.squareup.wire.AndroidMessage$*
|
||||
-dontwarn android.os.Parcelable
|
||||
-dontwarn android.os.Parcelable$*
|
||||
|
||||
-dontwarn kotlin.concurrent.atomics.**
|
||||
-dontwarn kotlin.uuid.UuidV7Generator
|
||||
|
||||
# ---- Library consumer rules ------------------------------------------------
|
||||
# The compose-jb gradle plugin auto-injects `default-compose-desktop-rules.pro`
|
||||
# (bundled inside org.jetbrains.compose:compose-gradle-plugin) into every
|
||||
# desktop ProGuard run. That file already covers:
|
||||
# - kotlin.**, kotlinx.coroutines.** (incl. SwingDispatcherFactory ServiceLoader)
|
||||
# - org.jetbrains.skiko.**, org.jetbrains.skia.**
|
||||
# - kotlinx.serialization.** (incl. @Serializable companion keeps)
|
||||
# - kotlinx.datetime.**
|
||||
# - androidx.compose.runtime SnapshotStateKt + Material3 SliderDefaults
|
||||
# So we DO NOT re-declare those here. Source of truth:
|
||||
# https://github.com/JetBrains/compose-multiplatform/blob/master/gradle-plugins/compose/src/main/resources/default-compose-desktop-rules.pro
|
||||
#
|
||||
# However, the standalone ProGuard 7.7.0 that compose-jb invokes does NOT
|
||||
# auto-import library `META-INF/proguard/*.pro` consumer rules from arbitrary
|
||||
# jars (only R8/Android does). So any consumer-rule pattern outside the bundled
|
||||
# defaults above must be copied here manually (see Ktor SL block below).
|
||||
|
||||
# ---- androidx.sqlite bundled driver (JNI native bridge) ---------------------
|
||||
# BundledSQLiteDriver loads `libsqliteJni` and the native code calls back into
|
||||
# JVM-land via methods on `BundledSQLiteDriverKt` (e.g. `nativeThreadSafeMode`)
|
||||
# and member methods on `BundledSQLiteDriver` itself. Because those JVM symbols
|
||||
# are referenced only from native code, ProGuard removes them as unused; the
|
||||
# native loader then crashes with `NoSuchMethodError: ... name or signature does
|
||||
# not match`. Keep the whole driver package — it's small and entirely needed at
|
||||
# runtime once the bundled SQLite driver is selected.
|
||||
-keep class androidx.sqlite.driver.bundled.** { *; }
|
||||
-keepclassmembers class androidx.sqlite.driver.bundled.** { native <methods>; *; }
|
||||
|
||||
# ---- Ktor serialization extension providers (ServiceLoader) -----------------
|
||||
# io.ktor.serialization.kotlinx-json discovers KotlinxSerializationJsonExtensionProvider
|
||||
# via META-INF/services/io.ktor.serialization.kotlinx.KotlinxSerializationExtensionProvider.
|
||||
# Without this keep the desktop HttpClient init throws ServiceConfigurationError
|
||||
# at first request; on Windows jpackage's launcher swallows the trace and
|
||||
# surfaces it as "Failed to launch JVM".
|
||||
-keep class * implements io.ktor.serialization.kotlinx.KotlinxSerializationExtensionProvider { *; }
|
||||
|
||||
# ---- Vico 3.2.0-next.1 ColorScale (CMP API drift) ---------------------------
|
||||
# Vico's new ColorScale* classes (ColorScaleShader, ColorScaleAreaFill,
|
||||
# ColorScaleLineFill) reference CMP UI graphics members that don't exist in
|
||||
# compose-multiplatform 1.11.0-beta03 (LinearGradientShader-VjE6UOU$default
|
||||
# on ShaderKt and Paint.setShader(org.jetbrains.skia.Shader)). We don't use
|
||||
# the ColorScale APIs in this app, so suppress these warnings to let ProGuard
|
||||
# proceed; otherwise it aborts with "unresolved program class members".
|
||||
# Remove once Vico ships a release built against CMP 1.11 stable.
|
||||
# Vico's ColorScale* classes call into skia-shader bridges that aren't on the
|
||||
# desktop ProGuard classpath. Vico ships no consumer rules.
|
||||
-dontwarn com.patrykandpatrick.vico.compose.cartesian.ColorScaleShader
|
||||
-dontwarn com.patrykandpatrick.vico.compose.cartesian.layer.ColorScaleAreaFill
|
||||
-dontwarn com.patrykandpatrick.vico.compose.cartesian.layer.ColorScaleLineFill
|
||||
|
||||
# ---- Kotlin 2.3+ stdlib intrinsics not present on JDK 17 --------------------
|
||||
-dontwarn kotlin.concurrent.atomics.**
|
||||
-dontwarn kotlin.uuid.UuidV7Generator
|
||||
|
||||
@@ -44,9 +44,9 @@ compose-multiplatform-material3 = "1.11.0-alpha07"
|
||||
# AndroidCompose.kt's resolutionStrategy force-aligns these groups to *this* version
|
||||
# at resolution time, so it is the source of truth for the Android target.
|
||||
androidx-compose-bom-aligned = "1.11.0"
|
||||
# `androidx-compose-material` (M2) is independent of CMP and pinned separately
|
||||
# because some third-party libs (maps-compose-widgets, datadog) drag in
|
||||
# unversioned material transitives.
|
||||
# `androidx-compose-material` (M2) is independent of CMP. Pinned because
|
||||
# maps-compose-widgets requests `androidx.compose.material:material` without
|
||||
# a version (relying on a BOM that we exclude). M2 is frozen at 1.7.8.
|
||||
androidx-compose-material = "1.7.8"
|
||||
jetbrains-adaptive = "1.3.0-alpha07"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user