Allow including external binaries within klibs with -includeBinary flag.
Link such binaries in case they are javascripts on wasm32. Otherwise don't do anything useful yet.
This commit is contained in:
committed by
alexander-gorshenev
parent
c363732eb5
commit
e9720b7e13
@@ -87,6 +87,8 @@ class K2Native : CLICompiler<K2NativeCompilerArguments>() {
|
|||||||
|
|
||||||
arguments.target ?.let{ put(TARGET, it) }
|
arguments.target ?.let{ put(TARGET, it) }
|
||||||
|
|
||||||
|
put(INCLUDED_BINARY_FILES,
|
||||||
|
arguments.includeBinaries.toNonNullList())
|
||||||
put(NATIVE_LIBRARY_FILES,
|
put(NATIVE_LIBRARY_FILES,
|
||||||
arguments.nativeLibraries.toNonNullList())
|
arguments.nativeLibraries.toNonNullList())
|
||||||
put(REPOSITORIES,
|
put(REPOSITORIES,
|
||||||
|
|||||||
@@ -30,6 +30,9 @@ class K2NativeCompilerArguments : CommonCompilerArguments() {
|
|||||||
@Argument(value = "-enable_assertions", shortName = "-ea", description = "Enable runtime assertions in generated code")
|
@Argument(value = "-enable_assertions", shortName = "-ea", description = "Enable runtime assertions in generated code")
|
||||||
var enableAssertions: Boolean = false
|
var enableAssertions: Boolean = false
|
||||||
|
|
||||||
|
@Argument(value = "-includeBinary", shortName = "-ib", valueDescription = "<path>", description = "Pack external binary within the klib")
|
||||||
|
var includeBinaries: Array<String>? = null
|
||||||
|
|
||||||
@Argument(value = "-library", shortName = "-l", valueDescription = "<path>", description = "Link with the library")
|
@Argument(value = "-library", shortName = "-l", valueDescription = "<path>", description = "Link with the library")
|
||||||
var libraries: Array<String>? = null
|
var libraries: Array<String>? = null
|
||||||
|
|
||||||
@@ -39,7 +42,7 @@ class K2NativeCompilerArguments : CommonCompilerArguments() {
|
|||||||
@Argument(value = "-manifest", valueDescription = "<path>", description = "Provide a maniferst addend file")
|
@Argument(value = "-manifest", valueDescription = "<path>", description = "Provide a maniferst addend file")
|
||||||
var manifestFile: String? = null
|
var manifestFile: String? = null
|
||||||
|
|
||||||
@Argument(value = "-nativelibrary", shortName = "-nl", valueDescription = "<path>", description = "Include the native library")
|
@Argument(value = "-nativelibrary", shortName = "-nl", valueDescription = "<path>", description = "Include the native bitcode library")
|
||||||
var nativeLibraries: Array<String>? = null
|
var nativeLibraries: Array<String>? = null
|
||||||
|
|
||||||
@Argument(value = "-nomain", description = "Assume 'main' entry point to be provided by external libraries")
|
@Argument(value = "-nomain", description = "Assume 'main' entry point to be provided by external libraries")
|
||||||
|
|||||||
+3
@@ -98,6 +98,9 @@ class KonanConfig(val project: Project, val configuration: CompilerConfiguration
|
|||||||
internal val nativeLibraries: List<String> =
|
internal val nativeLibraries: List<String> =
|
||||||
configuration.getList(KonanConfigKeys.NATIVE_LIBRARY_FILES)
|
configuration.getList(KonanConfigKeys.NATIVE_LIBRARY_FILES)
|
||||||
|
|
||||||
|
internal val includeBinaries: List<String> =
|
||||||
|
configuration.getList(KonanConfigKeys.INCLUDED_BINARY_FILES)
|
||||||
|
|
||||||
fun loadLibMetadata(): List<ModuleDescriptorImpl> {
|
fun loadLibMetadata(): List<ModuleDescriptorImpl> {
|
||||||
|
|
||||||
val allMetadata = mutableListOf<ModuleDescriptorImpl>()
|
val allMetadata = mutableListOf<ModuleDescriptorImpl>()
|
||||||
|
|||||||
+2
@@ -37,6 +37,8 @@ class KonanConfigKeys {
|
|||||||
= CompilerConfigurationKey.create("enable backend phases")
|
= CompilerConfigurationKey.create("enable backend phases")
|
||||||
val ENTRY: CompilerConfigurationKey<String?>
|
val ENTRY: CompilerConfigurationKey<String?>
|
||||||
= CompilerConfigurationKey.create("fully qualified main() name")
|
= CompilerConfigurationKey.create("fully qualified main() name")
|
||||||
|
val INCLUDED_BINARY_FILES: CompilerConfigurationKey<List<String>>
|
||||||
|
= CompilerConfigurationKey.create("included binary file paths")
|
||||||
val LIBRARY_FILES: CompilerConfigurationKey<List<String>>
|
val LIBRARY_FILES: CompilerConfigurationKey<List<String>>
|
||||||
= CompilerConfigurationKey.create("library file paths")
|
= CompilerConfigurationKey.create("library file paths")
|
||||||
val LINKER_ARGS: CompilerConfigurationKey<List<String>>
|
val LINKER_ARGS: CompilerConfigurationKey<List<String>>
|
||||||
|
|||||||
+21
-2
@@ -292,7 +292,7 @@ internal class LinkStage(val context: Context) {
|
|||||||
private val entryPointSelector: List<String>
|
private val entryPointSelector: List<String>
|
||||||
get() = if (nomain) emptyList() else platform.entrySelector
|
get() = if (nomain) emptyList() else platform.entrySelector
|
||||||
|
|
||||||
private fun link(objectFiles: List<ObjectFile>, libraryProvidedLinkerFlags: List<String>): ExecutableFile? {
|
private fun link(objectFiles: List<ObjectFile>, includedBinaries: List<String>, libraryProvidedLinkerFlags: List<String>): ExecutableFile? {
|
||||||
val executable = context.config.outputFile
|
val executable = context.config.outputFile
|
||||||
|
|
||||||
val linkCommand = platform.linkCommand(objectFiles, executable, optimize, debug) +
|
val linkCommand = platform.linkCommand(objectFiles, executable, optimize, debug) +
|
||||||
@@ -313,9 +313,25 @@ internal class LinkStage(val context: Context) {
|
|||||||
runTool(*platform.dsymutilDryRunVerboseCommand(executable).toTypedArray())
|
runTool(*platform.dsymutilDryRunVerboseCommand(executable).toTypedArray())
|
||||||
runTool(*platform.dsymutilCommand(executable).toTypedArray())
|
runTool(*platform.dsymutilCommand(executable).toTypedArray())
|
||||||
}
|
}
|
||||||
|
if (platform is WasmPlatform) {
|
||||||
|
JavaScriptLinker(includedBinaries.filter{it.isJavaScript}, executable)
|
||||||
|
}
|
||||||
return executable
|
return executable
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private val String.isJavaScript
|
||||||
|
get() = this.endsWith(".js")
|
||||||
|
|
||||||
|
private fun JavaScriptLinker(jsFiles: List<String>, executable: String): String {
|
||||||
|
val linkedJavaScript = File("$executable.js")
|
||||||
|
linkedJavaScript.writeBytes(ByteArray(0));
|
||||||
|
|
||||||
|
jsFiles.forEach {
|
||||||
|
linkedJavaScript.appendBytes(File(it).readBytes())
|
||||||
|
}
|
||||||
|
return linkedJavaScript.name
|
||||||
|
}
|
||||||
|
|
||||||
private fun executeCommand(vararg command: String): Int {
|
private fun executeCommand(vararg command: String): Int {
|
||||||
|
|
||||||
context.log{""}
|
context.log{""}
|
||||||
@@ -362,6 +378,9 @@ internal class LinkStage(val context: Context) {
|
|||||||
val bitcodeFiles = listOf(emitted) +
|
val bitcodeFiles = listOf(emitted) +
|
||||||
libraries.map{it -> it.bitcodePaths}.flatten()
|
libraries.map{it -> it.bitcodePaths}.flatten()
|
||||||
|
|
||||||
|
val includedBinaries =
|
||||||
|
libraries.map{it -> it.includedPaths}.flatten()
|
||||||
|
|
||||||
val libraryProvidedLinkerFlags =
|
val libraryProvidedLinkerFlags =
|
||||||
libraries.map{it -> it.linkerOpts}.flatten()
|
libraries.map{it -> it.linkerOpts}.flatten()
|
||||||
|
|
||||||
@@ -377,7 +396,7 @@ internal class LinkStage(val context: Context) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
phaser.phase(KonanPhase.LINKER) {
|
phaser.phase(KonanPhase.LINKER) {
|
||||||
link(objectFiles, libraryProvidedLinkerFlags)
|
link(objectFiles, includedBinaries, libraryProvidedLinkerFlags)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
@@ -37,6 +37,8 @@ interface KonanLibraryLayout {
|
|||||||
get() = File(targetDir, "kotlin")
|
get() = File(targetDir, "kotlin")
|
||||||
val nativeDir
|
val nativeDir
|
||||||
get() = File(targetDir, "native")
|
get() = File(targetDir, "native")
|
||||||
|
val includedDir
|
||||||
|
get() = File(targetDir, "included")
|
||||||
val linkdataDir
|
val linkdataDir
|
||||||
get() = File(libDir, "linkdata")
|
get() = File(libDir, "linkdata")
|
||||||
val moduleHeaderFile
|
val moduleHeaderFile
|
||||||
|
|||||||
+1
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
|||||||
interface KonanLibraryReader {
|
interface KonanLibraryReader {
|
||||||
val libraryName: String
|
val libraryName: String
|
||||||
val bitcodePaths: List<String>
|
val bitcodePaths: List<String>
|
||||||
|
val includedPaths: List<String>
|
||||||
val linkerOpts: List<String>
|
val linkerOpts: List<String>
|
||||||
val escapeAnalysis: ByteArray?
|
val escapeAnalysis: ByteArray?
|
||||||
fun moduleDescriptor(specifics: LanguageVersionSettings): ModuleDescriptor
|
fun moduleDescriptor(specifics: LanguageVersionSettings): ModuleDescriptor
|
||||||
|
|||||||
+1
@@ -21,6 +21,7 @@ import llvm.LLVMModuleRef
|
|||||||
interface KonanLibraryWriter {
|
interface KonanLibraryWriter {
|
||||||
fun addLinkData(linkData: LinkData)
|
fun addLinkData(linkData: LinkData)
|
||||||
fun addNativeBitcode(library: String)
|
fun addNativeBitcode(library: String)
|
||||||
|
fun addIncludedBinary(library: String)
|
||||||
fun addKotlinBitcode(llvmModule: LLVMModuleRef)
|
fun addKotlinBitcode(llvmModule: LLVMModuleRef)
|
||||||
fun addManifestAddend(path: String)
|
fun addManifestAddend(path: String)
|
||||||
fun addEscapeAnalysis(escapeAnalysis: ByteArray)
|
fun addEscapeAnalysis(escapeAnalysis: ByteArray)
|
||||||
|
|||||||
+4
@@ -63,6 +63,10 @@ class FileExtractor(zippedLibrary: KonanLibrary): KonanLibrary by zippedLibrary
|
|||||||
extractDir(super.resourcesDir)
|
extractDir(super.resourcesDir)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override val includedDir: File by lazy {
|
||||||
|
extractDir(super.includedDir)
|
||||||
|
}
|
||||||
|
|
||||||
override val kotlinDir: File by lazy {
|
override val kotlinDir: File by lazy {
|
||||||
extractDir(super.kotlinDir)
|
extractDir(super.kotlinDir)
|
||||||
}
|
}
|
||||||
|
|||||||
+3
@@ -55,6 +55,9 @@ class LibraryReaderImpl(var libraryFile: File, val currentAbiVersion: Int, val t
|
|||||||
override val bitcodePaths: List<String>
|
override val bitcodePaths: List<String>
|
||||||
get() = (realFiles.kotlinDir.listFiles + realFiles.nativeDir.listFiles).map{it.absolutePath}
|
get() = (realFiles.kotlinDir.listFiles + realFiles.nativeDir.listFiles).map{it.absolutePath}
|
||||||
|
|
||||||
|
override val includedPaths: List<String>
|
||||||
|
get() = (realFiles.includedDir.listFiles).map{it.absolutePath}
|
||||||
|
|
||||||
override val linkerOpts: List<String>
|
override val linkerOpts: List<String>
|
||||||
get() = manifestProperties.propertyList("linkerOpts", target!!.targetSuffix)
|
get() = manifestProperties.propertyList("linkerOpts", target!!.targetSuffix)
|
||||||
|
|
||||||
|
|||||||
+10
@@ -56,6 +56,7 @@ class LibraryWriterImpl(override val libDir: File, currentAbiVersion: Int,
|
|||||||
targetDir.mkdirs()
|
targetDir.mkdirs()
|
||||||
kotlinDir.mkdirs()
|
kotlinDir.mkdirs()
|
||||||
nativeDir.mkdirs()
|
nativeDir.mkdirs()
|
||||||
|
includedDir.mkdirs()
|
||||||
resourcesDir.mkdirs()
|
resourcesDir.mkdirs()
|
||||||
manifestProperties.setProperty("abi_version", "$currentAbiVersion")
|
manifestProperties.setProperty("abi_version", "$currentAbiVersion")
|
||||||
}
|
}
|
||||||
@@ -76,6 +77,11 @@ class LibraryWriterImpl(override val libDir: File, currentAbiVersion: Int,
|
|||||||
File(library).copyTo(File(nativeDir, basename))
|
File(library).copyTo(File(nativeDir, basename))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun addIncludedBinary(library: String) {
|
||||||
|
val basename = File(library).name
|
||||||
|
File(library).copyTo(File(includedDir, basename))
|
||||||
|
}
|
||||||
|
|
||||||
override fun addManifestAddend(path: String) {
|
override fun addManifestAddend(path: String) {
|
||||||
val properties = File(path).loadProperties()
|
val properties = File(path).loadProperties()
|
||||||
manifestProperties.putAll(properties)
|
manifestProperties.putAll(properties)
|
||||||
@@ -97,6 +103,7 @@ class LibraryWriterImpl(override val libDir: File, currentAbiVersion: Int,
|
|||||||
|
|
||||||
internal fun buildLibrary(
|
internal fun buildLibrary(
|
||||||
natives: List<String>,
|
natives: List<String>,
|
||||||
|
included: List<String>,
|
||||||
linkData: LinkData,
|
linkData: LinkData,
|
||||||
abiVersion: Int,
|
abiVersion: Int,
|
||||||
target: KonanTarget,
|
target: KonanTarget,
|
||||||
@@ -113,6 +120,9 @@ internal fun buildLibrary(
|
|||||||
natives.forEach {
|
natives.forEach {
|
||||||
library.addNativeBitcode(it)
|
library.addNativeBitcode(it)
|
||||||
}
|
}
|
||||||
|
included.forEach {
|
||||||
|
library.addIncludedBinary(it)
|
||||||
|
}
|
||||||
manifest ?.let { library.addManifestAddend(it) }
|
manifest ?.let { library.addManifestAddend(it) }
|
||||||
escapeAnalysis?.let { library.addEscapeAnalysis(it) }
|
escapeAnalysis?.let { library.addEscapeAnalysis(it) }
|
||||||
|
|
||||||
|
|||||||
+1
@@ -121,6 +121,7 @@ internal fun produceOutput(context: Context) {
|
|||||||
|
|
||||||
val library = buildLibrary(
|
val library = buildLibrary(
|
||||||
context.config.nativeLibraries,
|
context.config.nativeLibraries,
|
||||||
|
context.config.includeBinaries,
|
||||||
context.serializedLinkData!!,
|
context.serializedLinkData!!,
|
||||||
abiVersion,
|
abiVersion,
|
||||||
target,
|
target,
|
||||||
|
|||||||
Reference in New Issue
Block a user