[libraries] Move SearchPathResolver into shared

This commit is contained in:
Ilya Matveev
2018-05-11 11:42:39 +07:00
committed by ilmat192
parent f54f7bfde2
commit 301af84358
11 changed files with 112 additions and 107 deletions
@@ -0,0 +1,99 @@
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
interface SearchPathResolver {
val searchRoots: List<File>
fun resolve(givenPath: String): File
fun defaultLinks(nostdlib: Boolean, noDefaultLibs: Boolean): List<File>
}
fun defaultResolver(repositories: List<String>, target: KonanTarget): SearchPathResolver =
defaultResolver(repositories, target, Distribution())
fun defaultResolver(repositories: List<String>, target: KonanTarget, distribution: Distribution): SearchPathResolver =
KonanLibrarySearchPathResolver(
repositories,
target,
distribution.klib,
distribution.localKonanDir.absolutePath
)
class KonanLibrarySearchPathResolver(
repositories: List<String>,
val target: KonanTarget?,
val distributionKlib: String?,
val localKonanDir: String?,
val skipCurrentDir: Boolean = false
): SearchPathResolver {
val localHead: File?
get() = localKonanDir?.File()?.klib
val distHead: File?
get() = distributionKlib?.File()?.child("common")
val distPlatformHead: File?
get() = target?.let { distributionKlib?.File()?.child("platform")?.child(target.visibleName) }
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"))
val withSuffix = File(candidate.path.suffixIfNot(".klib"))
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() = listOf(distHead, distPlatformHead)
.filterNotNull()
.filter{ it.exists }
override fun defaultLinks(nostdlib: Boolean, noDefaultLibs: Boolean): List<File> {
val defaultLibs = defaultRoots.flatMap{ it.listFiles }
.filterNot { it.name.removeSuffixIfPresent(".klib") == "stdlib" }
.map { File(it.absolutePath) }
val result = mutableListOf<File>()
if (!nostdlib) result.add(resolve("stdlib"))
if (!noDefaultLibs) result.addAll(defaultLibs)
return result
}
}
@@ -0,0 +1,56 @@
/*
* Copyright 2010-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.konan.util
import kotlin.system.measureTimeMillis
import org.jetbrains.kotlin.konan.file.*
fun printMillisec(message: String, body: () -> Unit) {
val msec = measureTimeMillis{
body()
}
println("$message: $msec msec")
}
fun profile(message: String, body: () -> Unit) = profileIf(
System.getProperty("konan.profile")?.equals("true") ?: false,
message, body)
fun profileIf(condition: Boolean, message: String, body: () -> Unit) =
if (condition) printMillisec(message, body) else body()
fun nTabs(amount: Int): String {
return String.format("%1$-${(amount+1)*4}s", "")
}
fun String.prefixIfNot(prefix: String) =
if (this.startsWith(prefix)) this else "$prefix$this"
fun String.prefixBaseNameIfNot(prefix: String): String {
val file = File(this).absoluteFile
val name = file.name
val directory = file.parent
return "$directory/${name.prefixIfNot(prefix)}"
}
fun String.suffixIfNot(suffix: String) =
if (this.endsWith(suffix)) this else "$this$suffix"
fun String.removeSuffixIfPresent(suffix: String) =
if (this.endsWith(suffix)) this.dropLast(suffix.length) else this
fun <T> Lazy<T>.getValueOrNull(): T? = if (isInitialized()) value else null