Interop: handle all main.kotlin.srcDirs in Gradle plugin
also fix minor bug with default package
This commit is contained in:
+89
-84
@@ -9,96 +9,101 @@ import kotlin.system.exitProcess
|
|||||||
fun main(args: Array<String>) {
|
fun main(args: Array<String>) {
|
||||||
val llvmInstallPath = System.getProperty("llvmInstallPath")!!
|
val llvmInstallPath = System.getProperty("llvmInstallPath")!!
|
||||||
|
|
||||||
val ktSrcRoot = args[0]
|
val ktGenRoot = args[0]
|
||||||
val ktGenRoot = args[1]
|
val nativeLibsDir = args[1]
|
||||||
val nativeLibsDir = args[2]
|
val ktSrcRoots = args.drop(2)
|
||||||
|
|
||||||
val defFiles = File(ktSrcRoot).walk().filter { it.name.endsWith(".def") }
|
ktSrcRoots.forEach { ktSrcRoot ->
|
||||||
|
val defFiles = File(ktSrcRoot).walk().filter { it.name.endsWith(".def") }
|
||||||
|
|
||||||
defFiles.forEach { defFile ->
|
defFiles.forEach { defFile ->
|
||||||
val config = Properties()
|
processDefFile(ktSrcRoot, defFile, ktGenRoot, nativeLibsDir, llvmInstallPath)
|
||||||
defFile.bufferedReader().use { reader ->
|
|
||||||
config.load(reader)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val headerFiles = config.getProperty("headers").split(' ')
|
|
||||||
val compilerOpts = config.getProperty("compilerOpts").split(' ')
|
|
||||||
val compiler = config.getProperty("compiler")
|
|
||||||
val libName = config.getProperty("libName")
|
|
||||||
val linkerOpts = config.getProperty("linkerOpts").split(' ').toTypedArray()
|
|
||||||
val linker = config.getProperty("linker")
|
|
||||||
val excludedFunctions = config.getProperty("excludedFunctions")?.split(' ')?.toSet() ?: emptySet()
|
|
||||||
|
|
||||||
|
|
||||||
val defFileRelative = defFile.relativeTo(File(ktSrcRoot))
|
|
||||||
val outKtFile = File(ktGenRoot, defFileRelative.toString().substringBeforeLast(".def") + ".kt")
|
|
||||||
val outKtPkg = defFileRelative.parentFile.path.replace(File.separatorChar, '.')
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
val nativeIndex = buildNativeIndex(headerFiles, compilerOpts)
|
|
||||||
|
|
||||||
val gen = StubGenerator(nativeIndex, outKtPkg, libName, excludedFunctions)
|
|
||||||
|
|
||||||
outKtFile.parentFile.mkdirs()
|
|
||||||
outKtFile.bufferedWriter().use { out ->
|
|
||||||
gen.withOutput({ out.appendln(it) }) {
|
|
||||||
gen.generateKotlinFile()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
val outCFile = createTempFile(suffix = ".c")
|
|
||||||
|
|
||||||
outCFile.bufferedWriter().use { out ->
|
|
||||||
gen.withOutput({ out.appendln(it) }) {
|
|
||||||
gen.generateCFile(headerFiles)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val outOFile = createTempFile(suffix = ".o")
|
|
||||||
|
|
||||||
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)
|
|
||||||
|
|
||||||
println(compilerCmd.joinToString(" "))
|
|
||||||
|
|
||||||
val compilerRes = ProcessBuilder(*compilerCmd)
|
|
||||||
.inheritIO()
|
|
||||||
.start()
|
|
||||||
.waitFor()
|
|
||||||
|
|
||||||
if (compilerRes != 0) {
|
|
||||||
exitProcess(compilerRes)
|
|
||||||
}
|
|
||||||
|
|
||||||
File(nativeLibsDir).mkdirs()
|
|
||||||
|
|
||||||
val outLib = nativeLibsDir + "/" + System.mapLibraryName(libName)
|
|
||||||
|
|
||||||
val linkerCmd = arrayOf("$llvmInstallPath/bin/$linker", *linkerOpts, outOFile.path, "-shared", "-o", outLib,
|
|
||||||
"-Wl,-flat_namespace,-undefined,dynamic_lookup")
|
|
||||||
|
|
||||||
println(linkerCmd.joinToString(" "))
|
|
||||||
|
|
||||||
val linkerRes = ProcessBuilder(*linkerCmd)
|
|
||||||
.inheritIO()
|
|
||||||
.start()
|
|
||||||
.waitFor()
|
|
||||||
|
|
||||||
if (linkerRes != 0) {
|
|
||||||
exitProcess(linkerRes)
|
|
||||||
}
|
|
||||||
|
|
||||||
outCFile.delete()
|
|
||||||
outOFile.delete()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun processDefFile(ktSrcRoot: String, defFile: File, ktGenRoot: String, nativeLibsDir: String, llvmInstallPath: String) {
|
||||||
|
val config = Properties()
|
||||||
|
defFile.bufferedReader().use { reader ->
|
||||||
|
config.load(reader)
|
||||||
|
}
|
||||||
|
|
||||||
|
val headerFiles = config.getProperty("headers").split(' ')
|
||||||
|
val compilerOpts = config.getProperty("compilerOpts").split(' ')
|
||||||
|
val compiler = config.getProperty("compiler")
|
||||||
|
val libName = config.getProperty("libName")
|
||||||
|
val linkerOpts = config.getProperty("linkerOpts").split(' ').toTypedArray()
|
||||||
|
val linker = config.getProperty("linker")
|
||||||
|
val excludedFunctions = config.getProperty("excludedFunctions")?.split(' ')?.toSet() ?: emptySet()
|
||||||
|
|
||||||
|
|
||||||
|
val defFileRelative = defFile.relativeTo(File(ktSrcRoot))
|
||||||
|
val outKtFile = File(ktGenRoot, defFileRelative.toString().substringBeforeLast(".def") + ".kt")
|
||||||
|
val outKtPkg = defFileRelative.parentFile?.path?.replace(File.separatorChar, '.') ?: ""
|
||||||
|
|
||||||
|
|
||||||
|
val nativeIndex = buildNativeIndex(headerFiles, compilerOpts)
|
||||||
|
|
||||||
|
val gen = StubGenerator(nativeIndex, outKtPkg, libName, excludedFunctions)
|
||||||
|
|
||||||
|
outKtFile.parentFile.mkdirs()
|
||||||
|
outKtFile.bufferedWriter().use { out ->
|
||||||
|
gen.withOutput({ out.appendln(it) }) {
|
||||||
|
gen.generateKotlinFile()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
val outCFile = createTempFile(suffix = ".c")
|
||||||
|
|
||||||
|
outCFile.bufferedWriter().use { out ->
|
||||||
|
gen.withOutput({ out.appendln(it) }) {
|
||||||
|
gen.generateCFile(headerFiles)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val outOFile = createTempFile(suffix = ".o")
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
|
println(compilerCmd.joinToString(" "))
|
||||||
|
|
||||||
|
val compilerRes = ProcessBuilder(*compilerCmd)
|
||||||
|
.inheritIO()
|
||||||
|
.start()
|
||||||
|
.waitFor()
|
||||||
|
|
||||||
|
if (compilerRes != 0) {
|
||||||
|
exitProcess(compilerRes)
|
||||||
|
}
|
||||||
|
|
||||||
|
File(nativeLibsDir).mkdirs()
|
||||||
|
|
||||||
|
val outLib = nativeLibsDir + "/" + System.mapLibraryName(libName)
|
||||||
|
|
||||||
|
val linkerCmd = arrayOf("$llvmInstallPath/bin/$linker", *linkerOpts, outOFile.path, "-shared", "-o", outLib,
|
||||||
|
"-Wl,-flat_namespace,-undefined,dynamic_lookup")
|
||||||
|
|
||||||
|
println(linkerCmd.joinToString(" "))
|
||||||
|
|
||||||
|
val linkerRes = ProcessBuilder(*linkerCmd)
|
||||||
|
.inheritIO()
|
||||||
|
.start()
|
||||||
|
.waitFor()
|
||||||
|
|
||||||
|
if (linkerRes != 0) {
|
||||||
|
exitProcess(linkerRes)
|
||||||
|
}
|
||||||
|
|
||||||
|
outCFile.delete()
|
||||||
|
outOFile.delete()
|
||||||
|
}
|
||||||
|
|
||||||
private fun buildNativeIndex(headerFiles: List<String>, compilerOpts: List<String>): NativeIndex {
|
private fun buildNativeIndex(headerFiles: List<String>, compilerOpts: List<String>): NativeIndex {
|
||||||
val tempHeaderFile = createTempFile(suffix = ".h")
|
val tempHeaderFile = createTempFile(suffix = ".h")
|
||||||
tempHeaderFile.deleteOnExit()
|
tempHeaderFile.deleteOnExit()
|
||||||
|
|||||||
@@ -8,8 +8,6 @@ class NativeInteropPlugin implements Plugin<Project> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
void apply(Project prj) {
|
void apply(Project prj) {
|
||||||
// TODO: handle other source sets
|
|
||||||
def srcDir = prj.file("src/main/kotlin")
|
|
||||||
def generatedSrcDir = new File(prj.buildDir, "nativeInteropStubs/kotlin")
|
def generatedSrcDir = new File(prj.buildDir, "nativeInteropStubs/kotlin")
|
||||||
def nativeLibsDir = new File(prj.buildDir, "nativelibs")
|
def nativeLibsDir = new File(prj.buildDir, "nativelibs")
|
||||||
|
|
||||||
@@ -27,18 +25,26 @@ class NativeInteropPlugin implements Plugin<Project> {
|
|||||||
prj.task(genStubsTaskName, type: JavaExec) {
|
prj.task(genStubsTaskName, type: JavaExec) {
|
||||||
classpath = prj.configurations.interopStubGenerator
|
classpath = prj.configurations.interopStubGenerator
|
||||||
main = "org.jetbrains.kotlin.native.interop.gen.jvm.MainKt"
|
main = "org.jetbrains.kotlin.native.interop.gen.jvm.MainKt"
|
||||||
args = [srcDir, generatedSrcDir, nativeLibsDir]
|
args = [generatedSrcDir, nativeLibsDir]
|
||||||
systemProperties "java.library.path" : new File(prj.findProject(":Interop:Indexer").buildDir, "nativelibs")
|
systemProperties "java.library.path" : new File(prj.findProject(":Interop:Indexer").buildDir, "nativelibs")
|
||||||
systemProperties "llvmInstallPath" : prj.llvmInstallPath
|
systemProperties "llvmInstallPath" : prj.llvmInstallPath
|
||||||
environment "LIBCLANG_DISABLE_CRASH_RECOVERY": "1"
|
environment "LIBCLANG_DISABLE_CRASH_RECOVERY": "1"
|
||||||
environment "DYLD_LIBRARY_PATH": "${prj.llvmInstallPath}/lib"
|
environment "DYLD_LIBRARY_PATH": "${prj.llvmInstallPath}/lib"
|
||||||
|
|
||||||
inputs.files prj.fileTree(srcDir.path).include('**/*.def')
|
|
||||||
|
|
||||||
outputs.dir generatedSrcDir
|
outputs.dir generatedSrcDir
|
||||||
outputs.dir nativeLibsDir
|
outputs.dir nativeLibsDir
|
||||||
}
|
}
|
||||||
|
|
||||||
|
prj.afterEvaluate {
|
||||||
|
prj.tasks.getByName(genStubsTaskName) {
|
||||||
|
// TODO: handle other source sets
|
||||||
|
prj.sourceSets.main.kotlin.srcDirs.each { srcDir ->
|
||||||
|
inputs.files prj.fileTree(srcDir.path).include('**/*.def')
|
||||||
|
args srcDir
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
prj.sourceSets {
|
prj.sourceSets {
|
||||||
main {
|
main {
|
||||||
kotlin {
|
kotlin {
|
||||||
|
|||||||
Reference in New Issue
Block a user