Browse Source

Add tutorial on using ProGuard (#2392)

* Add tutorial on using ProGuard

Resolves #1174
pull/2396/head
Alexey Tsvetkov 2 years ago committed by GitHub
parent
commit
2af56d8cbf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 91
      tutorials/Native_distributions_and_local_execution/README.md

91
tutorials/Native_distributions_and_local_execution/README.md

@ -586,55 +586,54 @@ fun main() {
3. Run `./gradlew runDistributable`. 3. Run `./gradlew runDistributable`.
4. Links like `compose://foo/bar` are now redirected from a browser to your application. 4. Links like `compose://foo/bar` are now redirected from a browser to your application.
## Obfuscation ## Minification & obfuscation
To obfuscate Compose Multiplatform JVM applications the standard approach for JVM applications works. Starting from 1.2 the Compose Gradle plugin supports [ProGuard](https://www.guardsquare.com/proguard) out-of-the-box.
With the task `packageUberJarForCurrentOS` one could generate a JAR file which could be later obfuscated using ProGuard or R8. 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/).
### ProGuard example
The Gradle plugin provides a *release* task for each corresponding *default* packaging task:
``` kotlin
// build.gradle.kts Default task (w/o ProGuard)| Release task (w. ProGuard) |Description
---------------------------|----------------------------------|-----------
// Add ProGuard to buildscript classpath `createDistributable` | `createReleaseDistributable` |Creates an application image with bundled JDK & resources
buildscript { `runDistributable` | `runReleaseDistributable` |Runs an application image with bundled JDK & resources
repositories { `run` | `runRelease` |Runs a non-packaged application `jar` using Gradle JDK
mavenCentral() `package<FORMAT_NAME>` | `packageRelease<FORMAT_NAME>` |Packages an application image into a `<FORMAT_NAME>` file
} `packageForCurrentOS` | `packageReleaseForCurrentOS` |Packages an application image into a format compatible with current OS
dependencies { `notarize<FORMAT_NAME>` | `notarizeRelease<FORMAT_NAME>` |Uploads a `<FORMAT_NAME>` application image for notarization (macOS only)
classpath("com.guardsquare:proguard-gradle:7.2.0") `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 <name>.min.jar
tasks.register<ProGuardTask>("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 compose.desktop {
-dontoptimize application {
-dontobfuscate buildTypes.release.proguard {
obfuscate.set(true)
-dontwarn kotlinx.** }
}
-keepclasseswithmembers public class com.example.MainKt {
public static void main(java.lang.String[]);
} }
-keep class org.jetbrains.skia.** { *; } ```
-keep class org.jetbrains.skiko.** { *; }
```
Loading…
Cancel
Save