Animesh Sahu
12/30/2020, 11:18 AMAnimesh Sahu
12/30/2020, 11:20 AMval generateJniHeaders by tasks.creating {
group = "build"
dependsOn(tasks.getByName("compileKotlinJvm"))
// For caching
inputs.dir("src/jvmMain/kotlin")
outputs.dir("src/jvmMain/generated/jni")
doLast {
val javaHome = Jvm.current().javaHome
val javap = javaHome.resolve("bin").walk().firstOrNull { it.name.startsWith("javap") }?.absolutePath ?: error("javap not found")
val javac = javaHome.resolve("bin").walk().firstOrNull { it.name.startsWith("javac") }?.absolutePath ?: error("javac not found")
val buildDir = file("build/classes/kotlin/jvm/main")
val tmpDir = file("build/tmp/jvmJni").apply { mkdirs() }
buildDir.walkTopDown()
.filter { "META" !in it.absolutePath }
.forEach { file ->
if (!file.isFile) return@forEach
val output = ByteArrayOutputStream().use {
project.exec {
commandLine(javap, "-private", "-cp", buildDir.absolutePath, file.absolutePath)
standardOutput = it
}.assertNormalExitValue()
it.toString()
}
val (packageName, className, methodInfo) =
"""public \w*\s*class (.+)\.(\w+) (?:implements|extends).*\{\R([^\}]*)\}""".toRegex().find(output)?.destructured ?: return@forEach
val nativeMethods =
""".*\bnative\b.*""".toRegex().findAll(methodInfo).mapNotNull { it.groups }.flatMap { it.asSequence().mapNotNull { group -> group?.value } }.toList()
if (nativeMethods.isEmpty()) return@forEach
val source = buildString {
appendln("package $packageName;")
appendln("public class $className {")
for (method in nativeMethods) {
if ("()" in method) appendln(method)
else {
val updatedMethod = StringBuilder(method).apply {
var count = 0
var i = 0
while (i < length) {
if (this[i] == ',' || this[i] == ')') insert(i, " arg${count++}".also { i += it.length })
else i++
}
}
appendln(updatedMethod)
}
}
appendln("}")
}
val outputFile = tmpDir.resolve(packageName.replace(".", "/")).apply { mkdirs() }.resolve("$className.java").apply { delete() }.apply { createNewFile() }
outputFile.writeText(source)
project.exec {
commandLine(javac, "-h", jniHeaderDirectory.absolutePath, outputFile.absolutePath)
}.assertNormalExitValue()
}
}
}
Animesh Sahu
12/30/2020, 11:23 AMAnimesh Sahu
12/30/2020, 11:23 AMif (this[i] == ',' || this[i] == ')') insert(i, " arg${count++}".also { i += it.length + 1 })
Animesh Sahu
12/30/2020, 11:23 AMandylamax
12/30/2020, 4:29 PM