Unverified Commit f2266923 authored by Alexey Tsvetkov's avatar Alexey Tsvetkov Committed by GitHub

Exclude bytecode from skiko-awt-runtime-*.jar files (#608)

* Exclude bytecode from skiko-awt-runtime-*.jar files

Previously, `skiko-awt.jar` and all of `skiko-awt-runtime-*.jar` files
contained the same bytecode. However, this led to duplication
of bytecode in Compose projects:
* `skiko-awt.jar` is a necessary API dependency of Compose/Desktop, which means
it is a runtime dependency as well;
* `skiko-awt-runtime-*.jar` is a necessary RUNTIME dependency of any Compose/Desktop project.

Thus, both `skiko-awt.jar` and `skiko-awt-runtime-*.jar` ended up in a runtime classpath of
any Compose/Desktop project, so the same classes were present in the runtime classpath twice.
This increased a final application image by approximately 1.1 Mb. Also, it led to
excessive ProGuard warnings, e.g. https://github.com/JetBrains/compose-jb/issues/2393

This change excludes bytecode from `skiko-awt-runtime-*.jar` artifacts, and adds
Maven dependency `skiko-awt-runtime-*.jar` -> `skiko-awt.jar`, so
many existing Maven/Gradle usages of `skiko-awt-runtime-*.jar` will continue to work.
parent 673c85d1
...@@ -25,7 +25,7 @@ val skiko = SkikoProperties(rootProject) ...@@ -25,7 +25,7 @@ val skiko = SkikoProperties(rootProject)
val buildType = skiko.buildType val buildType = skiko.buildType
allprojects { allprojects {
group = "org.jetbrains.skiko" group = SkikoArtifacts.groupId
version = skiko.deployVersion version = skiko.deployVersion
} }
...@@ -621,7 +621,8 @@ val skikoAwtJar by project.tasks.registering(Jar::class) { ...@@ -621,7 +621,8 @@ val skikoAwtJar by project.tasks.registering(Jar::class) {
from(kotlin.jvm("awt").compilations["main"].output.allOutputs) from(kotlin.jvm("awt").compilations["main"].output.allOutputs)
} }
val skikoAwtRuntimeJar = createSkikoJvmJarTask(hostOs, hostArch, skikoAwtJar) val skikoAwtRuntimeJar = createSkikoJvmJarTask(hostOs, hostArch, skikoAwtJar)
val skikoRuntimeDirForTests = skikoRuntimeDirForTestsTask(hostOs, hostArch, skikoAwtRuntimeJar) val skikoRuntimeDirForTests = skikoRuntimeDirForTestsTask(hostOs, hostArch, skikoAwtJar, skikoAwtRuntimeJar)
val skikoJarForTests = skikoJarForTestsTask(skikoRuntimeDirForTests)
if (supportAndroid) { if (supportAndroid) {
val os = OS.Android val os = OS.Android
...@@ -1077,34 +1078,40 @@ fun skikoJvmRuntimeJarTask( ...@@ -1077,34 +1078,40 @@ fun skikoJvmRuntimeJarTask(
awtJar: TaskProvider<Jar>, awtJar: TaskProvider<Jar>,
nativeFiles: List<Provider<File>> nativeFiles: List<Provider<File>>
) = project.registerSkikoTask<Jar>("skikoJvmRuntimeJar", targetOs, targetArch) { ) = project.registerSkikoTask<Jar>("skikoJvmRuntimeJar", targetOs, targetArch) {
dependsOn(awtJar)
val target = targetId(targetOs, targetArch) val target = targetId(targetOs, targetArch)
archiveBaseName.set("skiko-$target") archiveBaseName.set("skiko-$target")
from(awtJar.map { zipTree(it.archiveFile) })
nativeFiles.forEach { provider -> from(provider) } nativeFiles.forEach { provider -> from(provider) }
} }
fun skikoRuntimeDirForTestsTask( fun skikoRuntimeDirForTestsTask(
targetOs: OS, targetOs: OS,
targetArch: Arch, targetArch: Arch,
skikoJvmJar: Provider<Jar>,
skikoJvmRuntimeJar: Provider<Jar> skikoJvmRuntimeJar: Provider<Jar>
) = project.registerSkikoTask<Copy>("skikoRuntimeDirForTests", targetOs, targetArch) { ) = project.registerSkikoTask<Copy>("skikoRuntimeDirForTests", targetOs, targetArch) {
dependsOn(skikoJvmRuntimeJar) dependsOn(skikoJvmJar, skikoJvmRuntimeJar)
from(zipTree(skikoJvmRuntimeJar.flatMap { it.archiveFile })) { from(zipTree(skikoJvmJar.flatMap { it.archiveFile }))
include("*.so") from(zipTree(skikoJvmRuntimeJar.flatMap { it.archiveFile }))
include("*.dylib") duplicatesStrategy = DuplicatesStrategy.WARN
include("*.dll")
include("icudtl.dat")
}
destinationDir = project.buildDir.resolve("skiko-runtime-for-tests") destinationDir = project.buildDir.resolve("skiko-runtime-for-tests")
} }
fun skikoJarForTestsTask(
runtimeDirForTestsTask: Provider<Copy>
) = project.registerSkikoTask<Jar>("skikoJvmJarForTests") {
dependsOn(runtimeDirForTestsTask)
from(runtimeDirForTestsTask.map { it.destinationDir })
archiveFileName.set("skiko-runtime-for-tests.jar")
}
tasks.withType<Test>().configureEach { tasks.withType<Test>().configureEach {
dependsOn(skikoRuntimeDirForTests) dependsOn(skikoRuntimeDirForTests)
dependsOn(skikoAwtRuntimeJar) dependsOn(skikoJarForTests)
options { options {
val dir = skikoRuntimeDirForTests.map { it.destinationDir }.get() val dir = skikoRuntimeDirForTests.map { it.destinationDir }.get()
systemProperty("skiko.library.path", dir) systemProperty("skiko.library.path", dir)
val jar = skikoAwtRuntimeJar.get().outputs.files.files.single { it.name.endsWith(".jar")} val jar = skikoJarForTests.get().outputs.files.files.single { it.name.endsWith(".jar")}
systemProperty("skiko.jar.path", jar.absolutePath) systemProperty("skiko.jar.path", jar.absolutePath)
systemProperty("skiko.test.screenshots.dir", File(project.projectDir, "src/jvmTest/screenshots").absolutePath) systemProperty("skiko.test.screenshots.dir", File(project.projectDir, "src/jvmTest/screenshots").absolutePath)
...@@ -1187,7 +1194,7 @@ publishing { ...@@ -1187,7 +1194,7 @@ publishing {
} }
configureEach { configureEach {
this as MavenPublication this as MavenPublication
groupId = "org.jetbrains.skiko" groupId = SkikoArtifacts.groupId
// Necessary for publishing to Maven Central // Necessary for publishing to Maven Central
artifact(emptyJavadocJar) artifact(emptyJavadocJar)
...@@ -1226,15 +1233,15 @@ publishing { ...@@ -1226,15 +1233,15 @@ publishing {
artifactId = SkikoArtifacts.jvmRuntimeArtifactIdFor(os, arch) artifactId = SkikoArtifacts.jvmRuntimeArtifactIdFor(os, arch)
afterEvaluate { afterEvaluate {
artifact(entry.value.map { it.archiveFile.get() }) artifact(entry.value.map { it.archiveFile.get() })
var jvmSourcesArtifact: Any? = null artifact(emptySourcesJar)
// todo: use correct sources jar for each jvm source set
kotlin.jvm(if (os == OS.Android) "android" else "awt").mavenPublication {
jvmSourcesArtifact = artifacts.find { it.classifier == "sources" }
} }
if (jvmSourcesArtifact == null) { pom.withXml {
error("Could not find sources jar artifact for JVM target") asNode().appendNode("dependencies")
} else { .appendNode("dependency").apply {
artifact(jvmSourcesArtifact) appendNode("groupId", SkikoArtifacts.groupId)
appendNode("artifactId", SkikoArtifacts.jvmArtifactId)
appendNode("version", skiko.deployVersion)
appendNode("scope", "compile")
} }
} }
} }
......
...@@ -177,6 +177,7 @@ class SkikoProperties(private val myProject: Project) { ...@@ -177,6 +177,7 @@ class SkikoProperties(private val myProject: Project) {
} }
object SkikoArtifacts { object SkikoArtifacts {
val groupId = "org.jetbrains.skiko"
// names are also used in samples, e.g. samples/SkijaInjectSample/build.gradle // names are also used in samples, e.g. samples/SkijaInjectSample/build.gradle
val commonArtifactId = "skiko" val commonArtifactId = "skiko"
val jvmArtifactId = "skiko-awt" val jvmArtifactId = "skiko-awt"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment