From 0715fa0369a18712a8aeed79c86cbf3ef740ccac Mon Sep 17 00:00:00 2001 From: Sergey Bogolepov Date: Thu, 12 Mar 2020 14:03:19 +0700 Subject: [PATCH] [cinterop] Allow compiling auxiliary c/c++ files Add `-Xcompile-source` and `-Xsource-compile-options` flags to cinterop tools. These flags allow to compile C and C++ files into klib. --- .../native/interop/gen/jvm/CommandLine.kt | 11 ++++++++++ .../native/interop/gen/jvm/ToolConfig.kt | 2 ++ .../kotlin/native/interop/gen/jvm/main.kt | 21 +++++++++++++++++-- 3 files changed, 32 insertions(+), 2 deletions(-) diff --git a/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/jvm/CommandLine.kt b/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/jvm/CommandLine.kt index e377313b22f..5343dc62bbe 100644 --- a/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/jvm/CommandLine.kt +++ b/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/jvm/CommandLine.kt @@ -27,6 +27,7 @@ const val NOENDORSEDLIBS = "no-endorsed-libs" const val PURGE_USER_LIBS = "Xpurge-user-libs" const val TEMP_DIR = "Xtemporary-files-dir" const val NOPACK = "nopack" +const val COMPILE_SOURCES = "Xcompile-source" // TODO: unify camel and snake cases. // Possible solution is to accept both cases @@ -103,6 +104,16 @@ class CInteropArguments(argParser: ArgParser = val linkerOption = argParser.option(ArgType.String, "linker-option", description = "additional linker option").multiple() val linker by argParser.option(ArgType.String, description = "use specified linker") + + val compileSource by argParser.option(ArgType.String, + fullName = COMPILE_SOURCES, + description = "additional C/C++ sources to be compiled into resulting library" + ).multiple() + + val sourceCompileOptions by argParser.option(ArgType.String, + fullName = "Xsource-compiler-option", + description = "compiler options for sources provided via -$COMPILE_SOURCES" + ).multiple() } class JSInteropArguments(argParser: ArgParser = ArgParser("jsinterop", diff --git a/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/jvm/ToolConfig.kt b/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/jvm/ToolConfig.kt index 5a0a7b7ff4d..b9cad75e27e 100644 --- a/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/jvm/ToolConfig.kt +++ b/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/jvm/ToolConfig.kt @@ -34,6 +34,8 @@ class ToolConfig(userProvidedTargetName: String?, flavor: KotlinPlatform) { private val platform = platformManager.platform(target) + val clang = platform.clang + val substitutions = defaultTargetSubstitutions(target) fun downloadDependencies() = platform.downloadDependencies() 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 9f4876b2fc2..702a2106ef8 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 @@ -329,14 +329,17 @@ private fun processCLib(args: Array, additionalArgs: Map = } } + val compiledFiles = compileSources(nativeLibsDir, tool, cinteropArguments) + return when (stubIrOutput) { is StubIrDriver.Result.SourceCode -> { - argsToCompiler(staticLibraries, libraryPaths) + val bitcodePaths = compiledFiles.map { listOf("-native-library", it) }.flatten() + argsToCompiler(staticLibraries, libraryPaths) + bitcodePaths } is StubIrDriver.Result.Metadata -> { createInteropLibrary( metadata = stubIrOutput.metadata, - nativeBitcodeFiles = listOf(nativeOutputPath), + nativeBitcodeFiles = compiledFiles + nativeOutputPath, target = tool.target, moduleName = moduleName, outputPath = cinteropArguments.output, @@ -349,6 +352,20 @@ private fun processCLib(args: Array, additionalArgs: Map = } } +private fun compileSources( + nativeLibsDir: String, + toolConfig: ToolConfig, + cinteropArguments: CInteropArguments +): List = cinteropArguments.compileSource.mapIndexed { index, source -> + // Mangle file name to avoid collisions. + val mangledFileName = "${index}_${File(source).nameWithoutExtension}" + val outputFileName = "$nativeLibsDir/${mangledFileName}.bc" + val compilerArgs = cinteropArguments.sourceCompileOptions.toTypedArray() + val compilerCmd = toolConfig.clang.clangCXX(*compilerArgs, source, "-emit-llvm", "-c", "-o", outputFileName) + runCmd(compilerCmd.toTypedArray(), verbose = cinteropArguments.verbose) + outputFileName +} + private fun resolveDependencies( cinteropArguments: CInteropArguments, target: KonanTarget ): List {