From 2af56d8cbf85d0530b2849545aba65b8668f0f3c Mon Sep 17 00:00:00 2001 From: Alexey Tsvetkov <654232+AlexeyTsvetkov@users.noreply.github.com> Date: Wed, 12 Oct 2022 17:22:49 +0200 Subject: [PATCH] Add tutorial on using ProGuard (#2392) * Add tutorial on using ProGuard Resolves #1174 --- .../README.md | 91 +++++++++---------- 1 file changed, 45 insertions(+), 46 deletions(-) diff --git a/tutorials/Native_distributions_and_local_execution/README.md b/tutorials/Native_distributions_and_local_execution/README.md index fd23282714..59509ba7dd 100755 --- a/tutorials/Native_distributions_and_local_execution/README.md +++ b/tutorials/Native_distributions_and_local_execution/README.md @@ -586,55 +586,54 @@ fun main() { 3. Run `./gradlew runDistributable`. 4. Links like `compose://foo/bar` are now redirected from a browser to your application. -## Obfuscation - -To obfuscate Compose Multiplatform JVM applications the standard approach for JVM applications works. -With the task `packageUberJarForCurrentOS` one could generate a JAR file which could be later obfuscated using ProGuard or R8. - -### ProGuard example - -``` kotlin -// build.gradle.kts - -// Add ProGuard to buildscript classpath -buildscript { - repositories { - mavenCentral() - } - dependencies { - classpath("com.guardsquare:proguard-gradle:7.2.0") +## Minification & obfuscation + +Starting from 1.2 the Compose Gradle plugin supports [ProGuard](https://www.guardsquare.com/proguard) out-of-the-box. +ProGuard is a well known [open source](https://github.com/Guardsquare/proguard) tool for minification and obfuscation, +that is developed by [Guardsquare](https://www.guardsquare.com/). + +The Gradle plugin provides a *release* task for each corresponding *default* packaging task: + +Default task (w/o ProGuard)| Release task (w. ProGuard) |Description +---------------------------|----------------------------------|----------- +`createDistributable` | `createReleaseDistributable` |Creates an application image with bundled JDK & resources +`runDistributable` | `runReleaseDistributable` |Runs an application image with bundled JDK & resources +`run` | `runRelease` |Runs a non-packaged application `jar` using Gradle JDK +`package` | `packageRelease` |Packages an application image into a `` file +`packageForCurrentOS` | `packageReleaseForCurrentOS` |Packages an application image into a format compatible with current OS +`notarize` | `notarizeRelease` |Uploads a `` application image for notarization (macOS only) +`checkNotarizationStatus` | `checkReleaseNotarizationStatus` |Checks if notarization succeeded (macOS only) + +The default configuration adds a few ProGuard rules: +* an application image is minified, i.e. non-used classes are removed; +* `compose.desktop.application.mainClass` is used as an entry point; +* a few `keep` rules to avoid breaking Compose runtime. + +In many cases getting a minified Compose application will not require any additional configuration. +However, sometimes ProGuard might be unable to track certain usages in bytecode +(for example, this might happen if a class is used via reflection). +If you encounter an issue, which happens only after ProGuard processing, +you might want to add custom rules. +To do so, specify a configuration file via DSL: +``` +compose.desktop { + application { + buildTypes.release.proguard { + configurationFiles.from(project.file("compose-desktop.pro")) + } } } - -// ... - -// Define task to obfuscate the JAR and output to .min.jar -tasks.register("obfuscate") { - val packageUberJarForCurrentOS by tasks.getting - dependsOn(packageUberJarForCurrentOS) - val files = packageUberJarForCurrentOS.outputs.files - injars(files) - outjars(files.map { file -> File(file.parentFile, "${file.nameWithoutExtension}.min.jar") }) - - val library = if (System.getProperty("java.version").startsWith("1.")) "lib/rt.jar" else "jmods" - libraryjars("${System.getProperty("java.home")}/$library") - - configuration("proguard-rules.pro") -} ``` +See the Guardsquare's [comprehensive manual](https://www.guardsquare.com/manual/configuration/usage) +on ProGuard's rules & configuration options. -This ProGuard configuration should get you started: - +Obfuscation is disabled by default. To enable it, set the following property via Gradle DSL: ``` -# proguard-rules.pro --dontoptimize --dontobfuscate - --dontwarn kotlinx.** - --keepclasseswithmembers public class com.example.MainKt { - public static void main(java.lang.String[]); +compose.desktop { + application { + buildTypes.release.proguard { + obfuscate.set(true) + } + } } --keep class org.jetbrains.skia.** { *; } --keep class org.jetbrains.skiko.** { *; } -``` +``` \ No newline at end of file