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!")
}
@@ -47,6 +47,7 @@ abstract class KonanTest extends JavaExec {
boolean enabled = true
boolean expectedFail = false
boolean run = true
boolean compilerMessages = false
void setDisabled(boolean value) {
this.enabled = !value
@@ -268,6 +269,8 @@ abstract class KonanTest extends JavaExec {
}
println "execution: $exe"
def compilerMessagesText = compilerMessages ? project.file("${program}.compilation.log").getText('UTF-8') : ""
def out = new ByteArrayOutputStream()
//TODO Add test timeout
ExecResult execResult = project.execute {
@@ -284,7 +287,7 @@ abstract class KonanTest extends JavaExec {
ignoreExitValue = true
}
def result = out.toString("UTF-8")
def result = compilerMessagesText + out.toString("UTF-8")
println(result)
@@ -0,0 +1,8 @@
package org.jetbrains.kotlin.konan.library
import org.jetbrains.kotlin.konan.library.resolver.KonanLibraryResolver
import org.jetbrains.kotlin.konan.library.resolver.impl.KonanLibraryResolverImpl
import org.jetbrains.kotlin.konan.KonanAbiVersion
fun SearchPathResolverWithTarget.libraryResolver(): KonanLibraryResolver =
KonanLibraryResolverImpl(this)
@@ -2,23 +2,20 @@ package org.jetbrains.kotlin.konan.library.resolver
import org.jetbrains.kotlin.konan.library.KonanLibrary
import org.jetbrains.kotlin.konan.library.SearchPathResolverWithTarget
typealias DuplicatedLibraryLogger = (String) -> Unit
import org.jetbrains.kotlin.konan.library.UnresolvedLibrary
interface KonanLibraryResolver {
val searchPathResolver: SearchPathResolverWithTarget
val abiVersion: Int
/**
* Given the list of Kotlin/Native library names, ABI version and other parameters
* resolves libraries and evaluates dependencies between them.
*/
fun resolveWithDependencies(
libraryNames: List<String>,
unresolvedLibraries: List<UnresolvedLibrary>,
noStdLib: Boolean = false,
noDefaultLibs: Boolean = false,
logger: DuplicatedLibraryLogger? = null
noDefaultLibs: Boolean = false
): KonanLibraryResolveResult
}
@@ -31,7 +28,6 @@ interface KonanLibraryResolveResult {
fun forEach(action: (KonanLibrary, PackageAccessedHandler) -> Unit)
}
typealias LibraryOrder = (Iterable<KonanResolvedLibrary>) -> List<KonanResolvedLibrary>
val TopologicalLibraryOrder: LibraryOrder = { input ->
@@ -1,11 +1,10 @@
package org.jetbrains.kotlin.konan.library.resolver
import org.jetbrains.kotlin.konan.library.KonanLibrary
import org.jetbrains.kotlin.name.FqName
interface PackageAccessedHandler {
fun markPackageAccessed(fqName: FqName)
fun markPackageAccessed(fqName: String)
}
/**
@@ -1,24 +1,20 @@
package org.jetbrains.kotlin.konan.library.resolver.impl
import org.jetbrains.kotlin.konan.file.File
import org.jetbrains.kotlin.konan.library.KonanLibrary
import org.jetbrains.kotlin.konan.library.SearchPathResolverWithTarget
import org.jetbrains.kotlin.konan.library.createKonanLibrary
import org.jetbrains.kotlin.konan.library.*
import org.jetbrains.kotlin.konan.library.resolver.*
import org.jetbrains.kotlin.konan.library.unresolvedDependencies
import org.jetbrains.kotlin.konan.util.WithLogger
internal class KonanLibraryResolverImpl(
override val searchPathResolver: SearchPathResolverWithTarget,
override val abiVersion: Int
): KonanLibraryResolver {
override val searchPathResolver: SearchPathResolverWithTarget
): KonanLibraryResolver, WithLogger by searchPathResolver {
override fun resolveWithDependencies(
libraryNames: List<String>,
unresolvedLibraries: List<UnresolvedLibrary>,
noStdLib: Boolean,
noDefaultLibs: Boolean,
logger: DuplicatedLibraryLogger?
) = findLibraries(libraryNames, noStdLib, noDefaultLibs)
.leaveDistinct(logger)
noDefaultLibs: Boolean
) = findLibraries(unresolvedLibraries, noStdLib, noDefaultLibs)
.leaveDistinct()
.resolveDependencies()
/**
@@ -28,19 +24,16 @@ internal class KonanLibraryResolverImpl(
* from the original library set (root set).
*/
private fun findLibraries(
libraryNames: List<String>,
unresolvedLibraries: List<UnresolvedLibrary>,
noStdLib: Boolean,
noDefaultLibs: Boolean
): List<KonanLibrary> {
val userProvidedLibraries = libraryNames.asSequence()
val userProvidedLibraries = unresolvedLibraries.asSequence()
.map { searchPathResolver.resolve(it) }
.map { createKonanLibrary(it, abiVersion, searchPathResolver.target) }
.toList()
val defaultLibraries = searchPathResolver.defaultLinks(noStdLib, noDefaultLibs).map {
createKonanLibrary(it, abiVersion, searchPathResolver.target, isDefault = true)
}
val defaultLibraries = searchPathResolver.defaultLinks(noStdLib, noDefaultLibs)
// Make sure the user provided ones appear first, so that
// they have precedence over defaults when duplicates are eliminated.
@@ -50,14 +43,13 @@ internal class KonanLibraryResolverImpl(
/**
* Leaves only distinct libraries (by absolute path), warns on duplicated paths.
*/
private fun List<KonanLibrary>.leaveDistinct(logger: DuplicatedLibraryLogger?) =
private fun List<KonanLibrary>.leaveDistinct() =
this.groupBy { it.libraryFile.absolutePath }.let { groupedByAbsolutePath ->
warnOnLibraryDuplicates(groupedByAbsolutePath.filter { it.value.size > 1 }.keys, logger)
warnOnLibraryDuplicates(groupedByAbsolutePath.filter { it.value.size > 1 }.keys)
groupedByAbsolutePath.map { it.value.first() }
}
private fun warnOnLibraryDuplicates(duplicatedPaths: Iterable<String>, logger: DuplicatedLibraryLogger? ) {
if (logger == null) return
private fun warnOnLibraryDuplicates(duplicatedPaths: Iterable<String>) {
duplicatedPaths.forEach { logger("library included more than once: $it") }
}
@@ -84,18 +76,20 @@ internal class KonanLibraryResolverImpl(
do {
newDependencies = newDependencies.map { library: KonanResolvedLibraryImpl ->
library.library.unresolvedDependencies.asSequence()
.map { searchPathResolver.resolve(it).absoluteFile }
.mapNotNull {
if (it in cache) {
library.addDependency(cache[it]!!)
.map { KonanResolvedLibraryImpl(searchPathResolver.resolve(it)) }
.map { resolved ->
val absoluteFile = resolved.library.libraryFile.absoluteFile
if (absoluteFile in cache) {
library.addDependency(cache[absoluteFile]!!)
null
} else {
val newLibrary = KonanResolvedLibraryImpl(createKonanLibrary(it, abiVersion, searchPathResolver.target))
cache[it] = newLibrary
library.addDependency(newLibrary)
newLibrary
cache.put(absoluteFile, resolved)
library.addDependency(resolved)
resolved
}
}
}.filterNotNull()
.toList()
}.flatten()
} while (newDependencies.isNotEmpty())
@@ -2,7 +2,6 @@ package org.jetbrains.kotlin.konan.library.resolver.impl
import org.jetbrains.kotlin.konan.library.KonanLibrary
import org.jetbrains.kotlin.konan.library.resolver.KonanResolvedLibrary
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.serialization.konan.parseModuleHeader
internal class KonanResolvedLibraryImpl(
@@ -23,9 +22,9 @@ internal class KonanResolvedLibraryImpl(
override val isDefault: Boolean
get() = library.isDefault
override fun markPackageAccessed(fqName: FqName) {
override fun markPackageAccessed(fqName: String) {
if (!isNeededForLink // fast path
&& !_emptyPackages.contains(fqName.asString())) {
&& !_emptyPackages.contains(fqName)) {
isNeededForLink = true
}
}
@@ -35,7 +35,7 @@ class KonanPackageFragment(
}
val proto: KonanProtoBuf.LinkDataPackageFragment
get() = protoForNames.also { packageAccessedHandler?.markPackageAccessed(fqName) }
get() = protoForNames.also { packageAccessedHandler?.markPackageAccessed(fqName.toString()) }
private val nameResolver by lazy {
NameResolverImpl(protoForNames.stringTable, protoForNames.nameTable)
@@ -41,9 +41,9 @@ internal object KonanDeserializedPackageFragmentsFactoryImpl: KonanDeserializedP
if (!library.isInterop) return emptyList()
val mainPackageFqName = library.packageFqName
val mainPackageFqName = library.packageFqName ?.let { FqName(it) }
?: error("Inconsistent manifest: interop library ${library.libraryName} should have `package` specified")
val exportForwardDeclarations = library.exportForwardDeclarations
val exportForwardDeclarations = library.exportForwardDeclarations.map { FqName(it) }
val aliasedPackageFragments = deserializedPackageFragments.filter { it.fqName == mainPackageFqName }
@@ -6,7 +6,6 @@
package org.jetbrains.kotlin.cli.klib
// TODO: Extract `library` package as a shared jar?
import org.jetbrains.kotlin.backend.konan.library.KLIB_CURRENT_ABI_VERSION
import org.jetbrains.kotlin.config.ApiVersion
import org.jetbrains.kotlin.config.LanguageVersion
import org.jetbrains.kotlin.config.LanguageVersionSettingsImpl
@@ -15,11 +14,12 @@ import org.jetbrains.kotlin.descriptors.konan.isKonanStdlib
import org.jetbrains.kotlin.konan.file.File
import org.jetbrains.kotlin.konan.library.KLIB_FILE_EXTENSION_WITH_DOT
import org.jetbrains.kotlin.konan.library.createKonanLibrary
import org.jetbrains.kotlin.konan.library.noTargetResolver
import org.jetbrains.kotlin.konan.library.unpackZippedKonanLibraryTo
import org.jetbrains.kotlin.konan.library.resolverByName
import org.jetbrains.kotlin.konan.target.Distribution
import org.jetbrains.kotlin.konan.target.PlatformManager
import org.jetbrains.kotlin.konan.util.DependencyProcessor
import org.jetbrains.kotlin.konan.KonanAbiVersion
import org.jetbrains.kotlin.konan.library.unpackZippedKonanLibraryTo
import org.jetbrains.kotlin.konan.utils.KonanFactories.DefaultDeserializedDescriptorFactory
import org.jetbrains.kotlin.metadata.konan.KonanProtoBuf
import org.jetbrains.kotlin.serialization.konan.parseModuleHeader
@@ -96,31 +96,30 @@ class Library(val name: String, val requestedRepository: String?, val target: St
val repository = requestedRepository?.File() ?: defaultRepository
fun info() {
val library = libraryInRepoOrCurrentDir(repository, name)
val reader = createKonanLibrary(library, currentAbiVersion)
val headerAbiVersion = reader.abiVersion
val moduleName = ModuleDeserializer(reader.moduleHeaderData).moduleName
val headerAbiVersion = library.versions.abiVersion
val moduleName = ModuleDeserializer(library.moduleHeaderData).moduleName
println("")
println("Resolved to: ${reader.libraryName.File().absolutePath}")
println("Resolved to: ${library.libraryName.File().absolutePath}")
println("Module name: $moduleName")
println("ABI version: $headerAbiVersion")
val targets = reader.targetList.joinToString(", ")
val targets = library.targetList.joinToString(", ")
print("Available targets: $targets\n")
}
fun install() {
Library(File(name).name.removeSuffix(KLIB_FILE_EXTENSION_WITH_DOT), requestedRepository, target).remove(true)
val klibFile = libraryInCurrentDir(name)
val newLibDir = File(repository, klibFile.name.removeSuffix(KLIB_FILE_EXTENSION_WITH_DOT))
val library = libraryInCurrentDir(name)
val newLibDir = File(repository, library.libraryFile.name.removeSuffix(KLIB_FILE_EXTENSION_WITH_DOT))
klibFile.unpackZippedKonanLibraryTo(newLibDir)
library.libraryFile.unpackZippedKonanLibraryTo(newLibDir)
}
fun remove(blind: Boolean = false) {
if (!repository.exists) error("Repository does not exist: $repository")
val libDir = try {
val library = try {
val library = libraryInRepo(repository, name)
if (blind) warn("Removing The previously installed $name from $repository.")
library
@@ -130,26 +129,26 @@ class Library(val name: String, val requestedRepository: String?, val target: St
null
}
libDir?.deleteRecursively()
library?.libraryFile?.deleteRecursively()
}
fun contents(output: Appendable = out) {
val storageManager = LockBasedStorageManager()
val library = createKonanLibrary(libraryInRepoOrCurrentDir(repository, name), currentAbiVersion)
val library = libraryInRepoOrCurrentDir(repository, name)
val versionSpec = LanguageVersionSettingsImpl(currentLanguageVersion, currentApiVersion)
val module = DefaultDeserializedDescriptorFactory.createDescriptorAndNewBuiltIns(library, versionSpec, storageManager)
val defaultModules = mutableListOf<ModuleDescriptorImpl>()
if (!module.isKonanStdlib()) {
val resolver = noTargetResolver(
val resolver = resolverByName(
emptyList(),
distributionKlib = Distribution().klib,
skipCurrentDir = true)
resolver.defaultLinks(false, true)
.mapTo(defaultModules) {
DefaultDeserializedDescriptorFactory.createDescriptor(
createKonanLibrary(it, currentAbiVersion), versionSpec, storageManager, module.builtIns)
it, versionSpec, storageManager, module.builtIns)
}
}
@@ -161,17 +160,16 @@ class Library(val name: String, val requestedRepository: String?, val target: St
}
}
const val currentAbiVersion = KLIB_CURRENT_ABI_VERSION
val currentLanguageVersion = LanguageVersion.LATEST_STABLE
val currentApiVersion = ApiVersion.LATEST_STABLE
fun libraryInRepo(repository: File, name: String) =
noTargetResolver(listOf(repository.absolutePath), skipCurrentDir = true).resolve(name)
resolverByName(listOf(repository.absolutePath), skipCurrentDir = true).resolve(name)
fun libraryInCurrentDir(name: String) = noTargetResolver(emptyList()).resolve(name)
fun libraryInCurrentDir(name: String) = resolverByName(emptyList()).resolve(name)
fun libraryInRepoOrCurrentDir(repository: File, name: String) =
noTargetResolver(listOf(repository.absolutePath)).resolve(name)
resolverByName(listOf(repository.absolutePath)).resolve(name)
fun main(args: Array<String>) {
val command = Command(args)
+1
View File
@@ -40,6 +40,7 @@ task generateCompilerVersion(type: VersionGenerator){}
sourceSets {
main.kotlin {
srcDir 'src/main/kotlin'
srcDir 'src/library/kotlin'
srcDir generateCompilerVersion.versionSourceDirectory
}
}
@@ -93,6 +93,17 @@ open class VersionGenerator: DefaultTask() {
|
| override fun toString() = versionString
|}
|fun String.parseKonanVersion(): KonanVersion {
| val (major, minor, maintenance, meta, build) =
| Regex(""${'"'}([0-9]+)\.([0-9]+)(?:\.([0-9]+))?(?:-(\p{Alpha}\p{Alnum}*))?(?:-([0-9]+))?""${'"'})
| .matchEntire(this)!!.destructured
| return KonanVersionImpl(
| MetaVersion.valueOf(meta.toUpperCase()),
| major.toInt(),
| minor.toInt(),
| maintenance.toIntOrNull() ?: 0,
| build.toIntOrNull() ?: -1)
|}
""".trimMargin()
}
versionFile.printWriter().use {
@@ -3,9 +3,11 @@ package org.jetbrains.kotlin.konan.library
import org.jetbrains.kotlin.konan.file.File
import org.jetbrains.kotlin.konan.properties.Properties
import org.jetbrains.kotlin.konan.properties.propertyList
import org.jetbrains.kotlin.name.FqName
const val KLIB_PROPERTY_ABI_VERSION = "abi_version"
const val KLIB_PROPERTY_COMPILER_VERSION = "compiler_version"
const val KLIB_PROPERTY_DEPENDENCY_VERSION = "dependency_version"
const val KLIB_PROPERTY_LIBRARY_VERSION = "library_version"
const val KLIB_PROPERTY_UNIQUE_NAME = "unique_name"
const val KLIB_PROPERTY_LINKED_OPTS = "linkerOpts"
const val KLIB_PROPERTY_DEPENDS = "depends"
@@ -27,7 +29,6 @@ interface KonanLibrary {
// Properties:
val manifestProperties: Properties
val abiVersion: String
val linkerOpts: List<String>
// Paths:
@@ -35,6 +36,7 @@ interface KonanLibrary {
val includedPaths: List<String>
val targetList: List<String>
val versions: KonanLibraryVersioning
val dataFlowGraph: ByteArray?
val moduleHeaderData: ByteArray
@@ -44,21 +46,24 @@ interface KonanLibrary {
val KonanLibrary.uniqueName
get() = manifestProperties.getProperty(KLIB_PROPERTY_UNIQUE_NAME)!!
val KonanLibrary.unresolvedDependencies: List<String>
val KonanLibrary.unresolvedDependencies: List<UnresolvedLibrary>
get() = manifestProperties.propertyList(KLIB_PROPERTY_DEPENDS)
.map {
UnresolvedLibrary(it, manifestProperties.getProperty("dependency_version_$it"))
}
val KonanLibrary.isInterop
get() = manifestProperties.getProperty(KLIB_PROPERTY_INTEROP) == "true"
val KonanLibrary.packageFqName
get() = manifestProperties.getProperty(KLIB_PROPERTY_PACKAGE)?.let { FqName(it) }
get() = manifestProperties.getProperty(KLIB_PROPERTY_PACKAGE)
val KonanLibrary.exportForwardDeclarations
get() = manifestProperties.getProperty(KLIB_PROPERTY_EXPORT_FORWARD_DECLARATIONS)
.split(' ').asSequence()
.map { it.trim() }
.filter { it.isNotEmpty() }
.map { FqName(it) }
.map { it }
.toList()
val KonanLibrary.includedHeaders
@@ -3,14 +3,14 @@ package org.jetbrains.kotlin.konan.library
import org.jetbrains.kotlin.konan.file.File
import org.jetbrains.kotlin.konan.file.file
import org.jetbrains.kotlin.konan.file.withMutableZipFileSystem
import org.jetbrains.kotlin.konan.file.withZipFileSystem
import org.jetbrains.kotlin.konan.library.impl.DefaultMetadataReaderImpl
import org.jetbrains.kotlin.konan.library.impl.KonanLibraryImpl
import org.jetbrains.kotlin.konan.library.impl.zippedKonanLibraryChecks
import org.jetbrains.kotlin.konan.library.resolver.KonanLibraryResolver
import org.jetbrains.kotlin.konan.library.resolver.impl.KonanLibraryResolverImpl
import org.jetbrains.kotlin.konan.target.KonanTarget
val KLIB_FILE_EXTENSION = "klib"
val KLIB_FILE_EXTENSION_WITH_DOT = ".$KLIB_FILE_EXTENSION"
fun File.unpackZippedKonanLibraryTo(newDir: File) {
// First, run validity checks for the given KLIB file.
@@ -29,13 +29,18 @@ fun File.unpackZippedKonanLibraryTo(newDir: File) {
check(newDir.exists) { "Could not unpack $this as $newDir." }
}
val List<String>.toUnresolvedLibraries
get() = this.map {
val version = it.substringAfterLast('@', "")
.let { if (it.isEmpty()) null else it}
val name = it.substringBeforeLast('@')
UnresolvedLibrary(name, version)
}
fun createKonanLibrary(
libraryFile: File,
currentAbiVersion: Int,
target: KonanTarget? = null,
isDefault: Boolean = false,
metadataReader: MetadataReader = DefaultMetadataReaderImpl
): KonanLibrary = KonanLibraryImpl(libraryFile, currentAbiVersion, target, isDefault, metadataReader)
fun SearchPathResolverWithTarget.libraryResolver(abiVersion: Int): KonanLibraryResolver =
KonanLibraryResolverImpl(this, abiVersion)
): KonanLibrary = KonanLibraryImpl(libraryFile, target, isDefault, metadataReader)
@@ -0,0 +1,28 @@
package org.jetbrains.kotlin.konan.library
import org.jetbrains.kotlin.konan.KonanVersion
import org.jetbrains.kotlin.konan.parseKonanVersion
import org.jetbrains.kotlin.konan.KonanAbiVersion
import org.jetbrains.kotlin.konan.properties.Properties
import org.jetbrains.kotlin.konan.parseKonanAbiVersion
data class KonanLibraryVersioning(
val libraryVersion: String?,
val compilerVersion: KonanVersion,
val abiVersion: KonanAbiVersion
)
fun Properties.writeKonanLibraryVersioning(versions: KonanLibraryVersioning) {
this.setProperty(KLIB_PROPERTY_ABI_VERSION, versions.abiVersion.toString())
versions.libraryVersion ?. let { this.setProperty(KLIB_PROPERTY_LIBRARY_VERSION, it) }
this.setProperty(KLIB_PROPERTY_COMPILER_VERSION, "${versions.compilerVersion}")
}
fun Properties.readKonanLibraryVersioning(): KonanLibraryVersioning {
val abiVersion = this.getProperty(KLIB_PROPERTY_ABI_VERSION)!!.parseKonanAbiVersion()
val libraryVersion = this.getProperty(KLIB_PROPERTY_LIBRARY_VERSION)
val compilerVersion = this.getProperty(KLIB_PROPERTY_COMPILER_VERSION)!!.parseKonanVersion()
return KonanLibraryVersioning(abiVersion = abiVersion, libraryVersion = libraryVersion, compilerVersion = compilerVersion)
}
@@ -0,0 +1,200 @@
package org.jetbrains.kotlin.konan.library
import org.jetbrains.kotlin.konan.KonanAbiVersion
import org.jetbrains.kotlin.konan.KonanVersion
import org.jetbrains.kotlin.konan.file.File
import org.jetbrains.kotlin.konan.library.impl.KonanLibraryImpl
import org.jetbrains.kotlin.konan.target.Distribution
import org.jetbrains.kotlin.konan.target.KonanTarget
import org.jetbrains.kotlin.konan.util.*
// FIXME(ddol): KLIB-REFACTORING-CLEANUP: remove the constants below:
const val KONAN_STDLIB_NAME = "stdlib"
// FIXME(ddol): KLIB-REFACTORING-CLEANUP: remove this interface!
interface SearchPathResolver : WithLogger {
val searchRoots: List<File>
fun resolutionSequence(givenPath: String): Sequence<File>
fun resolve(unresolved: UnresolvedLibrary, isDefaultLink: Boolean = false): KonanLibraryImpl
fun resolve(givenPath: String): KonanLibraryImpl
fun defaultLinks(noStdLib: Boolean, noDefaultLibs: Boolean): List<KonanLibraryImpl>
}
// FIXME(ddol): KLIB-REFACTORING-CLEANUP: remove this interface!
interface SearchPathResolverWithTarget: SearchPathResolver {
val target: KonanTarget
val knownAbiVersions: List<KonanAbiVersion>?
val knownCompilerVersions: List<KonanVersion>?
}
fun defaultResolver(
repositories: List<String>,
target: KonanTarget
): SearchPathResolverWithTarget = defaultResolver(repositories, target, Distribution())
fun defaultResolver(
repositories: List<String>,
target: KonanTarget,
distribution: Distribution,
logger: Logger = ::dummyLogger,
skipCurrentDir: Boolean = false
): SearchPathResolverWithTarget = KonanLibraryProperResolver(
repositories,
target,
listOf(KonanAbiVersion.CURRENT),
listOf(KonanVersion.CURRENT),
distribution.klib,
distribution.localKonanDir.absolutePath,
skipCurrentDir,
logger)
fun resolverByName(
repositories: List<String>,
distributionKlib: String? = null,
localKonanDir: String? = null,
skipCurrentDir: Boolean = false
): SearchPathResolver = KonanLibrarySearchPathResolver(repositories, distributionKlib, localKonanDir, skipCurrentDir)
internal open class KonanLibrarySearchPathResolver(
repositories: List<String>,
val distributionKlib: String?,
val localKonanDir: String?,
val skipCurrentDir: Boolean,
override val logger:Logger = ::dummyLogger
) : SearchPathResolver {
val localHead: File?
get() = localKonanDir?.File()?.klib
val distHead: File?
get() = distributionKlib?.File()?.child("common")
open val distPlatformHead: File? = null
val currentDirHead: File?
get() = if (!skipCurrentDir) File.userDir else null
private val repoRoots: List<File> by lazy { repositories.map { File(it) } }
// This is the place where we specify the order of library search.
override val searchRoots: List<File> by lazy {
(listOf(currentDirHead) + repoRoots + listOf(localHead, distHead, distPlatformHead)).filterNotNull()
}
private fun found(candidate: File): File? {
fun check(file: File): Boolean =
file.exists && (file.isFile || File(file, "manifest").exists)
val noSuffix = File(candidate.path.removeSuffixIfPresent(KLIB_FILE_EXTENSION_WITH_DOT))
val withSuffix = File(candidate.path.suffixIfNot(KLIB_FILE_EXTENSION_WITH_DOT))
return when {
check(withSuffix) -> withSuffix
check(noSuffix) -> noSuffix
else -> null
}
}
override fun resolutionSequence(givenPath: String): Sequence<File> {
val given = File(givenPath)
val sequence = if (given.isAbsolute) {
sequenceOf(found(given))
} else {
searchRoots.asSequence().map {
found(File(it, givenPath))
}
}
return sequence.filterNotNull()
}
override fun resolve(unresolved: UnresolvedLibrary, isDefaultLink: Boolean): KonanLibraryImpl {
val givenPath = unresolved.path
return resolutionSequence(givenPath).firstOrNull() ?. let {
createKonanLibrary(it, null, isDefaultLink) as KonanLibraryImpl
} ?: error("Could not find \"$givenPath\" in ${searchRoots.map { it.absolutePath }}.")
}
override fun resolve(givenPath: String) = resolve(UnresolvedLibrary(givenPath, null), false)
private val File.klib
get() = File(this, "klib")
// The libraries from the default root are linked automatically.
val defaultRoots: List<File>
get() = listOfNotNull(distHead, distPlatformHead).filter { it.exists }
override fun defaultLinks(noStdLib: Boolean, noDefaultLibs: Boolean): List<KonanLibraryImpl> {
val result = mutableListOf<KonanLibraryImpl>()
if (!noStdLib) {
result.add(resolve(UnresolvedLibrary(KONAN_STDLIB_NAME, null), true))
}
if (!noDefaultLibs) {
val defaultLibs = defaultRoots.flatMap { it.listFiles }
.filterNot { it.name.removeSuffixIfPresent(KLIB_FILE_EXTENSION_WITH_DOT) == KONAN_STDLIB_NAME }
.map { UnresolvedLibrary(it.absolutePath, null) }
.map {resolve(it, isDefaultLink = true) }
result.addAll(defaultLibs)
}
return result
}
}
internal class KonanLibraryProperResolver(
repositories: List<String>,
override val target: KonanTarget,
override val knownAbiVersions: List<KonanAbiVersion>?,
override val knownCompilerVersions: List<KonanVersion>?,
distributionKlib: String?,
localKonanDir: String?,
skipCurrentDir: Boolean,
override val logger: Logger = ::dummyLogger
): KonanLibrarySearchPathResolver(repositories, distributionKlib, localKonanDir, skipCurrentDir, logger), SearchPathResolverWithTarget {
override val distPlatformHead: File?
get() = distributionKlib?.File()?.child("platform")?.child(target.visibleName)
override fun resolve(unresolved: UnresolvedLibrary, isDefaultLink: Boolean): KonanLibraryImpl {
val givenPath = unresolved.path
val fileSequence = resolutionSequence(givenPath)
val matching = fileSequence.map { createKonanLibrary(it, target, isDefaultLink) as KonanLibraryImpl }
.map { it.takeIf { libraryMatch(it, unresolved) } }
.filterNotNull()
return matching.firstOrNull() ?: error("Could not find \"$givenPath\" in ${searchRoots.map { it.absolutePath }}.")
}
}
internal fun SearchPathResolverWithTarget.libraryMatch(candidate: KonanLibraryImpl, unresolved: UnresolvedLibrary): Boolean {
val resolverTarget = this.target
val candidatePath = candidate.libraryFile.absolutePath
if (resolverTarget != null && !candidate.targetList.contains(resolverTarget.visibleName)) {
logger("skipping $candidatePath. The target doesn't match. Expected '$resolverTarget', found ${candidate.targetList}")
return false
}
if (knownCompilerVersions != null &&
!knownCompilerVersions!!.contains(candidate.versions.compilerVersion)) {
logger("skipping $candidatePath. The compiler versions don't match. Expected '${knownCompilerVersions}', found '${candidate.versions.compilerVersion}'")
return false
}
if (knownAbiVersions != null &&
!knownAbiVersions!!.contains(candidate.versions.abiVersion)) {
logger("skipping $candidatePath. The abi versions don't match. Expected '${knownAbiVersions}', found '${candidate.versions.abiVersion}'")
return false
}
if (candidate.versions.libraryVersion != unresolved.libraryVersion &&
candidate.versions.libraryVersion != null &&
unresolved.libraryVersion != null) {
logger("skipping $candidatePath. The library versions don't match. Expected '${unresolved.libraryVersion}', found '${candidate.versions.libraryVersion}'")
return false
}
return true
}
@@ -0,0 +1,10 @@
package org.jetbrains.kotlin.konan.library
data class UnresolvedLibrary(
val path: String,
val libraryVersion: String?) {
fun substitutePath(newPath: String): UnresolvedLibrary {
return UnresolvedLibrary(newPath, libraryVersion)
}
}
@@ -9,9 +9,9 @@ import org.jetbrains.kotlin.konan.target.KonanTarget
import org.jetbrains.kotlin.konan.util.defaultTargetSubstitutions
import org.jetbrains.kotlin.konan.util.substitute
internal class KonanLibraryImpl(
class KonanLibraryImpl(
override val libraryFile: File,
private val currentAbiVersion: Int,
internal val target: KonanTarget?,
override val isDefault: Boolean,
private val metadataReader: MetadataReader
@@ -32,14 +32,8 @@ internal class KonanLibraryImpl(
properties
}
override val abiVersion: String
get() {
val manifestAbiVersion = manifestProperties.getProperty(KLIB_PROPERTY_ABI_VERSION)
check(currentAbiVersion.toString() == manifestAbiVersion) {
"ABI version mismatch. Compiler expects: $currentAbiVersion, the library is $manifestAbiVersion"
}
return manifestAbiVersion
}
override val versions: KonanLibraryVersioning
get() = manifestProperties.readKonanLibraryVersioning()
override val linkerOpts: List<String>
get() = manifestProperties.propertyList(KLIB_PROPERTY_LINKED_OPTS, target!!.visibleName)
@@ -0,0 +1,12 @@
package org.jetbrains.kotlin.konan
fun String.parseKonanAbiVersion(): KonanAbiVersion {
return KonanAbiVersion(this.toInt())
}
data class KonanAbiVersion(val version: Int) {
companion object {
val CURRENT = KonanAbiVersion(1)
}
override fun toString() = "$version"
}
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.konan.file
// FIXME(ddol): KLIB-REFACTORING-CLEANUP: remove the whole file!
import org.jetbrains.kotlin.konan.util.removeSuffixIfPresent
import java.io.BufferedReader
import java.io.InputStream
import java.io.InputStreamReader
@@ -38,7 +39,7 @@ data class File constructor(internal val javaPath: Path) {
val absoluteFile: File
get() = File(absolutePath)
val name: String
get() = javaPath.fileName.toString()
get() = javaPath.fileName.toString().removeSuffixIfPresent("/") // https://bugs.java.com/bugdatabase/view_bug.do?bug_id=8153248
val extension: String
get() = name.substringAfterLast('.', "")
val parent: String
@@ -1,138 +0,0 @@
package org.jetbrains.kotlin.konan.library
import org.jetbrains.kotlin.konan.file.File
import org.jetbrains.kotlin.konan.target.Distribution
import org.jetbrains.kotlin.konan.target.KonanTarget
import org.jetbrains.kotlin.konan.util.removeSuffixIfPresent
import org.jetbrains.kotlin.konan.util.suffixIfNot
// FIXME(ddol): KLIB-REFACTORING-CLEANUP: remove the constants below:
const val KLIB_FILE_EXTENSION = "klib"
const val KLIB_FILE_EXTENSION_WITH_DOT = ".$KLIB_FILE_EXTENSION"
const val KONAN_STDLIB_NAME = "stdlib"
// FIXME(ddol): KLIB-REFACTORING-CLEANUP: remove this interface!
interface SearchPathResolver {
val searchRoots: List<File>
fun resolve(givenPath: String): File
fun defaultLinks(noStdLib: Boolean, noDefaultLibs: Boolean): List<File>
}
// FIXME(ddol): KLIB-REFACTORING-CLEANUP: remove this interface!
interface SearchPathResolverWithTarget: SearchPathResolver {
val target: KonanTarget
}
fun defaultResolver(
repositories: List<String>,
target: KonanTarget
): SearchPathResolverWithTarget = defaultResolver(repositories, target, Distribution())
fun defaultResolver(
repositories: List<String>,
target: KonanTarget,
distribution: Distribution,
skipCurrentDir: Boolean = false
): SearchPathResolverWithTarget = KonanLibrarySearchPathResolverWithTarget(
repositories,
target,
distribution.klib,
distribution.localKonanDir.absolutePath,
skipCurrentDir)
fun noTargetResolver(
repositories: List<String>,
distributionKlib: String? = null,
localKonanDir: String? = null,
skipCurrentDir: Boolean = false
): SearchPathResolver = KonanLibrarySearchPathResolver(repositories, distributionKlib, localKonanDir, skipCurrentDir)
internal open class KonanLibrarySearchPathResolver(
repositories: List<String>,
val distributionKlib: String?,
val localKonanDir: String?,
val skipCurrentDir: Boolean
) : SearchPathResolver {
val localHead: File?
get() = localKonanDir?.File()?.klib
val distHead: File?
get() = distributionKlib?.File()?.child("common")
open val distPlatformHead: File? = null
val currentDirHead: File?
get() = if (!skipCurrentDir) File.userDir else null
private val repoRoots: List<File> by lazy { repositories.map { File(it) } }
// This is the place where we specify the order of library search.
override val searchRoots: List<File> by lazy {
(listOf(currentDirHead) + repoRoots + listOf(localHead, distHead, distPlatformHead)).filterNotNull()
}
private fun found(candidate: File): File? {
fun check(file: File): Boolean =
file.exists && (file.isFile || File(file, "manifest").exists)
val noSuffix = File(candidate.path.removeSuffixIfPresent(KLIB_FILE_EXTENSION_WITH_DOT))
val withSuffix = File(candidate.path.suffixIfNot(KLIB_FILE_EXTENSION_WITH_DOT))
return when {
check(withSuffix) -> withSuffix
check(noSuffix) -> noSuffix
else -> null
}
}
override fun resolve(givenPath: String): File {
val given = File(givenPath)
if (given.isAbsolute) {
found(given)?.apply { return this }
} else {
searchRoots.forEach {
found(File(it, givenPath))?.apply { return this }
}
}
error("Could not find \"$givenPath\" in ${searchRoots.map { it.absolutePath }}.")
}
private val File.klib
get() = File(this, "klib")
// The libraries from the default root are linked automatically.
val defaultRoots: List<File>
get() = listOfNotNull(distHead, distPlatformHead).filter { it.exists }
override fun defaultLinks(noStdLib: Boolean, noDefaultLibs: Boolean): List<File> {
val result = mutableListOf<File>()
if (!noStdLib) {
result.add(resolve(KONAN_STDLIB_NAME))
}
if (!noDefaultLibs) {
val defaultLibs = defaultRoots.flatMap { it.listFiles }
.filterNot { it.name.removeSuffixIfPresent(KLIB_FILE_EXTENSION_WITH_DOT) == KONAN_STDLIB_NAME }
.map { File(it.absolutePath) }
result.addAll(defaultLibs)
}
return result
}
}
internal class KonanLibrarySearchPathResolverWithTarget(
repositories: List<String>,
override val target: KonanTarget,
distributionKlib: String?,
localKonanDir: String?,
skipCurrentDir: Boolean
): KonanLibrarySearchPathResolver(repositories, distributionKlib, localKonanDir, skipCurrentDir), SearchPathResolverWithTarget {
override val distPlatformHead: File?
get() = distributionKlib?.File()?.child("platform")?.child(target.visibleName)
}
@@ -0,0 +1,10 @@
package org.jetbrains.kotlin.konan.util
typealias Logger = (String) -> Unit
interface WithLogger {
val logger: Logger
}
fun dummyLogger(message: String) {}
@@ -154,6 +154,6 @@ open class KonanLibrariesSpec(val task: KonanArtifactWithLibrariesTask, val proj
files.flatMapTo(this) { it.files }
addAll(artifactFiles)
addAll(task.platformConfiguration.files)
namedKlibs.mapTo(this) { project.file(resolver.resolve(it).absolutePath) }
namedKlibs.mapTo(this) { project.file(resolver.resolve(it).libraryFile.absolutePath) }
}
}
@@ -4,13 +4,10 @@
*/
package org.jetbrains.kotlin.cli.utilities
import org.jetbrains.kotlin.backend.konan.library.KLIB_CURRENT_ABI_VERSION
import org.jetbrains.kotlin.konan.file.File
import org.jetbrains.kotlin.konan.library.defaultResolver
import org.jetbrains.kotlin.konan.library.includedHeaders
import org.jetbrains.kotlin.konan.library.libraryResolver
import org.jetbrains.kotlin.konan.library.packageFqName
import org.jetbrains.kotlin.konan.target.PlatformManager
import org.jetbrains.kotlin.konan.KonanAbiVersion
import org.jetbrains.kotlin.konan.library.*
import org.jetbrains.kotlin.native.interop.gen.jvm.interop
import org.jetbrains.kotlin.utils.addIfNotNull
@@ -57,14 +54,14 @@ fun invokeInterop(flavor: String, args: Array<String>): Array<String> {
val manifest = File(buildDir, "manifest.properties")
val target = PlatformManager().targetManager(targetRequest).target
val resolver = defaultResolver(repos, target).libraryResolver(KLIB_CURRENT_ABI_VERSION)
val resolver = defaultResolver(repos, target).libraryResolver()
val allLibraries = resolver.resolveWithDependencies(
libraries, noStdLib = true, noDefaultLibs = noDefaultLibs
libraries.toUnresolvedLibraries, noStdLib = true, noDefaultLibs = noDefaultLibs
).getFullList()
val importArgs = allLibraries.flatMap { library ->
// TODO: handle missing properties?
library.packageFqName?.asString()?.let { packageFqName ->
library.packageFqName?.let { packageFqName ->
val headerIds = library.includedHeaders
val arg = "$packageFqName:${headerIds.joinToString(";")}"
listOf("-import", arg)