JetBrains / compose-multiplatform

Compose Multiplatform, a modern UI framework for Kotlin that makes building performant and beautiful user interfaces easy and enjoyable.
https://jetbrains.com/lp/compose-multiplatform
Apache License 2.0
15.94k stars 1.16k forks source link

Pass certain library jars to proguard as -libraryjars instead of -injars #2769

Open mcpiroman opened 1 year ago

mcpiroman commented 1 year ago

Currently gradle plugin sends the whole application's classpath as -injars argument to proguard. But some, if not most dependencies are desirable to be put as -libraryjars instead, because of:

(In particular I cannot manage to process libraries such sa ojdbc11 library even with -keep class, -dontwarn and -dontnote rules.)

It could even be the default to pass all not-project and not-compose dependencies as -libraryjars with an option to specify which should actually be -injars.

AlexeyTsvetkov commented 1 year ago

Currently gradle plugin sends the whole application's classpath as -injars argument to proguard.

@mcpiroman that's not entirely accurate. Currently the plugin sends the whole runtime classpath as -injars. These libraries are potentially needed at runtime, so basically you want us to exclude some libraries from the minification, and simply pack them in full?

It could even be the default to pass all not-project and not-compose dependencies as -libraryjars with an option to specify which should actually be -injars.

I don't see a way to do this reliably in Compose Gradle Plugin. We get a reference to Kotlin runtime classpath as a FileCollection, which is just Iterable<File>. We could try to invent some heuristics, but, given Gradle's inherent customizability, all heuristics are going to fail.

I think adding a way to exclude some library from DSL is possible.
But it should also be possible with wildcard keep rules like:

-keep class oracle.** { *; }

Also, since you have an issue with a jdbc library, have you trried including java.sql JDK module (in addition to the wildcard rules above)?


// build.gradle.kts
compose.desktop {
    application {
        nativeDistributions {
            // ...
            modules("java.sql")
        }
        buildTypes.release {
            proguard {
                configurationFiles.from("compose-desktop.pro")
            }
        }
    }
}
// compose-desktop.pro
-keep class oracle.** { *; }
mcpiroman commented 1 year ago

you want us to exclude some libraries from the minification, and simply pack them in full?

Exactly

I don't see a way to do this reliably in Compose Gradle Plugin

How about collecting output jars of all projects, something like project.root.allProjects.flatMap { it.jar.outputFiles } (syntax made up).

Now to my case with ojdbc: Yes, I have tired all that you proposed. Currently I use my own gradle script run proguard and there I pass some libraries like ojdbc with -libraryjars and copy them as-is. So basically I would like to do the same but with the official proguard support.

AlexeyTsvetkov commented 1 year ago

How about collecting output jars of all projects, something like project.root.allProjects.flatMap { it.jar.outputFiles }

The proposed snippet won't work for all projects. It only looks at the Jar task, created by java plugin by default. Plugins or builds might define additional Jar tasks or produce jar files by other means.

Also allProjects most likely will be incompatible with Gradle's future project isolation.

okushnikov commented 3 weeks ago

Please check the following ticket on YouTrack for follow-ups to this issue. GitHub issues will be closed in the coming weeks.