Provided library versioning in klib. (#2038)

* Provided library versioning in klib.
* A test for library mismatch messages.
This commit is contained in:
alexander-gorshenev
2018-09-13 02:10:34 +03:00
committed by Dmitriy Dolovov
parent d406b1b16d
commit 27ce3b194d
37 changed files with 454 additions and 264 deletions
@@ -24,10 +24,11 @@ import org.jetbrains.kotlin.cli.jvm.plugins.PluginCliParser
import org.jetbrains.kotlin.config.CommonConfigurationKeys
import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.config.Services
import org.jetbrains.kotlin.konan.KonanAbiVersion
import org.jetbrains.kotlin.konan.KonanVersion
import org.jetbrains.kotlin.konan.file.File
import org.jetbrains.kotlin.konan.target.CompilerOutputKind
import org.jetbrains.kotlin.konan.util.profile
import org.jetbrains.kotlin.konan.util.*
import org.jetbrains.kotlin.metadata.deserialization.BinaryVersion
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.utils.KotlinPaths
@@ -142,7 +143,7 @@ class K2Native : CLICompiler<K2NativeCompilerArguments>() {
val outputKind = CompilerOutputKind.valueOf(
(arguments.produce ?: "program").toUpperCase())
put(PRODUCE, outputKind)
put(ABI_VERSION, 1)
arguments.libraryVersion ?. let { put(LIBRARY_VERSION, it) }
arguments.mainPackage ?.let{ put(ENTRY, it) }
arguments.manifestFile ?.let{ put(MANIFEST_FILE, it) }
@@ -30,6 +30,9 @@ class K2NativeCompilerArguments : CommonCompilerArguments() {
@Argument(value = "-library", shortName = "-l", valueDescription = "<path>", description = "Link with the library")
var libraries: Array<String>? = null
@Argument(value = "-library-version", shortName = "-lv", valueDescription = "<version>", description = "Set library version")
var libraryVersion: String? = null
@Argument(value = "-list-targets", deprecatedName = "-list_targets", description = "List available hardware targets")
var listTargets: Boolean = false
@@ -8,6 +8,9 @@ import llvm.LLVMLinkModules2
import llvm.LLVMWriteBitcodeToFile
import org.jetbrains.kotlin.backend.konan.library.impl.buildLibrary
import org.jetbrains.kotlin.backend.konan.llvm.parseBitcodeFile
import org.jetbrains.kotlin.konan.KonanAbiVersion
import org.jetbrains.kotlin.konan.KonanVersion
import org.jetbrains.kotlin.konan.library.KonanLibraryVersioning
import org.jetbrains.kotlin.konan.target.CompilerOutputKind
val CompilerOutputKind.isNativeBinary: Boolean get() = when (this) {
@@ -62,17 +65,21 @@ internal fun produceOutput(context: Context, phaser: PhaseManager) {
val libraryName = context.config.moduleId
val neededLibraries
= context.llvm.librariesForLibraryManifest
val abiVersion = context.config.currentAbiVersion
val abiVersion = KonanAbiVersion.CURRENT
val compilerVersion = KonanVersion.CURRENT
val libraryVersion = config.get(KonanConfigKeys.LIBRARY_VERSION)
val versions = KonanLibraryVersioning(abiVersion = abiVersion, libraryVersion = libraryVersion, compilerVersion = compilerVersion)
val target = context.config.target
val nopack = config.getBoolean(KonanConfigKeys.NOPACK)
val manifestProperties = context.config.manifestProperties
val library = buildLibrary(
context.config.nativeLibraries,
context.config.includeBinaries,
neededLibraries,
context.serializedLinkData!!,
abiVersion,
context.serializedLinkData!!,
versions,
target,
output,
libraryName,
@@ -20,11 +20,11 @@ import org.jetbrains.kotlin.konan.library.defaultResolver
import org.jetbrains.kotlin.konan.library.libraryResolver
import org.jetbrains.kotlin.konan.properties.loadProperties
import org.jetbrains.kotlin.konan.target.*
import org.jetbrains.kotlin.konan.KonanAbiVersion
import org.jetbrains.kotlin.konan.library.toUnresolvedLibraries
class KonanConfig(val project: Project, val configuration: CompilerConfiguration) {
val currentAbiVersion: Int = configuration.get(KonanConfigKeys.ABI_VERSION)!!
internal val distribution = Distribution(
false,
null,
@@ -71,15 +71,18 @@ class KonanConfig(val project: Project, val configuration: CompilerConfiguration
private val libraryNames: List<String>
get() = configuration.getList(KonanConfigKeys.LIBRARY_FILES)
private val unresolvedLibraries = libraryNames.toUnresolvedLibraries
private val repositories = configuration.getList(KonanConfigKeys.REPOSITORIES)
private val resolver = defaultResolver(repositories, target, distribution).libraryResolver(currentAbiVersion)
private fun resolverLogger(msg: String) = configuration.report(STRONG_WARNING, msg)
private val resolver = defaultResolver(repositories, target, distribution, ::resolverLogger).libraryResolver()
internal val resolvedLibraries by lazy {
resolver.resolveWithDependencies(
libraryNames,
unresolvedLibraries,
noStdLib = configuration.getBoolean(KonanConfigKeys.NOSTDLIB),
noDefaultLibs = configuration.getBoolean(KonanConfigKeys.NODEFAULTLIBS) ) { msg ->
configuration.report(STRONG_WARNING, msg) }
noDefaultLibs = configuration.getBoolean(KonanConfigKeys.NODEFAULTLIBS) )
}
fun librariesWithDependencies(moduleDescriptor: ModuleDescriptor?): List<KonanLibrary> {
@@ -114,3 +117,4 @@ class KonanConfig(val project: Project, val configuration: CompilerConfiguration
fun CompilerConfiguration.report(priority: CompilerMessageSeverity, message: String)
= this.getNotNull(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY).report(priority, message)
@@ -12,8 +12,6 @@ import org.jetbrains.kotlin.konan.target.CompilerOutputKind
class KonanConfigKeys {
companion object {
// Keep the list lexically sorted.
val ABI_VERSION: CompilerConfigurationKey<Int>
= CompilerConfigurationKey.create("current abi version")
val CHECK_DEPENDENCIES: CompilerConfigurationKey<Boolean>
= CompilerConfigurationKey.create("check dependencies and download the missing ones")
val DEBUG: CompilerConfigurationKey<Boolean>
@@ -26,12 +24,16 @@ class KonanConfigKeys {
= CompilerConfigurationKey.create("enable backend phases")
val ENTRY: CompilerConfigurationKey<String?>
= CompilerConfigurationKey.create("fully qualified main() name")
val FRIEND_MODULES: CompilerConfigurationKey<List<String>>
= CompilerConfigurationKey.create<List<String>>("friend module paths")
val GENERATE_TEST_RUNNER: CompilerConfigurationKey<Boolean>
= CompilerConfigurationKey.create("generate test runner")
val INCLUDED_BINARY_FILES: CompilerConfigurationKey<List<String>>
= CompilerConfigurationKey.create("included binary file paths")
val LIBRARY_FILES: CompilerConfigurationKey<List<String>>
= CompilerConfigurationKey.create("library file paths")
val LIBRARY_VERSION: CompilerConfigurationKey<String?>
= CompilerConfigurationKey.create("library version")
val LINKER_ARGS: CompilerConfigurationKey<List<String>>
= CompilerConfigurationKey.create("additional linker arguments")
val LIST_PHASES: CompilerConfigurationKey<Boolean>
@@ -94,8 +96,6 @@ class KonanConfigKeys {
= CompilerConfigurationKey.create("verify ir")
val VERBOSE_PHASES: CompilerConfigurationKey<List<String>>
= CompilerConfigurationKey.create("verbose backend phases")
val FRIEND_MODULES: CompilerConfigurationKey<List<String>>
= CompilerConfigurationKey.create<List<String>>("friend module paths")
}
}
@@ -7,11 +7,11 @@ package org.jetbrains.kotlin.backend.konan.library
import llvm.LLVMModuleRef
import org.jetbrains.kotlin.konan.library.KonanLibrary
import java.util.*
const val KLIB_CURRENT_ABI_VERSION = 1
import org.jetbrains.kotlin.konan.library.KonanLibraryVersioning
import org.jetbrains.kotlin.konan.properties.Properties
interface KonanLibraryWriter {
val versions: KonanLibraryVersioning
fun addLinkData(linkData: LinkData)
fun addNativeBitcode(library: String)
fun addIncludedBinary(library: String)
@@ -11,10 +11,11 @@ import org.jetbrains.kotlin.backend.konan.library.KonanLibraryWriter
import org.jetbrains.kotlin.backend.konan.library.LinkData
import org.jetbrains.kotlin.konan.file.*
import org.jetbrains.kotlin.konan.library.*
import org.jetbrains.kotlin.konan.library.KLIB_FILE_EXTENSION
import org.jetbrains.kotlin.konan.properties.*
import org.jetbrains.kotlin.konan.target.KonanTarget
abstract class FileBasedLibraryWriter (val file: File, val currentAbiVersion: Int): KonanLibraryWriter
abstract class FileBasedLibraryWriter (val file: File): KonanLibraryWriter
/**
* Requires non-null [target].
@@ -22,13 +23,13 @@ abstract class FileBasedLibraryWriter (val file: File, val currentAbiVersion: In
class LibraryWriterImpl(
override val libDir: File,
moduleName: String,
currentAbiVersion: Int,
override val versions: KonanLibraryVersioning,
override val target: KonanTarget,
val nopack: Boolean = false
): FileBasedLibraryWriter(libDir, currentAbiVersion), KonanLibraryLayout {
): FileBasedLibraryWriter(libDir), KonanLibraryLayout {
constructor(path: String, moduleName: String, currentAbiVersion: Int, target: KonanTarget, nopack: Boolean):
this(File(path), moduleName, currentAbiVersion, target, nopack)
constructor(path: String, moduleName: String, versions: KonanLibraryVersioning, target: KonanTarget, nopack: Boolean):
this(File(path), moduleName, versions, target, nopack)
override val libraryName = libDir.path
val klibFile
@@ -53,7 +54,7 @@ class LibraryWriterImpl(
resourcesDir.mkdirs()
// TODO: <name>:<hash> will go somewhere around here.
manifestProperties.setProperty(KLIB_PROPERTY_UNIQUE_NAME, moduleName)
manifestProperties.setProperty(KLIB_PROPERTY_ABI_VERSION, currentAbiVersion.toString())
manifestProperties.writeKonanLibraryVersioning(versions)
}
var llvmModule: LLVMModuleRef? = null
@@ -85,6 +86,11 @@ class LibraryWriterImpl(
} else {
val newValue = libraries.joinToString(" ") { it.uniqueName }
manifestProperties.setProperty(KLIB_PROPERTY_DEPENDS, newValue)
libraries.forEach { it ->
if (it.versions.libraryVersion != null) {
manifestProperties.setProperty("${KLIB_PROPERTY_DEPENDENCY_VERSION}_${it.uniqueName}", it.versions.libraryVersion)
}
}
}
}
@@ -110,7 +116,7 @@ internal fun buildLibrary(
included: List<String>,
linkDependencies: List<KonanLibrary>,
linkData: LinkData,
abiVersion: Int,
versions: KonanLibraryVersioning,
target: KonanTarget,
output: String,
moduleName: String,
@@ -119,7 +125,7 @@ internal fun buildLibrary(
manifestProperties: Properties?,
dataFlowGraph: ByteArray?): KonanLibraryWriter {
val library = LibraryWriterImpl(output, moduleName, abiVersion, target, nopack)
val library = LibraryWriterImpl(File(output), moduleName, versions, target, nopack)
library.addKotlinBitcode(llvmModule)
library.addLinkData(linkData)
+31
View File
@@ -2892,6 +2892,37 @@ task produce_dynamic(type: DynamicKonanTest) {
"topLevel = 777 3\n"
}
task library_mismatch(type: RunStandaloneKonanTest) {
def dir = buildDir.absolutePath
def lib = "$projectDir/link/versioning/empty.kt"
def currentTarget = project.target.name
def someOtherTarget = (project.testTarget == 'wasm32' ? project.hostName : 'wasm32')
if (!useCustomDist) {
dependsOn ':wasm32CrossDistRuntime' // we actually need any target other than the current one.
}
doFirst {
def konancScript = isWindows() ? "konanc.bat" : "konanc"
def konanc = "$dist/bin/$konancScript"
"$konanc $lib -p library -o $dir/1.2/empty -target $currentTarget -lv 1.2".execute().waitFor()
"$konanc $lib -p library -o $dir/3.4/empty -target $someOtherTarget".execute().waitFor()
"$konanc $lib -p library -o $dir/5.6/empty -target $currentTarget -lv 5.6".execute().waitFor()
"$konanc $lib -p library -o $dir/7.8/empty -target $currentTarget -lv 7.8".execute().waitFor()
}
source = "link/versioning/hello.kt"
flags = ['-l', 'empty@5.6', '-r', "$dir/1.2", '-r', "$dir/3.4", '-r', "$dir/5.6"]
compilerMessages = true
def messages =
"warning: skipping $dir/1.2/empty.klib. The library versions don't match. Expected '5.6', found '1.2'\n" +
"warning: skipping $dir/3.4/empty.klib. The target doesn't match. Expected '$currentTarget', found [$someOtherTarget]\n" +
"Hello, versioned world!\n"
goldValue = isWindows() ? messages.replaceAll('\\/', '\\\\') : messages
}
if (isMac() && project.testTarget != 'wasm32') {
def target = ext.platformManager.targetByName(project.testTarget ?: 'host').name
@@ -0,0 +1,2 @@
/* This file has intentionally been left blank */
@@ -0,0 +1,3 @@
fun main(args: Array<String>) {
println("Hello, versioned world!")
}