Interop/StubGenerator, NativeInteropPlugin: add support for Kotlin Native
Also add minor improvements.
This commit is contained in:
committed by
SvyatoslavScherbina
parent
4b694225c1
commit
cf3b95fb3d
+89
-22
@@ -3,12 +3,20 @@ package org.jetbrains.kotlin.native.interop.gen.jvm
|
|||||||
import org.jetbrains.kotlin.native.interop.indexer.*
|
import org.jetbrains.kotlin.native.interop.indexer.*
|
||||||
import java.lang.IllegalStateException
|
import java.lang.IllegalStateException
|
||||||
|
|
||||||
|
enum class KotlinPlatform {
|
||||||
|
JVM,
|
||||||
|
NATIVE
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: mostly rename 'jni' to 'c'.
|
||||||
|
|
||||||
class StubGenerator(
|
class StubGenerator(
|
||||||
val nativeIndex: NativeIndex,
|
val nativeIndex: NativeIndex,
|
||||||
val pkgName: String,
|
val pkgName: String,
|
||||||
val libName: String,
|
val libName: String,
|
||||||
val excludedFunctions: Set<String>,
|
val excludedFunctions: Set<String>,
|
||||||
val dumpShims: Boolean) {
|
val dumpShims: Boolean,
|
||||||
|
val platform: KotlinPlatform = KotlinPlatform.JVM) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The names that should not be used for struct classes to prevent name clashes
|
* The names that should not be used for struct classes to prevent name clashes
|
||||||
@@ -253,7 +261,7 @@ class StubGenerator(
|
|||||||
override fun argFromJni(name: String) = "CPointer.createNullable<$pointee>($name)"
|
override fun argFromJni(name: String) = "CPointer.createNullable<$pointee>($name)"
|
||||||
|
|
||||||
override val jniType: String
|
override val jniType: String
|
||||||
get() = "Long"
|
get() = "NativePtr"
|
||||||
|
|
||||||
override fun constructPointedType(valueType: String) = "CPointerVarWithValueMappedTo<$valueType>"
|
override fun constructPointedType(valueType: String) = "CPointerVarWithValueMappedTo<$valueType>"
|
||||||
}
|
}
|
||||||
@@ -264,7 +272,7 @@ class StubGenerator(
|
|||||||
override fun argFromJni(name: String) = "interpretPointed<$pointed>($name)"
|
override fun argFromJni(name: String) = "interpretPointed<$pointed>($name)"
|
||||||
|
|
||||||
override val jniType: String
|
override val jniType: String
|
||||||
get() = "Long"
|
get() = "NativePtr"
|
||||||
|
|
||||||
override fun constructPointedType(valueType: String): String {
|
override fun constructPointedType(valueType: String): String {
|
||||||
// TODO: this method must not exist
|
// TODO: this method must not exist
|
||||||
@@ -390,7 +398,7 @@ class StubGenerator(
|
|||||||
kotlinType = "String?",
|
kotlinType = "String?",
|
||||||
kotlinConv = { name -> "$name?.toCString(memScope).rawPtr" },
|
kotlinConv = { name -> "$name?.toCString(memScope).rawPtr" },
|
||||||
memScoped = true,
|
memScoped = true,
|
||||||
kotlinJniBridgeType = "Long"
|
kotlinJniBridgeType = "NativePtr"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -573,7 +581,7 @@ class StubGenerator(
|
|||||||
paramBindings.add(OutValueBinding(
|
paramBindings.add(OutValueBinding(
|
||||||
kotlinType = "NativePlacement",
|
kotlinType = "NativePlacement",
|
||||||
kotlinConv = { name -> "$name.alloc<${retValMirror.pointedTypeName}>().rawPtr" },
|
kotlinConv = { name -> "$name.alloc<${retValMirror.pointedTypeName}>().rawPtr" },
|
||||||
kotlinJniBridgeType = "Long"
|
kotlinJniBridgeType = "NativePtr"
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -614,7 +622,7 @@ class StubGenerator(
|
|||||||
|
|
||||||
val header = "fun ${func.name}($args): ${retValBinding.kotlinType}"
|
val header = "fun ${func.name}($args): ${retValBinding.kotlinType}"
|
||||||
|
|
||||||
fun generateBody() {
|
fun generateBody(memScoped: Boolean) {
|
||||||
val externalParamNames = paramNames.mapIndexed { i: Int, name: String ->
|
val externalParamNames = paramNames.mapIndexed { i: Int, name: String ->
|
||||||
val binding = paramBindings[i]
|
val binding = paramBindings[i]
|
||||||
val externalParamName: String
|
val externalParamName: String
|
||||||
@@ -631,8 +639,9 @@ class StubGenerator(
|
|||||||
}
|
}
|
||||||
out("val res = externals.${func.name}(" + externalParamNames.joinToString(", ") + ")")
|
out("val res = externals.${func.name}(" + externalParamNames.joinToString(", ") + ")")
|
||||||
|
|
||||||
|
val result = retValBinding.conv("res")
|
||||||
if (dumpShims) {
|
if (dumpShims) {
|
||||||
val returnValueRepresentation = retValBinding.conv("res")
|
val returnValueRepresentation = result
|
||||||
out("print(\"\${${returnValueRepresentation}}\\t= \")")
|
out("print(\"\${${returnValueRepresentation}}\\t= \")")
|
||||||
out("print(\"${func.name}( \")")
|
out("print(\"${func.name}( \")")
|
||||||
val argsRepresentation = paramNames.map{"\${${it}}"}.joinToString(", ")
|
val argsRepresentation = paramNames.map{"\${${it}}"}.joinToString(", ")
|
||||||
@@ -640,17 +649,21 @@ class StubGenerator(
|
|||||||
out("println(\")\")")
|
out("println(\")\")")
|
||||||
}
|
}
|
||||||
|
|
||||||
out("return " + retValBinding.conv("res"))
|
if (memScoped) {
|
||||||
|
out(result)
|
||||||
|
} else {
|
||||||
|
out("return " + result)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
block(header) {
|
block(header) {
|
||||||
val memScoped = paramBindings.any { it.memScoped }
|
val memScoped = paramBindings.any { it.memScoped }
|
||||||
if (memScoped) {
|
if (memScoped) {
|
||||||
block("memScoped") {
|
block("return memScoped") {
|
||||||
generateBody()
|
generateBody(true)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
generateBody()
|
generateBody(false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -696,6 +709,11 @@ class StubGenerator(
|
|||||||
private fun generateFunctionType(type: FunctionType, name: String) {
|
private fun generateFunctionType(type: FunctionType, name: String) {
|
||||||
val kotlinFunctionType = getKotlinFunctionType(type)
|
val kotlinFunctionType = getKotlinFunctionType(type)
|
||||||
|
|
||||||
|
if (platform == KotlinPlatform.NATIVE) {
|
||||||
|
out("object $name : CFunctionType {}")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
val constructorArgs = listOf(getRetValFfiType(type.returnType)) +
|
val constructorArgs = listOf(getRetValFfiType(type.returnType)) +
|
||||||
type.parameterTypes.map { getArgFfiType(it) }
|
type.parameterTypes.map { getArgFfiType(it) }
|
||||||
|
|
||||||
@@ -727,6 +745,12 @@ class StubGenerator(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private val FunctionDecl.stubSymbolName: String
|
||||||
|
get() {
|
||||||
|
require(platform == KotlinPlatform.NATIVE)
|
||||||
|
return "kni_" + pkgName.replace('/', '_') + '_' + this.name
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Produces to [out] the definition of Kotlin JNI function used in binding for given C function.
|
* Produces to [out] the definition of Kotlin JNI function used in binding for given C function.
|
||||||
*/
|
*/
|
||||||
@@ -739,6 +763,9 @@ class StubGenerator(
|
|||||||
"$name: " + paramBindings[i].kotlinJniBridgeType
|
"$name: " + paramBindings[i].kotlinJniBridgeType
|
||||||
}.joinToString(", ")
|
}.joinToString(", ")
|
||||||
|
|
||||||
|
if (platform == KotlinPlatform.NATIVE) {
|
||||||
|
out("@SymbolName(\"${func.stubSymbolName}\")")
|
||||||
|
}
|
||||||
out("external fun ${func.name}($args): ${retValBinding.kotlinJniBridgeType}")
|
out("external fun ${func.name}($args): ${retValBinding.kotlinJniBridgeType}")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -797,7 +824,9 @@ class StubGenerator(
|
|||||||
}
|
}
|
||||||
|
|
||||||
block("object externals") {
|
block("object externals") {
|
||||||
out("init { System.loadLibrary(\"$libName\") }")
|
if (platform == KotlinPlatform.JVM) {
|
||||||
|
out("init { System.loadLibrary(\"$libName\") }")
|
||||||
|
}
|
||||||
functionsToBind.forEach {
|
functionsToBind.forEach {
|
||||||
try {
|
try {
|
||||||
transaction {
|
transaction {
|
||||||
@@ -811,6 +840,28 @@ class StubGenerator(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the C type to be used for value of given Kotlin type in JNI function implementation.
|
||||||
|
*/
|
||||||
|
fun getCBridgeType(kotlinJniBridgeType: String): String {
|
||||||
|
return when (platform) {
|
||||||
|
KotlinPlatform.JVM -> getCJniBridgeType(kotlinJniBridgeType)
|
||||||
|
KotlinPlatform.NATIVE -> getCNativeBridgeType(kotlinJniBridgeType)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getCNativeBridgeType(kotlinJniBridgeType: String) = when (kotlinJniBridgeType) {
|
||||||
|
"Unit" -> "void"
|
||||||
|
"Byte" -> "int8_t"
|
||||||
|
"Short" -> "int16_t"
|
||||||
|
"Int" -> "int32_t"
|
||||||
|
"Long" -> "int64_t"
|
||||||
|
"Float" -> "float"
|
||||||
|
"Double" -> "double" // TODO: float32_t, float64_t?
|
||||||
|
"NativePtr" -> "void*"
|
||||||
|
else -> TODO(kotlinJniBridgeType)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the C type to be used for value of given Kotlin type in JNI function implementation.
|
* Returns the C type to be used for value of given Kotlin type in JNI function implementation.
|
||||||
*/
|
*/
|
||||||
@@ -819,7 +870,9 @@ class StubGenerator(
|
|||||||
"Byte" -> "jbyte"
|
"Byte" -> "jbyte"
|
||||||
"Short" -> "jshort"
|
"Short" -> "jshort"
|
||||||
"Int" -> "jint"
|
"Int" -> "jint"
|
||||||
"Long" -> "jlong"
|
"Long", "NativePtr" -> "jlong"
|
||||||
|
"Float" -> "jfloat"
|
||||||
|
"Double" -> "jdouble"
|
||||||
else -> throw NotImplementedError(kotlinJniBridgeType)
|
else -> throw NotImplementedError(kotlinJniBridgeType)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -828,7 +881,9 @@ class StubGenerator(
|
|||||||
*/
|
*/
|
||||||
fun generateCFile(headerFiles: List<String>) {
|
fun generateCFile(headerFiles: List<String>) {
|
||||||
out("#include <stdint.h>")
|
out("#include <stdint.h>")
|
||||||
out("#include <jni.h>")
|
if (platform == KotlinPlatform.JVM) {
|
||||||
|
out("#include <jni.h>")
|
||||||
|
}
|
||||||
headerFiles.forEach {
|
headerFiles.forEach {
|
||||||
out("#include <$it>")
|
out("#include <$it>")
|
||||||
}
|
}
|
||||||
@@ -856,11 +911,11 @@ class StubGenerator(
|
|||||||
if (paramBindings.isEmpty())
|
if (paramBindings.isEmpty())
|
||||||
""
|
""
|
||||||
else paramBindings
|
else paramBindings
|
||||||
.map { getCJniBridgeType(it.kotlinJniBridgeType) }
|
.map { getCBridgeType(it.kotlinJniBridgeType) }
|
||||||
.mapIndexed { i, type -> "$type ${paramNames[i]}" }
|
.mapIndexed { i, type -> "$type ${paramNames[i]}" }
|
||||||
.joinToString(separator = ", ", prefix = ", ")
|
.joinToString(separator = ", ", prefix = ", ")
|
||||||
|
|
||||||
val cReturnType = getCJniBridgeType(retValBinding.kotlinJniBridgeType)
|
val cReturnType = getCBridgeType(retValBinding.kotlinJniBridgeType)
|
||||||
|
|
||||||
val params = func.parameters.mapIndexed { i, parameter ->
|
val params = func.parameters.mapIndexed { i, parameter ->
|
||||||
val cType = parameter.type.getStringRepresentation()
|
val cType = parameter.type.getStringRepresentation()
|
||||||
@@ -872,14 +927,26 @@ class StubGenerator(
|
|||||||
}.joinToString(", ")
|
}.joinToString(", ")
|
||||||
|
|
||||||
val callExpr = "${func.name}($params)"
|
val callExpr = "${func.name}($params)"
|
||||||
val funcFullName = if (pkgName.isEmpty()) {
|
val jniFuncName = when (platform) {
|
||||||
"externals.${func.name}"
|
KotlinPlatform.JVM -> {
|
||||||
} else {
|
val funcFullName = if (pkgName.isEmpty()) {
|
||||||
"$pkgName.externals.${func.name}"
|
"externals.${func.name}"
|
||||||
|
} else {
|
||||||
|
"$pkgName.externals.${func.name}"
|
||||||
|
}
|
||||||
|
"Java_" + funcFullName.replace("_", "_1").replace('.', '_').replace("$", "_00024")
|
||||||
|
}
|
||||||
|
KotlinPlatform.NATIVE -> {
|
||||||
|
func.stubSymbolName
|
||||||
|
}
|
||||||
}
|
}
|
||||||
val jniFuncName = "Java_" + funcFullName.replace("_", "_1").replace('.', '_').replace("$", "_00024")
|
|
||||||
|
|
||||||
block("JNIEXPORT $cReturnType JNICALL $jniFuncName (JNIEnv *env, jobject obj$args)") {
|
val funcDecl = when (platform) {
|
||||||
|
KotlinPlatform.JVM -> "JNIEXPORT $cReturnType JNICALL $jniFuncName (JNIEnv *env, jobject obj$args)"
|
||||||
|
KotlinPlatform.NATIVE -> "$cReturnType $jniFuncName (void* obj$args)"
|
||||||
|
}
|
||||||
|
|
||||||
|
block(funcDecl) {
|
||||||
|
|
||||||
if (cReturnType == "void") {
|
if (cReturnType == "void") {
|
||||||
out("$callExpr;")
|
out("$callExpr;")
|
||||||
|
|||||||
+40
-22
@@ -99,6 +99,10 @@ private fun processLib(ktGenRoot: String,
|
|||||||
|
|
||||||
val args = additionalArgs.groupBy ({ getArgPrefix(it)!! }, { dropPrefix(it)!! }) // TODO
|
val args = additionalArgs.groupBy ({ getArgPrefix(it)!! }, { dropPrefix(it)!! }) // TODO
|
||||||
|
|
||||||
|
val platformName = args["-target"]?.single() ?: "jvm"
|
||||||
|
|
||||||
|
val platform = KotlinPlatform.values().single { it.name.equals(platformName, ignoreCase = true) }
|
||||||
|
|
||||||
val defFile = args["-def"]?.single()?.let { File(it) }
|
val defFile = args["-def"]?.single()?.let { File(it) }
|
||||||
|
|
||||||
val config = Properties()
|
val config = Properties()
|
||||||
@@ -133,7 +137,7 @@ private fun processLib(ktGenRoot: String,
|
|||||||
|
|
||||||
val nativeIndex = buildNativeIndex(headerFiles, compilerOpts)
|
val nativeIndex = buildNativeIndex(headerFiles, compilerOpts)
|
||||||
|
|
||||||
val gen = StubGenerator(nativeIndex, outKtPkg, libName, excludedFunctions, generateShims)
|
val gen = StubGenerator(nativeIndex, outKtPkg, libName, excludedFunctions, generateShims, platform)
|
||||||
|
|
||||||
outKtFile.parentFile.mkdirs()
|
outKtFile.parentFile.mkdirs()
|
||||||
outKtFile.bufferedWriter().use { out ->
|
outKtFile.bufferedWriter().use { out ->
|
||||||
@@ -151,36 +155,50 @@ private fun processLib(ktGenRoot: String,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val outOFile = createTempFile(suffix = ".o")
|
File(nativeLibsDir).mkdirs()
|
||||||
|
|
||||||
val javaHome = System.getProperty("java.home")
|
|
||||||
val compilerArgsForJniIncludes = listOf("", "linux", "darwin").map { "-I$javaHome/../include/$it" }.toTypedArray()
|
|
||||||
|
|
||||||
val compilerCmd = arrayOf("$llvmInstallPath/bin/$compiler", *compilerOpts.toTypedArray(),
|
|
||||||
*compilerArgsForJniIncludes,
|
|
||||||
"-c", outCFile.path, "-o", outOFile.path)
|
|
||||||
|
|
||||||
val workDir = defFile?.parentFile ?: File(System.getProperty("java.io.tmpdir"))
|
val workDir = defFile?.parentFile ?: File(System.getProperty("java.io.tmpdir"))
|
||||||
|
|
||||||
ProcessBuilder(*compilerCmd)
|
if (platform == KotlinPlatform.JVM) {
|
||||||
.directory(workDir)
|
|
||||||
.inheritIO()
|
|
||||||
.runExpectingSuccess()
|
|
||||||
|
|
||||||
File(nativeLibsDir).mkdirs()
|
val outOFile = createTempFile(suffix = ".o")
|
||||||
|
|
||||||
val outLib = nativeLibsDir + "/" + System.mapLibraryName(libName)
|
val javaHome = System.getProperty("java.home")
|
||||||
|
val compilerArgsForJniIncludes = listOf("", "linux", "darwin").map { "-I$javaHome/../include/$it" }.toTypedArray()
|
||||||
|
|
||||||
val linkerCmd = arrayOf("$llvmInstallPath/bin/$linker", *linkerOpts, outOFile.path, "-shared", "-o", outLib,
|
val compilerCmd = arrayOf("$llvmInstallPath/bin/$compiler", *compilerOpts.toTypedArray(),
|
||||||
"-Wl,-flat_namespace,-undefined,dynamic_lookup")
|
*compilerArgsForJniIncludes,
|
||||||
|
"-c", outCFile.path, "-o", outOFile.path)
|
||||||
|
|
||||||
ProcessBuilder(*linkerCmd)
|
ProcessBuilder(*compilerCmd)
|
||||||
.directory(workDir)
|
.directory(workDir)
|
||||||
.inheritIO()
|
.inheritIO()
|
||||||
.runExpectingSuccess()
|
.runExpectingSuccess()
|
||||||
|
|
||||||
|
val outLib = nativeLibsDir + "/" + System.mapLibraryName(libName)
|
||||||
|
|
||||||
|
val linkerCmd = arrayOf("$llvmInstallPath/bin/$linker", *linkerOpts, outOFile.path, "-shared", "-o", outLib,
|
||||||
|
"-Wl,-flat_namespace,-undefined,dynamic_lookup")
|
||||||
|
|
||||||
|
ProcessBuilder(*linkerCmd)
|
||||||
|
.directory(workDir)
|
||||||
|
.inheritIO()
|
||||||
|
.runExpectingSuccess()
|
||||||
|
|
||||||
|
outOFile.delete()
|
||||||
|
} else if (platform == KotlinPlatform.NATIVE) {
|
||||||
|
val outBcName = libName + ".bc"
|
||||||
|
val outLib = nativeLibsDir + "/" + outBcName
|
||||||
|
val compilerCmd = arrayOf("$llvmInstallPath/bin/$compiler", *compilerOpts.toTypedArray(),
|
||||||
|
"-emit-llvm", "-c", outCFile.path, "-o", outLib)
|
||||||
|
|
||||||
|
ProcessBuilder(*compilerCmd)
|
||||||
|
.directory(workDir)
|
||||||
|
.inheritIO()
|
||||||
|
.runExpectingSuccess()
|
||||||
|
}
|
||||||
|
|
||||||
outCFile.delete()
|
outCFile.delete()
|
||||||
outOFile.delete()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun buildNativeIndex(headerFiles: List<String>, compilerOpts: List<String>): NativeIndex {
|
private fun buildNativeIndex(headerFiles: List<String>, compilerOpts: List<String>): NativeIndex {
|
||||||
|
|||||||
@@ -18,15 +18,19 @@ class NamedNativeInteropConfig implements Named {
|
|||||||
private final Project project
|
private final Project project
|
||||||
final String name
|
final String name
|
||||||
|
|
||||||
private final SourceSet interopStubs
|
|
||||||
private final JavaExec genTask
|
private String interopStubsName
|
||||||
|
private SourceSet interopStubs
|
||||||
|
final JavaExec genTask
|
||||||
|
|
||||||
|
private String target = "jvm"
|
||||||
|
|
||||||
private String defFile
|
private String defFile
|
||||||
|
|
||||||
private String pkg;
|
private String pkg;
|
||||||
|
|
||||||
private List<String> compilerOpts = []
|
private List<String> compilerOpts = []
|
||||||
private FileCollection headers;
|
private List<String> headers;
|
||||||
private String linker
|
private String linker
|
||||||
private List<String> linkerOpts = []
|
private List<String> linkerOpts = []
|
||||||
private FileCollection linkFiles;
|
private FileCollection linkFiles;
|
||||||
@@ -34,6 +38,10 @@ class NamedNativeInteropConfig implements Named {
|
|||||||
|
|
||||||
Configuration configuration
|
Configuration configuration
|
||||||
|
|
||||||
|
void target(String value) {
|
||||||
|
target = value
|
||||||
|
}
|
||||||
|
|
||||||
void defFile(String value) {
|
void defFile(String value) {
|
||||||
defFile = value
|
defFile = value
|
||||||
genTask.inputs.file(project.file(defFile))
|
genTask.inputs.file(project.file(defFile))
|
||||||
@@ -49,7 +57,11 @@ class NamedNativeInteropConfig implements Named {
|
|||||||
|
|
||||||
void headers(FileCollection files) {
|
void headers(FileCollection files) {
|
||||||
dependsOnFiles(files)
|
dependsOnFiles(files)
|
||||||
headers = headers + files
|
headers = headers + files.toSet().collect { it.absolutePath }
|
||||||
|
}
|
||||||
|
|
||||||
|
void headers(String... values) {
|
||||||
|
headers = headers + values.toList()
|
||||||
}
|
}
|
||||||
|
|
||||||
void linker(String value) {
|
void linker(String value) {
|
||||||
@@ -107,11 +119,11 @@ class NamedNativeInteropConfig implements Named {
|
|||||||
compilerOpts.addAll(values.collect {"-I$it"})
|
compilerOpts.addAll(values.collect {"-I$it"})
|
||||||
}
|
}
|
||||||
|
|
||||||
private File getNativeLibsDir() {
|
File getNativeLibsDir() {
|
||||||
return new File(project.buildDir, "nativelibs")
|
return new File(project.buildDir, "nativelibs")
|
||||||
}
|
}
|
||||||
|
|
||||||
private File getGeneratedSrcDir() {
|
File getGeneratedSrcDir() {
|
||||||
return new File(project.buildDir, "nativeInteropStubs/$name/kotlin")
|
return new File(project.buildDir, "nativeInteropStubs/$name/kotlin")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -119,25 +131,31 @@ class NamedNativeInteropConfig implements Named {
|
|||||||
this.name = name
|
this.name = name
|
||||||
this.project = project
|
this.project = project
|
||||||
|
|
||||||
this.headers = project.files()
|
this.headers = []
|
||||||
this.linkFiles = project.files()
|
this.linkFiles = project.files()
|
||||||
|
|
||||||
interopStubs = project.sourceSets.create(name + "InteropStubs")
|
interopStubsName = name + "InteropStubs"
|
||||||
genTask = project.task(interopStubs.getTaskName("gen", ""), type: JavaExec)
|
genTask = project.task("gen" + interopStubsName.capitalize(), type: JavaExec)
|
||||||
configuration = project.configurations.create(interopStubs.name)
|
|
||||||
|
|
||||||
this.configure()
|
this.configure()
|
||||||
}
|
}
|
||||||
|
|
||||||
private void configure() {
|
private void configure() {
|
||||||
project.tasks.getByName(interopStubs.getTaskName("compile", "Kotlin")) {
|
if (project.plugins.hasPlugin("kotlin")) {
|
||||||
dependsOn genTask
|
interopStubs = project.sourceSets.create(interopStubsName)
|
||||||
}
|
configuration = project.configurations.create(interopStubs.name)
|
||||||
|
project.tasks.getByName(interopStubs.getTaskName("compile", "Kotlin")) {
|
||||||
|
dependsOn genTask
|
||||||
|
}
|
||||||
|
|
||||||
interopStubs.kotlin.srcDirs generatedSrcDir
|
interopStubs.kotlin.srcDirs generatedSrcDir
|
||||||
|
|
||||||
project.dependencies {
|
project.dependencies {
|
||||||
add interopStubs.getCompileConfigurationName(), project(path: ':Interop:Runtime')
|
add interopStubs.getCompileConfigurationName(), project(path: ':Interop:Runtime')
|
||||||
|
}
|
||||||
|
|
||||||
|
this.configuration.extendsFrom project.configurations[interopStubs.runtimeConfigurationName]
|
||||||
|
project.dependencies.add(this.configuration.name, interopStubs.output)
|
||||||
}
|
}
|
||||||
|
|
||||||
genTask.configure {
|
genTask.configure {
|
||||||
@@ -166,6 +184,9 @@ class NamedNativeInteropConfig implements Named {
|
|||||||
linkerOpts += linkFiles.files
|
linkerOpts += linkFiles.files
|
||||||
|
|
||||||
args = [generatedSrcDir, nativeLibsDir]
|
args = [generatedSrcDir, nativeLibsDir]
|
||||||
|
|
||||||
|
args "-target:" + this.target
|
||||||
|
|
||||||
if (defFile != null) {
|
if (defFile != null) {
|
||||||
args "-def:" + project.file(defFile)
|
args "-def:" + project.file(defFile)
|
||||||
}
|
}
|
||||||
@@ -188,7 +209,7 @@ class NamedNativeInteropConfig implements Named {
|
|||||||
args compilerOpts.collect { "-copt:$it" }
|
args compilerOpts.collect { "-copt:$it" }
|
||||||
args linkerOpts.collect { "-lopt:$it" }
|
args linkerOpts.collect { "-lopt:$it" }
|
||||||
|
|
||||||
headers.files.each {
|
headers.each {
|
||||||
args "-h:$it"
|
args "-h:$it"
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -198,9 +219,6 @@ class NamedNativeInteropConfig implements Named {
|
|||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.configuration.extendsFrom project.configurations[interopStubs.runtimeConfigurationName]
|
|
||||||
project.dependencies.add(this.configuration.name, interopStubs.output)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user