blob: 431443e686df81c140230f040d646be57984d0a3 [file] [log] [blame] [edit]
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
import com.github.jengelman.gradle.plugins.shadow.transformers.Transformer
import com.github.jengelman.gradle.plugins.shadow.transformers.TransformerContext
import kotlinx.metadata.jvm.KmModuleVisitor
import kotlinx.metadata.jvm.KotlinModuleMetadata
import proguard.gradle.ProGuardTask
import shadow.org.apache.tools.zip.ZipEntry
import shadow.org.apache.tools.zip.ZipOutputStream
description = "Kotlin Full Reflection Library"
buildscript {
dependencies {
classpath("org.jetbrains.kotlinx:kotlinx-metadata-jvm:0.1.0")
}
}
plugins {
java
id("pill-configurable")
}
callGroovy("configureJavaOnlyJvm6Project", this)
publish()
pill {
importAsLibrary = true
}
val core = "$rootDir/core"
val relocatedCoreSrc = "$buildDir/core-relocated"
val libsDir = property("libsDir")
val proguardDeps by configurations.creating
val proguardAdditionalInJars by configurations.creating
val embedded by configurations
embedded.isTransitive = false
configurations.getByName("compileOnly").extendsFrom(embedded)
val mainJar by configurations.creating
dependencies {
compile(kotlinStdlib())
proguardDeps(kotlinStdlib())
proguardAdditionalInJars(project(":kotlin-annotations-jvm"))
proguardDeps(files(firstFromJavaHomeThatExists("jre/lib/rt.jar", "../Classes/classes.jar", jdkHome = File(property("JDK_16") as String))))
embedded(project(":core:type-system"))
embedded(project(":kotlin-reflect-api"))
embedded(project(":core:metadata"))
embedded(project(":core:metadata.jvm"))
embedded(project(":core:descriptors"))
embedded(project(":core:descriptors.jvm"))
embedded(project(":core:deserialization"))
embedded(project(":core:descriptors.runtime"))
embedded(project(":core:util.runtime"))
embedded("javax.inject:javax.inject:1")
embedded(protobufLite())
compileOnly("org.jetbrains:annotations:13.0")
}
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 metadata = KotlinModuleMetadata.read(context.`is`.readBytes())
?: error("Not a .kotlin_module file: ${context.path}")
val writer = KotlinModuleMetadata.Writer()
logger.info("Transforming ${context.path}")
metadata.accept(object : KmModuleVisitor(writer) {
override fun visitPackageParts(fqName: String, fileFacades: List<String>, multiFileClassParts: Map<String, String>) {
assert(multiFileClassParts.isEmpty()) { multiFileClassParts } // There are no multi-file class parts in core
super.visitPackageParts(relocate(fqName), fileFacades.map(::relocate), multiFileClassParts)
}
})
data += Entry(context.path, writer.write().bytes)
}
override fun hasTransformedResource(): Boolean =
data.isNotEmpty()
override fun modifyOutputStream(os: ZipOutputStream, preserveFileTimestamps: Boolean) {
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> {
archiveClassifier.set("shadow")
configurations = listOf(embedded)
callGroovy("manifestAttributes", manifest, project, "Main" /*true*/)
exclude("**/*.proto")
if (kotlinBuildProperties.relocation) {
mergeServiceFiles()
transform(KotlinModuleShadowTransformer(logger))
relocate("org.jetbrains.kotlin", "kotlin.reflect.jvm.internal.impl")
relocate("javax.inject", "kotlin.reflect.jvm.internal.impl.javax.inject")
}
}
val stripMetadata by tasks.registering {
dependsOn(reflectShadowJar)
val inputJar = provider { reflectShadowJar.get().outputs.files.singleFile }
val outputJar = File("$libsDir/kotlin-reflect-stripped.jar")
inputs.file(inputJar)
outputs.file(outputJar)
doLast {
stripMetadata(logger, "kotlin/reflect/jvm/internal/impl/.*", inputJar.get(), outputJar)
}
}
val proguardOutput = "$libsDir/${property("archivesBaseName")}-proguard.jar"
val proguard by task<ProGuardTask> {
dependsOn(stripMetadata)
inputs.files(stripMetadata.get().outputs.files)
outputs.file(proguardOutput)
injars(mapOf("filter" to "!META-INF/versions/**"), stripMetadata.get().outputs.files)
injars(mapOf("filter" to "!META-INF/**,!**/*.kotlin_builtins"), proguardAdditionalInJars)
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 = tasks.register<Jar>("sourcesJar") {
archiveClassifier.set("sources")
dependsOn(relocateCoreSources)
from(relocatedCoreSrc)
from("$core/reflection.jvm/src")
}
addArtifact("archives", sourcesJar)
addArtifact("sources", sourcesJar)
val result by task<Jar> {
val task = when {
kotlinBuildProperties.proguard -> proguard
kotlinBuildProperties.relocation -> stripMetadata
else -> reflectShadowJar
}
dependsOn(task)
from {
zipTree(task.get().outputs.files.singleFile)
}
callGroovy("manifestAttributes", manifest, project, "Main")
}
val modularJar by task<Jar> {
dependsOn(proguard)
archiveClassifier.set("modular")
from(zipTree(file(proguardOutput)))
from(zipTree(reflectShadowJar.get().archivePath)) {
include("META-INF/versions/**")
}
callGroovy("manifestAttributes", manifest, project, "Main", true)
}
val dexMethodCount by task<DexMethodCount> {
dependsOn(result)
jarFile = result.get().outputs.files.single()
ownPackages = listOf("kotlin.reflect")
}
tasks.getByName("check").dependsOn(dexMethodCount)
artifacts {
listOf(mainJar.name, "runtime", "archives").forEach { configurationName ->
add(configurationName, result.get().outputs.files.singleFile) {
builtBy(result)
}
}
add("archives", modularJar)
}
javadocJar()