[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.
This commit is contained in:
Sergey Bogolepov
2020-03-12 14:03:19 +07:00
committed by Sergey Bogolepov
parent e8b341e977
commit 0715fa0369
3 changed files with 32 additions and 2 deletions
@@ -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",
@@ -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()
@@ -329,14 +329,17 @@ private fun processCLib(args: Array<String>, additionalArgs: Map<String, Any> =
}
}
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<String>, additionalArgs: Map<String, Any> =
}
}
private fun compileSources(
nativeLibsDir: String,
toolConfig: ToolConfig,
cinteropArguments: CInteropArguments
): List<String> = 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<KotlinLibrary> {