blob: 70603320bd72907e2f811d34c66638334e91822e [file] [log] [blame]
import com.github.jengelman.gradle.plugins.shadow.transformers.Transformer
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
import com.github.jengelman.gradle.plugins.shadow.transformers.TransformerContext
import org.gradle.kotlin.dsl.extra
import org.jetbrains.kotlin.metadata.jvm.JvmModuleProtoBuf
import proguard.gradle.ProGuardTask
import shadow.org.apache.tools.zip.ZipEntry
import shadow.org.apache.tools.zip.ZipOutputStream
import java.io.ByteArrayOutputStream
import java.io.DataInputStream
import java.io.DataOutputStream
description = "Kotlin Full Reflection Library"
plugins { java }
callGroovy("configureJavaOnlyJvm6Project", this)
publish()
val jpsLibraryPath by extra(rootProject.extra["distLibDir"])
val core = "$rootDir/core"
val annotationsSrc = "$buildDir/annotations"
val relocatedCoreSrc = "$buildDir/core-relocated"
val libsDir = property("libsDir")
sourceSets {
"main" {
java.srcDir(annotationsSrc)
}
}
val proguardDeps by configurations.creating
val shadows by configurations.creating {
isTransitive = false
}
configurations.getByName("compileOnly").extendsFrom(shadows)
val mainJar by configurations.creating
dependencies {
compile(project(":kotlin-stdlib"))
proguardDeps(project(":kotlin-stdlib"))
proguardDeps(files(firstFromJavaHomeThatExists("jre/lib/rt.jar", "../Classes/classes.jar", jdkHome = File(property("JDK_16") as String))))
shadows(project(":kotlin-reflect-api"))
shadows(project(":core:metadata"))
shadows(project(":core:metadata.jvm"))
shadows(project(":core:descriptors"))
shadows(project(":core:descriptors.jvm"))
shadows(project(":core:deserialization"))
shadows(project(":core:descriptors.runtime"))
shadows(project(":core:util.runtime"))
shadows("javax.inject:javax.inject:1")
shadows(project(":custom-dependencies:protobuf-lite", configuration = "default"))
}
val copyAnnotations by task<Sync> {
// copy just two missing annotations
from("$core/runtime.jvm/src") {
include("**/Mutable.java")
include("**/ReadOnly.java")
}
into(annotationsSrc)
includeEmptyDirs = false
}
tasks.getByName("compileJava").dependsOn(copyAnnotations)
class KotlinModuleShadowTransformer(private val logger: Logger) : Transformer {
@Suppress("ArrayInDataClass")
private data class Entry(val path: String, val bytes: ByteArray)
private val data = mutableListOf<Entry>()
override fun canTransformResource(element: FileTreeElement): Boolean =
element.path.substringAfterLast(".") == KOTLIN_MODULE
override fun transform(context: TransformerContext) {
fun relocate(content: String): String =
context.relocators.fold(content) { acc, relocator -> relocator.applyToSourceContent(acc) }
val input = DataInputStream(context.`is`)
val version = IntArray(input.readInt()) { input.readInt() }
logger.info("Transforming ${context.path} with version ${version.toList()}")
val table = JvmModuleProtoBuf.Module.parseFrom(context.`is`).toBuilder()
val newTable = JvmModuleProtoBuf.Module.newBuilder().apply {
for (packageParts in table.packagePartsList + table.metadataPartsList) {
addPackageParts(JvmModuleProtoBuf.PackageParts.newBuilder(packageParts).apply {
packageFqName = relocate(packageFqName)
})
}
addAllJvmPackageName(table.jvmPackageNameList.map(::relocate))
}
val baos = ByteArrayOutputStream()
val output = DataOutputStream(baos)
output.writeInt(version.size)
version.forEach(output::writeInt)
newTable.build().writeTo(output)
output.flush()
data += Entry(context.path, baos.toByteArray())
}
override fun hasTransformedResource(): Boolean =
data.isNotEmpty()
override fun modifyOutputStream(os: ZipOutputStream) {
for ((path, bytes) in data) {
os.putNextEntry(ZipEntry(path))
os.write(bytes)
}
data.clear()
}
companion object {
const val KOTLIN_MODULE = "kotlin_module"
}
}
val reflectShadowJar by task<ShadowJar> {
classifier = "shadow"
version = null
callGroovy("manifestAttributes", manifest, project, "Main", true)
from(the<JavaPluginConvention>().sourceSets.getByName("main").output)
from(project(":core:descriptors.jvm").the<JavaPluginConvention>().sourceSets.getByName("main").resources) {
include("META-INF/services/**")
}
from(project(":core:deserialization").the<JavaPluginConvention>().sourceSets.getByName("main").resources) {
include("META-INF/services/**")
}
exclude("**/*.proto")
transform(KotlinModuleShadowTransformer(logger))
configurations = listOf(shadows)
relocate("org.jetbrains.kotlin", "kotlin.reflect.jvm.internal.impl")
relocate("javax.inject", "kotlin.reflect.jvm.internal.impl.javax.inject")
mergeServiceFiles()
}
val stripMetadata by tasks.creating {
dependsOn("reflectShadowJar")
val inputJar = reflectShadowJar.archivePath
val outputJar = File("$libsDir/kotlin-reflect-stripped.jar")
inputs.file(inputJar)
outputs.file(outputJar)
doLast {
stripMetadata(logger, "kotlin/reflect/jvm/internal/impl/.*", inputJar, outputJar)
}
}
val proguardOutput = "$libsDir/${property("archivesBaseName")}-proguard.jar"
val proguard by task<ProGuardTask> {
dependsOn(stripMetadata)
inputs.files(stripMetadata.outputs.files)
outputs.file(proguardOutput)
injars(mapOf("filter" to "!META-INF/versions/**"), stripMetadata.outputs.files)
outjars(proguardOutput)
libraryjars(mapOf("filter" to "!META-INF/versions/**"), proguardDeps)
configuration("$core/reflection.jvm/reflection.pro")
}
val relocateCoreSources by task<Copy> {
doFirst {
delete(relocatedCoreSrc)
}
from("$core/descriptors/src")
from("$core/descriptors.jvm/src")
from("$core/descriptors.runtime/src")
from("$core/deserialization/src")
from("$core/util.runtime/src")
exclude("META-INF/services/**")
into(relocatedCoreSrc)
includeEmptyDirs = false
eachFile {
path = path.replace("org/jetbrains/kotlin", "kotlin/reflect/jvm/internal/impl")
}
filter { line ->
line.replace("org.jetbrains.kotlin", "kotlin.reflect.jvm.internal.impl")
}
}
tasks.getByName("jar").enabled = false
val sourcesJar = sourcesJar(sourceSet = null) {
dependsOn(relocateCoreSources)
from(relocatedCoreSrc)
from("$core/reflection.jvm/src")
}
val result by task<Jar> {
dependsOn(proguard)
from(zipTree(file(proguardOutput)))
from(zipTree(reflectShadowJar.archivePath)) {
include("META-INF/versions/**")
}
callGroovy("manifestAttributes", manifest, project, "Main", true)
}
val dexMethodCount by task<DexMethodCount> {
dependsOn(result)
jarFile = result.outputs.files.single()
ownPackages = listOf("kotlin.reflect")
}
tasks.getByName("check").dependsOn(dexMethodCount)
artifacts {
val artifactJar = mapOf(
"file" to result.outputs.files.single(),
"builtBy" to result,
"name" to property("archivesBaseName")
)
add(mainJar.name, artifactJar)
add("runtime", artifactJar)
add("archives", artifactJar)
}
javadocJar()
dist(fromTask = result) {
from(sourcesJar)
}