Pass linkerOpts from .def to klib manifest.
This commit is contained in:
committed by
alexander-gorshenev
parent
e2516f42e6
commit
5effdcb1d2
+22
-5
@@ -30,7 +30,6 @@ fun main(args: Array<String>) {
|
|||||||
"arch" to (System.getenv("TARGET_ARCH") ?: "x86-64"),
|
"arch" to (System.getenv("TARGET_ARCH") ?: "x86-64"),
|
||||||
"os" to (System.getenv("TARGET_OS") ?: host)
|
"os" to (System.getenv("TARGET_OS") ?: host)
|
||||||
)
|
)
|
||||||
|
|
||||||
processLib(konanHome, substitutions, parseArgs(args))
|
processLib(konanHome, substitutions, parseArgs(args))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -256,11 +255,17 @@ private fun loadProperties(file: File?, substitutions: Map<String, String>): Pro
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun parseDefFile(file: File?, substitutions: Map<String, String>): Pair<Properties, List<String>> {
|
private fun Properties.storeProperties(file: File) {
|
||||||
|
file.outputStream().use {
|
||||||
|
this.store(it, null)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun parseDefFile(file: File?, substitutions: Map<String, String>): Triple<Properties, Properties, List<String>> {
|
||||||
val properties = Properties()
|
val properties = Properties()
|
||||||
|
|
||||||
if (file == null) {
|
if (file == null) {
|
||||||
return properties to emptyList()
|
return Triple(properties, Properties(), emptyList())
|
||||||
}
|
}
|
||||||
|
|
||||||
val lines = file.readLines()
|
val lines = file.readLines()
|
||||||
@@ -281,11 +286,18 @@ private fun parseDefFile(file: File?, substitutions: Map<String, String>): Pair<
|
|||||||
|
|
||||||
val propertiesReader = StringReader(propertyLines.joinToString(System.lineSeparator()))
|
val propertiesReader = StringReader(propertyLines.joinToString(System.lineSeparator()))
|
||||||
properties.load(propertiesReader)
|
properties.load(propertiesReader)
|
||||||
|
|
||||||
|
// Pass unsubstituted copy of properties we have obtained from `.def`
|
||||||
|
// to compiler `-maniest`.
|
||||||
|
val manifestAddendProperties = properties.duplicate()
|
||||||
|
|
||||||
substitute(properties, substitutions)
|
substitute(properties, substitutions)
|
||||||
|
|
||||||
return properties to headerLines
|
return Triple(properties, manifestAddendProperties, headerLines)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun Properties.duplicate() = Properties().apply{ putAll(this@duplicate) }
|
||||||
|
|
||||||
private fun usage() {
|
private fun usage() {
|
||||||
println("""
|
println("""
|
||||||
Run interop tool with -def <def_file_for_lib>.def
|
Run interop tool with -def <def_file_for_lib>.def
|
||||||
@@ -316,13 +328,15 @@ private fun processLib(konanHome: String,
|
|||||||
val flavor = KotlinPlatform.values().single { it.name.equals(flavorName, ignoreCase = true) }
|
val flavor = KotlinPlatform.values().single { it.name.equals(flavorName, ignoreCase = true) }
|
||||||
val target = args["-target"]?.single()?.targetSuffix() ?: defaultTarget
|
val target = args["-target"]?.single()?.targetSuffix() ?: defaultTarget
|
||||||
val defFile = args["-def"]?.single()?.let { File(it) }
|
val defFile = args["-def"]?.single()?.let { File(it) }
|
||||||
|
val manifestAddend = args["-manifest"]?.single()?.let { File(it) }
|
||||||
|
|
||||||
if (defFile == null && args["-pkg"] == null) {
|
if (defFile == null && args["-pkg"] == null) {
|
||||||
usage()
|
usage()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
val (config, defHeaderLines) = parseDefFile(defFile, substitutions)
|
val (config, manifestAddendProperties, defHeaderLines)
|
||||||
|
= parseDefFile(defFile, substitutions)
|
||||||
|
|
||||||
val konanFileName = args["-properties"]?.single() ?:
|
val konanFileName = args["-properties"]?.single() ?:
|
||||||
"${konanHome}/konan/konan.properties"
|
"${konanHome}/konan/konan.properties"
|
||||||
@@ -409,6 +423,9 @@ private fun processLib(konanHome: String,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
manifestAddend?.parentFile?.mkdirs()
|
||||||
|
manifestAddend ?.let { manifestAddendProperties.storeProperties(it) }
|
||||||
|
|
||||||
val workDir = defFile?.absoluteFile?.parentFile ?: File(userDir)
|
val workDir = defFile?.absoluteFile?.parentFile ?: File(userDir)
|
||||||
|
|
||||||
if (flavor == KotlinPlatform.JVM) {
|
if (flavor == KotlinPlatform.JVM) {
|
||||||
|
|||||||
@@ -124,6 +124,7 @@ class K2Native : CLICompiler<K2NativeCompilerArguments>() {
|
|||||||
put(ABI_VERSION, 1)
|
put(ABI_VERSION, 1)
|
||||||
|
|
||||||
arguments.mainPackage ?.let{ put(ENTRY, it) }
|
arguments.mainPackage ?.let{ put(ENTRY, it) }
|
||||||
|
arguments.manifestFile ?.let{ put(MANIFEST_FILE, it) }
|
||||||
arguments.runtimeFile ?.let{ put(RUNTIME_FILE, it) }
|
arguments.runtimeFile ?.let{ put(RUNTIME_FILE, it) }
|
||||||
arguments.propertyFile ?.let{ put(PROPERTY_FILE, it) }
|
arguments.propertyFile ?.let{ put(PROPERTY_FILE, it) }
|
||||||
|
|
||||||
|
|||||||
@@ -36,6 +36,9 @@ class K2NativeCompilerArguments : CommonCompilerArguments() {
|
|||||||
@field:Argument(value = "-list_targets", description = "List available hardware targets")
|
@field:Argument(value = "-list_targets", description = "List available hardware targets")
|
||||||
@JvmField var listTargets: Boolean = false
|
@JvmField var listTargets: Boolean = false
|
||||||
|
|
||||||
|
@field:Argument(value = "-manifest", valueDescription = "<path>", description = "Provide a maniferst addend file")
|
||||||
|
@JvmField var manifestFile: String? = null
|
||||||
|
|
||||||
@field:Argument(value = "-nativelibrary", shortName = "-nl", valueDescription = "<path>", description = "Include the native library")
|
@field:Argument(value = "-nativelibrary", shortName = "-nl", valueDescription = "<path>", description = "Include the native library")
|
||||||
@JvmField var nativeLibraries: Array<String>? = null
|
@JvmField var nativeLibraries: Array<String>? = null
|
||||||
|
|
||||||
|
|||||||
+2
@@ -43,6 +43,8 @@ class KonanConfigKeys {
|
|||||||
= CompilerConfigurationKey.create("list backend phases")
|
= CompilerConfigurationKey.create("list backend phases")
|
||||||
val LIST_TARGETS: CompilerConfigurationKey<Boolean>
|
val LIST_TARGETS: CompilerConfigurationKey<Boolean>
|
||||||
= CompilerConfigurationKey.create("list available targets")
|
= CompilerConfigurationKey.create("list available targets")
|
||||||
|
val MANIFEST_FILE: CompilerConfigurationKey<String?>
|
||||||
|
= CompilerConfigurationKey.create("provide manifest addend file")
|
||||||
val META_INFO: CompilerConfigurationKey<List<String>>
|
val META_INFO: CompilerConfigurationKey<List<String>>
|
||||||
= CompilerConfigurationKey.create("generate metadata")
|
= CompilerConfigurationKey.create("generate metadata")
|
||||||
val MODULE_KIND: CompilerConfigurationKey<ModuleKind>
|
val MODULE_KIND: CompilerConfigurationKey<ModuleKind>
|
||||||
|
|||||||
+7
-3
@@ -248,13 +248,14 @@ internal class LinkStage(val context: Context) {
|
|||||||
val entryPointSelector: List<String>
|
val entryPointSelector: List<String>
|
||||||
get() = if (nomain) emptyList() else platform.entrySelector
|
get() = if (nomain) emptyList() else platform.entrySelector
|
||||||
|
|
||||||
fun link(objectFiles: List<ObjectFile>): ExecutableFile {
|
fun link(objectFiles: List<ObjectFile>, libraryProvidedLinkerFlags: List<String>): ExecutableFile {
|
||||||
val executable = context.config.outputFile
|
val executable = context.config.outputFile
|
||||||
val linkCommand = platform.linkCommand(objectFiles, executable, optimize, config.getBoolean(KonanConfigKeys.DEBUG)) +
|
val linkCommand = platform.linkCommand(objectFiles, executable, optimize, config.getBoolean(KonanConfigKeys.DEBUG)) +
|
||||||
distribution.libffi +
|
distribution.libffi +
|
||||||
asLinkerArgs(config.getNotNull(KonanConfigKeys.LINKER_ARGS)) +
|
asLinkerArgs(config.getNotNull(KonanConfigKeys.LINKER_ARGS)) +
|
||||||
entryPointSelector +
|
entryPointSelector +
|
||||||
platform.linkCommandSuffix()
|
platform.linkCommandSuffix() +
|
||||||
|
libraryProvidedLinkerFlags
|
||||||
|
|
||||||
runTool(*linkCommand.toTypedArray())
|
runTool(*linkCommand.toTypedArray())
|
||||||
if (platform is MacOSBasedPlatform && context.shouldContainDebugInfo()) {
|
if (platform is MacOSBasedPlatform && context.shouldContainDebugInfo()) {
|
||||||
@@ -312,6 +313,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 libraryProvidedLinkerFlags =
|
||||||
|
libraries.map{it -> it.linkerOpts}.flatten()
|
||||||
|
|
||||||
var objectFiles: List<String> = listOf()
|
var objectFiles: List<String> = listOf()
|
||||||
|
|
||||||
val phaser = PhaseManager(context)
|
val phaser = PhaseManager(context)
|
||||||
@@ -319,7 +323,7 @@ internal class LinkStage(val context: Context) {
|
|||||||
objectFiles = listOf( llvmLto(bitcodeFiles ) )
|
objectFiles = listOf( llvmLto(bitcodeFiles ) )
|
||||||
}
|
}
|
||||||
phaser.phase(KonanPhase.LINKER) {
|
phaser.phase(KonanPhase.LINKER) {
|
||||||
link(objectFiles)
|
link(objectFiles, libraryProvidedLinkerFlags)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+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 linkerOpts: List<String>
|
||||||
fun moduleDescriptor(specifics: LanguageVersionSettings): ModuleDescriptor
|
fun moduleDescriptor(specifics: LanguageVersionSettings): ModuleDescriptor
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
@@ -22,6 +22,7 @@ interface KonanLibraryWriter {
|
|||||||
fun addLinkData(linkData: LinkData)
|
fun addLinkData(linkData: LinkData)
|
||||||
fun addNativeBitcode(library: String)
|
fun addNativeBitcode(library: String)
|
||||||
fun addKotlinBitcode(llvmModule: LLVMModuleRef)
|
fun addKotlinBitcode(llvmModule: LLVMModuleRef)
|
||||||
|
fun addManifestAddend(path: String)
|
||||||
val mainBitcodeFileName: String
|
val mainBitcodeFileName: String
|
||||||
fun commit()
|
fun commit()
|
||||||
}
|
}
|
||||||
|
|||||||
+2
@@ -89,5 +89,7 @@ class LibraryReaderImpl(override val libDir: File, currentAbiVersion: Int,
|
|||||||
override val bitcodePaths: List<String>
|
override val bitcodePaths: List<String>
|
||||||
get() = (kotlinDir.listFiles + nativeDir.listFiles).map{it.absolutePath}
|
get() = (kotlinDir.listFiles + nativeDir.listFiles).map{it.absolutePath}
|
||||||
|
|
||||||
|
override val linkerOpts: List<String>
|
||||||
|
get() = manifestProperties.propertyList("linkerOpts", target!!.targetSuffix)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+16
-1
@@ -71,6 +71,12 @@ class LibraryWriterImpl(override val libDir: File, currentAbiVersion: Int,
|
|||||||
File(library).copyTo(File(nativeDir, basename))
|
File(library).copyTo(File(nativeDir, basename))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun addManifestAddend(path: String) {
|
||||||
|
val properties = File(path).loadProperties()
|
||||||
|
manifestProperties.putAll(properties)
|
||||||
|
println("manifest addend: ${properties.stringPropertyNames().joinToString(" ")}")
|
||||||
|
}
|
||||||
|
|
||||||
override fun commit() {
|
override fun commit() {
|
||||||
manifestProperties.saveToFile(manifestFile)
|
manifestProperties.saveToFile(manifestFile)
|
||||||
if (!nopack) {
|
if (!nopack) {
|
||||||
@@ -80,7 +86,15 @@ class LibraryWriterImpl(override val libDir: File, currentAbiVersion: Int,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun buildLibrary(natives: List<String>, linkData: LinkData, abiVersion: Int, target: KonanTarget, output: String, llvmModule: LLVMModuleRef, nopack: Boolean): KonanLibraryWriter {
|
internal fun buildLibrary(
|
||||||
|
natives: List<String>,
|
||||||
|
linkData: LinkData,
|
||||||
|
abiVersion: Int,
|
||||||
|
target: KonanTarget,
|
||||||
|
output: String,
|
||||||
|
llvmModule: LLVMModuleRef,
|
||||||
|
nopack: Boolean,
|
||||||
|
manifest: String?): KonanLibraryWriter {
|
||||||
|
|
||||||
val library = LibraryWriterImpl(output, abiVersion, target, nopack)
|
val library = LibraryWriterImpl(output, abiVersion, target, nopack)
|
||||||
|
|
||||||
@@ -89,6 +103,7 @@ internal fun buildLibrary(natives: List<String>, linkData: LinkData, abiVersion:
|
|||||||
natives.forEach {
|
natives.forEach {
|
||||||
library.addNativeBitcode(it)
|
library.addNativeBitcode(it)
|
||||||
}
|
}
|
||||||
|
manifest ?.let { library.addManifestAddend(it) }
|
||||||
|
|
||||||
library.commit()
|
library.commit()
|
||||||
return library
|
return library
|
||||||
|
|||||||
+3
-1
@@ -110,6 +110,7 @@ internal fun produceOutput(context: Context) {
|
|||||||
val abiVersion = context.config.currentAbiVersion
|
val abiVersion = context.config.currentAbiVersion
|
||||||
val target = context.config.targetManager.target
|
val target = context.config.targetManager.target
|
||||||
val nopack = config.getBoolean(KonanConfigKeys.NOPACK)
|
val nopack = config.getBoolean(KonanConfigKeys.NOPACK)
|
||||||
|
val manifest = config.get(KonanConfigKeys.MANIFEST_FILE)
|
||||||
|
|
||||||
val library = buildLibrary(
|
val library = buildLibrary(
|
||||||
context.config.nativeLibraries,
|
context.config.nativeLibraries,
|
||||||
@@ -118,7 +119,8 @@ internal fun produceOutput(context: Context) {
|
|||||||
target,
|
target,
|
||||||
libraryName,
|
libraryName,
|
||||||
llvmModule,
|
llvmModule,
|
||||||
nopack)
|
nopack,
|
||||||
|
manifest)
|
||||||
|
|
||||||
context.library = library
|
context.library = library
|
||||||
context.bitcodeFileName = library.mainBitcodeFileName
|
context.bitcodeFileName = library.mainBitcodeFileName
|
||||||
|
|||||||
+8
@@ -131,6 +131,8 @@ open class KonanCompileTask: KonanTargetableTask() {
|
|||||||
internal set
|
internal set
|
||||||
@Optional @Input var apiVersion : String? = null
|
@Optional @Input var apiVersion : String? = null
|
||||||
internal set
|
internal set
|
||||||
|
@Input var manifest : String? = null
|
||||||
|
internal set
|
||||||
|
|
||||||
@Input var dumpParameters: Boolean = false
|
@Input var dumpParameters: Boolean = false
|
||||||
// TODO: Is there a better way to rerun tasks when the compiler version changes?
|
// TODO: Is there a better way to rerun tasks when the compiler version changes?
|
||||||
@@ -150,6 +152,7 @@ open class KonanCompileTask: KonanTargetableTask() {
|
|||||||
addArgIfNotNull("-target", target)
|
addArgIfNotNull("-target", target)
|
||||||
addArgIfNotNull("-language-version", languageVersion)
|
addArgIfNotNull("-language-version", languageVersion)
|
||||||
addArgIfNotNull("-api-version", apiVersion)
|
addArgIfNotNull("-api-version", apiVersion)
|
||||||
|
addArgIfNotNull("-manifest", manifest)
|
||||||
|
|
||||||
addKey("-g", enableDebug)
|
addKey("-g", enableDebug)
|
||||||
addKey("-nostdlib", noStdLib)
|
addKey("-nostdlib", noStdLib)
|
||||||
@@ -232,6 +235,7 @@ open class KonanCompileConfig(
|
|||||||
builtBy(generateStubsTask)
|
builtBy(generateStubsTask)
|
||||||
include("**/*.bc")
|
include("**/*.bc")
|
||||||
})
|
})
|
||||||
|
generateStubsTask.manifest ?.let {manifest(it)}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun useInterops(interops: ArrayList<String>) {
|
fun useInterops(interops: ArrayList<String>) {
|
||||||
@@ -287,6 +291,10 @@ open class KonanCompileConfig(
|
|||||||
linkerOpts.addAll(args)
|
linkerOpts.addAll(args)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun manifest(arg: String) = with(compilationTask) {
|
||||||
|
manifest = arg
|
||||||
|
}
|
||||||
|
|
||||||
fun target(tgt: String) = with(compilationTask) {
|
fun target(tgt: String) = with(compilationTask) {
|
||||||
target = tgt
|
target = tgt
|
||||||
}
|
}
|
||||||
|
|||||||
+9
-3
@@ -82,6 +82,9 @@ open class KonanInteropTask: KonanTargetableTask() {
|
|||||||
@Optional @Input var linker: String? = null
|
@Optional @Input var linker: String? = null
|
||||||
internal set
|
internal set
|
||||||
|
|
||||||
|
@Optional @Input var manifest: String? = null
|
||||||
|
internal set
|
||||||
|
|
||||||
@Input var dumpParameters: Boolean = false
|
@Input var dumpParameters: Boolean = false
|
||||||
@Input val compilerOpts = mutableListOf<String>()
|
@Input val compilerOpts = mutableListOf<String>()
|
||||||
@Input val linkerOpts = mutableListOf<String>()
|
@Input val linkerOpts = mutableListOf<String>()
|
||||||
@@ -118,6 +121,7 @@ open class KonanInteropTask: KonanTargetableTask() {
|
|||||||
|
|
||||||
addArg("-generated", stubsDir.canonicalPath)
|
addArg("-generated", stubsDir.canonicalPath)
|
||||||
addArg("-natives", libsDir.canonicalPath)
|
addArg("-natives", libsDir.canonicalPath)
|
||||||
|
manifest ?.let {addArg("-manifest", it)}
|
||||||
|
|
||||||
addArgIfNotNull("-target", target)
|
addArgIfNotNull("-target", target)
|
||||||
val defFilePath = defFile?.canonicalPath ?:
|
val defFilePath = defFile?.canonicalPath ?:
|
||||||
@@ -156,14 +160,16 @@ open class KonanInteropConfig(
|
|||||||
val generateStubsTask: KonanInteropTask = project.tasks.create(
|
val generateStubsTask: KonanInteropTask = project.tasks.create(
|
||||||
"gen${name.capitalize()}InteropStubs",
|
"gen${name.capitalize()}InteropStubs",
|
||||||
KonanInteropTask::class.java
|
KonanInteropTask::class.java
|
||||||
) { it.init(name) }
|
) { it.init(name)
|
||||||
|
it.manifest = "${it.stubsDir.path}/manifest.properties"
|
||||||
// Config and task to compile *.kt stubs in a *.bc library
|
}
|
||||||
|
// Config and task to compile *.kt stubs into a library
|
||||||
internal val compileStubsConfig = KonanCompileConfig("${name}InteropStubs", project, "compile").apply {
|
internal val compileStubsConfig = KonanCompileConfig("${name}InteropStubs", project, "compile").apply {
|
||||||
compilationTask.dependsOn(generateStubsTask)
|
compilationTask.dependsOn(generateStubsTask)
|
||||||
outputDir("${project.konanInteropCompiledStubsDir}/$name")
|
outputDir("${project.konanInteropCompiledStubsDir}/$name")
|
||||||
produce("library")
|
produce("library")
|
||||||
inputFiles(project.fileTree(generateStubsTask.stubsDir).apply { builtBy(generateStubsTask) })
|
inputFiles(project.fileTree(generateStubsTask.stubsDir).apply { builtBy(generateStubsTask) })
|
||||||
|
manifest("${generateStubsTask.stubsDir.path}/manifest.properties")
|
||||||
}
|
}
|
||||||
val compileStubsTask = compileStubsConfig.compilationTask
|
val compileStubsTask = compileStubsConfig.compilationTask
|
||||||
|
|
||||||
|
|||||||
@@ -19,11 +19,13 @@ fun invokeCinterop(args: Array<String>) {
|
|||||||
val generatedDir = File(buildDir, "kotlin")
|
val generatedDir = File(buildDir, "kotlin")
|
||||||
val nativesDir = File(buildDir, "natives")
|
val nativesDir = File(buildDir, "natives")
|
||||||
val cstubsName ="cstubs"
|
val cstubsName ="cstubs"
|
||||||
|
val manifest = File(buildDir, "manifest.properties")
|
||||||
|
|
||||||
val additionalArgs = listOf<String>(
|
val additionalArgs = listOf<String>(
|
||||||
"-generated", generatedDir.path,
|
"-generated", generatedDir.path,
|
||||||
"-natives", nativesDir.path,
|
"-natives", nativesDir.path,
|
||||||
"-cstubsname", cstubsName,
|
"-cstubsname", cstubsName,
|
||||||
|
"-manifest", manifest.path,
|
||||||
"-flavor", "native")
|
"-flavor", "native")
|
||||||
|
|
||||||
val cinteropArgs = (additionalArgs + args.toList()).toTypedArray()
|
val cinteropArgs = (additionalArgs + args.toList()).toTypedArray()
|
||||||
@@ -34,7 +36,9 @@ fun invokeCinterop(args: Array<String>) {
|
|||||||
"-produce", "library",
|
"-produce", "library",
|
||||||
"-nativelibrary", File(nativesDir, "$cstubsName.bc").path,
|
"-nativelibrary", File(nativesDir, "$cstubsName.bc").path,
|
||||||
"-o", outputFileName,
|
"-o", outputFileName,
|
||||||
"-target", target)
|
"-target", target,
|
||||||
|
"-manifest", manifest.path
|
||||||
|
)
|
||||||
konancMain(konancArgs)
|
konancMain(konancArgs)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user