Library search path resolution.

This commit is contained in:
Alexander Gorshenev
2017-05-22 15:35:21 +03:00
committed by alexander-gorshenev
parent 1b30f0988b
commit 48742b7f3f
7 changed files with 112 additions and 3 deletions
@@ -101,6 +101,8 @@ class K2Native : CLICompiler<K2NativeCompilerArguments>() {
put(NATIVE_LIBRARY_FILES,
arguments.nativeLibraries.toNonNullList())
put(REPOSITORIES,
arguments.repositories.toNonNullList())
// TODO: Collect all the explicit file names into an object
// and teach the compiler to work with temporaries and -save-temps.
@@ -83,6 +83,9 @@ public class K2NativeCompilerArguments extends CommonCompilerArguments {
@Argument(value = "--print_bitcode", description = "Print llvm bitcode")
public boolean printBitCode;
@Argument(value = "-repo", shortName = "-r", valueDescription = "<path>", description = "Library search path")
public String[] repositories;
@Argument(value = "--verify_ir", description = "Verify IR")
public boolean verifyIr;
@@ -27,6 +27,10 @@ class Distribution(val config: CompilerConfiguration) {
val hostSuffix = TargetManager.host.suffix
init { if (!targetManager.crossCompile) assert(suffix == hostSuffix) }
private fun findUserHome() = File(System.getProperty("user.home")).absolutePath
val userHome = findUserHome()
val localKonanDir = "$userHome/.konan"
private fun findKonanHome(): String {
val value = System.getProperty("konan.home", "dist")
val path = File(value).absolutePath
@@ -19,12 +19,13 @@ package org.jetbrains.kotlin.backend.konan
import com.intellij.openapi.project.Project
import org.jetbrains.kotlin.backend.konan.library.KonanLibraryReader
import org.jetbrains.kotlin.backend.konan.library.SplitLibraryReader
import org.jetbrains.kotlin.backend.konan.library.KonanLibrarySearchPathResolver
import org.jetbrains.kotlin.backend.konan.util.profile
import org.jetbrains.kotlin.config.CommonConfigurationKeys
import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
import java.io.File
import org.jetbrains.kotlin.backend.konan.util.File
class KonanConfig(val project: Project, val configuration: CompilerConfiguration) {
@@ -40,14 +41,20 @@ class KonanConfig(val project: Project, val configuration: CompilerConfiguration
if (configuration.get(KonanConfigKeys.NOSTDLIB) ?: false) {
return fromCommandLine
}
return fromCommandLine + distribution.stdlib
return fromCommandLine + "stdlib"
}
private val repositories = configuration.getList(KonanConfigKeys.REPOSITORIES) ?: emptyList()
private val resolver = KonanLibrarySearchPathResolver(repositories, distribution)
private val librariesFound: List<File> by lazy {
libraryNames.map{it -> resolver.resolve(it)}
}
internal val libraries: List<KonanLibraryReader> by lazy {
val currentAbiVersion = configuration.get(KonanConfigKeys.ABI_VERSION)!!
val target = targetManager.currentName
// Here we have chosen a particular KonanLibraryReader implementation.
libraryNames.map{it -> SplitLibraryReader(it, currentAbiVersion, target)}
librariesFound.map{it -> SplitLibraryReader(it, currentAbiVersion, target)}
}
private val loadedDescriptors = loadLibMetadata()
@@ -53,6 +53,8 @@ class KonanConfigKeys {
= CompilerConfigurationKey.create("assume 'main' entry point to be provided by external libraries")
val LINKER_ARGS: CompilerConfigurationKey<List<String>>
= CompilerConfigurationKey.create("additional linker arguments")
val REPOSITORIES: CompilerConfigurationKey<List<String>>
= CompilerConfigurationKey.create("library search path repositories")
val TARGET: CompilerConfigurationKey<String?>
= CompilerConfigurationKey.create("target we compile for")
val LIST_TARGETS: CompilerConfigurationKey<Boolean>
@@ -0,0 +1,84 @@
/*
* 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.backend.konan.library
import org.jetbrains.kotlin.backend.konan.Distribution
import org.jetbrains.kotlin.backend.konan.KonanProperties
import org.jetbrains.kotlin.backend.konan.util.File
interface SearchPathResolver {
val searchRoots: List<File>
fun resolve(givenPath: String): File
}
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
class KonanLibrarySearchPathResolver(repositories: List<String>,
val distribution: Distribution): SearchPathResolver {
private val properties = distribution.properties
val localHead: File
get() = File(distribution.localKonanDir).klib
val distHead: File
get() = File(distribution.klib)
val currentDirHead: File
get() = File.userDir.klib
private val repoRoots: List<File> by lazy {
repositories.map{File(it).klib}
}
// 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)
}
private fun found(candidate: File): File? {
val noSuffix = File(candidate.path.removeSuffixIfPresent(".klib"))
val withSuffix = File(candidate.path.suffixIfNot(".klib"))
if (withSuffix.exists) {
// We always returing the name without suffix here.
return noSuffix
}
if (noSuffix.exists) {
return noSuffix
}
return 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 any of the provided locations.")
}
private val File.klib
get() = File(this, "klib")
}
@@ -44,6 +44,8 @@ class File(val path: String) {
get() = javaFile.isDirectory()
val isFile
get() = javaFile.isFile()
val isAbsolute
get() = javaFile.isAbsolute()
val listFiles
get() = javaFile.listFiles()!!.toList()
@@ -58,6 +60,11 @@ class File(val path: String) {
// TODO: Consider removeing these after konanazing java.util.Properties.
fun bufferedReader() = javaFile.bufferedReader()
fun outputStream() = javaFile.outputStream()
companion object {
val userDir
get() = File(System.getProperty("user.dir"))
}
}