diff --git a/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/jvm/main.kt b/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/jvm/main.kt index fa569384a44..60bf386f974 100644 --- a/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/jvm/main.kt +++ b/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/jvm/main.kt @@ -9,96 +9,101 @@ import kotlin.system.exitProcess fun main(args: Array) { val llvmInstallPath = System.getProperty("llvmInstallPath")!! - val ktSrcRoot = args[0] - val ktGenRoot = args[1] - val nativeLibsDir = args[2] + val ktGenRoot = args[0] + val nativeLibsDir = args[1] + 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 -> - val config = Properties() - defFile.bufferedReader().use { reader -> - config.load(reader) + defFiles.forEach { defFile -> + processDefFile(ktSrcRoot, defFile, ktGenRoot, nativeLibsDir, llvmInstallPath) } - - 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, compilerOpts: List): NativeIndex { val tempHeaderFile = createTempFile(suffix = ".h") tempHeaderFile.deleteOnExit() diff --git a/buildSrc/src/main/groovy/org/jetbrains/kotlin/NativeInteropPlugin.groovy b/buildSrc/src/main/groovy/org/jetbrains/kotlin/NativeInteropPlugin.groovy index 06d94e5fa6e..e191b535f29 100644 --- a/buildSrc/src/main/groovy/org/jetbrains/kotlin/NativeInteropPlugin.groovy +++ b/buildSrc/src/main/groovy/org/jetbrains/kotlin/NativeInteropPlugin.groovy @@ -8,8 +8,6 @@ class NativeInteropPlugin implements Plugin { @Override 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 nativeLibsDir = new File(prj.buildDir, "nativelibs") @@ -27,18 +25,26 @@ class NativeInteropPlugin implements Plugin { prj.task(genStubsTaskName, type: JavaExec) { classpath = prj.configurations.interopStubGenerator 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 "llvmInstallPath" : prj.llvmInstallPath environment "LIBCLANG_DISABLE_CRASH_RECOVERY": "1" environment "DYLD_LIBRARY_PATH": "${prj.llvmInstallPath}/lib" - inputs.files prj.fileTree(srcDir.path).include('**/*.def') - outputs.dir generatedSrcDir 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 { main { kotlin {