K/N: Refactor KotlinNativePluginSearchPathResolver
Get rid of dependency on KonanPaths project component
This commit is contained in:
committed by
Mikhail Glukhikh
parent
b157e9d5a1
commit
dd203830a8
@@ -1,78 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
|
||||||
* that can be found in the license/LICENSE.txt file.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.jetbrains.konan
|
|
||||||
|
|
||||||
import com.intellij.openapi.project.Project
|
|
||||||
import org.jetbrains.konan.settings.KonanPaths
|
|
||||||
import org.jetbrains.kotlin.konan.file.File
|
|
||||||
import org.jetbrains.kotlin.konan.library.*
|
|
||||||
import org.jetbrains.kotlin.konan.target.KonanTarget
|
|
||||||
|
|
||||||
class KonanPluginSearchPathResolver(val project: Project) : SearchPathResolverWithTarget {
|
|
||||||
|
|
||||||
private val paths by lazy { KonanPaths(project) }
|
|
||||||
|
|
||||||
override val searchRoots: List<File> by lazy {
|
|
||||||
paths.konanDist()?.let { distPath ->
|
|
||||||
listOf(KONAN_COMMON_LIBS_PATH, konanSpecificPlatformLibrariesPath(target.toString())).mapNotNull { relativePath ->
|
|
||||||
distPath.resolve(relativePath).File().takeIf { it.exists }
|
|
||||||
}
|
|
||||||
} ?: emptyList()
|
|
||||||
}
|
|
||||||
|
|
||||||
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 }}.")
|
|
||||||
}
|
|
||||||
|
|
||||||
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 = searchRoots.flatMap { it.listFiles }
|
|
||||||
.filterNot { it.name.removeSuffix(KLIB_FILE_EXTENSION_WITH_DOT) == KONAN_STDLIB_NAME }
|
|
||||||
.map { File(it.absolutePath) }
|
|
||||||
result.addAll(defaultLibs)
|
|
||||||
}
|
|
||||||
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
override val target: KonanTarget
|
|
||||||
get() = paths.target()
|
|
||||||
|
|
||||||
private fun found(candidate: File): File? {
|
|
||||||
|
|
||||||
fun check(file: File): Boolean =
|
|
||||||
file.exists && (file.isFile || File(file, "manifest").exists)
|
|
||||||
|
|
||||||
val noSuffix = File(candidate.path.removeSuffix(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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun String.suffixIfNot(suffix: String) = if (this.endsWith(suffix)) this else "$this$suffix"
|
|
||||||
@@ -9,6 +9,7 @@ import com.intellij.openapi.fileTypes.FileType
|
|||||||
import com.intellij.openapi.fileTypes.FileTypeConsumer
|
import com.intellij.openapi.fileTypes.FileTypeConsumer
|
||||||
import com.intellij.openapi.fileTypes.FileTypeFactory
|
import com.intellij.openapi.fileTypes.FileTypeFactory
|
||||||
import com.intellij.openapi.vfs.VirtualFile
|
import com.intellij.openapi.vfs.VirtualFile
|
||||||
|
import org.jetbrains.kotlin.konan.library.KLIB_METADATA_FILE_EXTENSION
|
||||||
import org.jetbrains.kotlin.metadata.deserialization.BinaryVersion
|
import org.jetbrains.kotlin.metadata.deserialization.BinaryVersion
|
||||||
import org.jetbrains.kotlin.resolve.konan.platform.KonanPlatform
|
import org.jetbrains.kotlin.resolve.konan.platform.KonanPlatform
|
||||||
import org.jetbrains.kotlin.serialization.konan.KonanSerializerProtocol
|
import org.jetbrains.kotlin.serialization.konan.KonanSerializerProtocol
|
||||||
@@ -40,7 +41,7 @@ class KonanMetadataVersion(vararg numbers: Int) : BinaryVersion(*numbers) {
|
|||||||
object KonanMetaFileType : FileType {
|
object KonanMetaFileType : FileType {
|
||||||
override fun getName() = "KNM"
|
override fun getName() = "KNM"
|
||||||
override fun getDescription() = "Kotlin/Native Metadata"
|
override fun getDescription() = "Kotlin/Native Metadata"
|
||||||
override fun getDefaultExtension() = "knm"
|
override fun getDefaultExtension() = KLIB_METADATA_FILE_EXTENSION
|
||||||
override fun getIcon() = null
|
override fun getIcon() = null
|
||||||
override fun isBinary() = true
|
override fun isBinary() = true
|
||||||
override fun isReadOnly() = true
|
override fun isReadOnly() = true
|
||||||
|
|||||||
+72
@@ -0,0 +1,72 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||||
|
* that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.ide.konan
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.konan.file.File
|
||||||
|
import org.jetbrains.kotlin.konan.library.*
|
||||||
|
import org.jetbrains.kotlin.konan.target.HostManager
|
||||||
|
import org.jetbrains.kotlin.konan.target.KonanTarget
|
||||||
|
import org.jetbrains.kotlin.konan.target.PredefinedKonanTargets
|
||||||
|
import java.nio.file.Path
|
||||||
|
import java.nio.file.Paths
|
||||||
|
|
||||||
|
internal class KotlinNativePluginSearchPathResolver(bundledLibraryPaths: Iterable<String>) : SearchPathResolverWithTarget {
|
||||||
|
|
||||||
|
override val target: KonanTarget
|
||||||
|
override val searchRoots: List<File>
|
||||||
|
|
||||||
|
init {
|
||||||
|
val commonLibsRoot = bundledLibraryPaths.firstParentPath { it.endsWith(KONAN_COMMON_LIBS_PATH) }
|
||||||
|
val platformLibsRoot = bundledLibraryPaths.firstParentPath { it.parent.endsWith(KONAN_ALL_PLATFORM_LIBS_PATH) }
|
||||||
|
val platformName = platformLibsRoot?.fileName?.toString()
|
||||||
|
|
||||||
|
target = if (platformName != null) {
|
||||||
|
PredefinedKonanTargets.getByName(platformName) ?: error("Unexpected Kotlin/Native target platform name: $platformName")
|
||||||
|
} else {
|
||||||
|
// If not possible to determine platform by platform libs root, then fallback to the host platform:
|
||||||
|
HostManager.host
|
||||||
|
}
|
||||||
|
|
||||||
|
searchRoots = listOfNotNull(commonLibsRoot, platformLibsRoot).map { File(it) }
|
||||||
|
}
|
||||||
|
|
||||||
|
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 fun found(candidate: File): File? {
|
||||||
|
|
||||||
|
fun checkAsFile(file: File): Boolean = file.isFile
|
||||||
|
|
||||||
|
fun checkAsDirectory(dir: File): Boolean =
|
||||||
|
dir.isDirectory && File(dir, "linkdata").listFilesOrEmpty.any { it.extension == KLIB_METADATA_FILE_EXTENSION }
|
||||||
|
|
||||||
|
val candidatePath = candidate.path
|
||||||
|
File(candidatePath.removeSuffix(KLIB_FILE_EXTENSION_WITH_DOT)).let { if (checkAsDirectory(it)) return it }
|
||||||
|
File(candidatePath.suffixIfNot(KLIB_FILE_EXTENSION_WITH_DOT)).let { if (checkAsFile(it)) return it }
|
||||||
|
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
// For IDEA plugin all dependencies (KLIBs) should be explicitly provided by underlying layer (Gradle plugin).
|
||||||
|
// Therefore, no default libraries.
|
||||||
|
override fun defaultLinks(noStdLib: Boolean, noDefaultLibs: Boolean) = emptyList<File>()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun Iterable<String>.firstParentPath(predicate: (Path) -> Boolean) =
|
||||||
|
asSequence().mapNotNull { Paths.get(it).parent }.firstOrNull(predicate)
|
||||||
|
|
||||||
|
private fun String.suffixIfNot(suffix: String) = if (this.endsWith(suffix)) this else "$this$suffix"
|
||||||
@@ -12,7 +12,6 @@ import com.intellij.psi.SingleRootFileViewProvider
|
|||||||
import com.intellij.psi.impl.PsiFileFactoryImpl
|
import com.intellij.psi.impl.PsiFileFactoryImpl
|
||||||
import com.intellij.psi.stubs.PsiFileStub
|
import com.intellij.psi.stubs.PsiFileStub
|
||||||
import com.intellij.testFramework.LightVirtualFile
|
import com.intellij.testFramework.LightVirtualFile
|
||||||
import org.jetbrains.konan.KonanPluginSearchPathResolver
|
|
||||||
import org.jetbrains.kotlin.analyzer.ModuleInfo
|
import org.jetbrains.kotlin.analyzer.ModuleInfo
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||||
@@ -52,17 +51,19 @@ fun ModuleInfo.createResolvedModuleDescriptors(
|
|||||||
val libraryMap =
|
val libraryMap =
|
||||||
this.dependencies().filterIsInstance<LibraryInfo>().flatMap { dependency ->
|
this.dependencies().filterIsInstance<LibraryInfo>().flatMap { dependency ->
|
||||||
if (dependency.platform == KonanPlatform) {
|
if (dependency.platform == KonanPlatform) {
|
||||||
dependency.getLibraryRoots().map { file ->
|
dependency.getLibraryRoots().map { libraryRoot ->
|
||||||
file to dependency
|
libraryRoot to dependency
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
emptyList()
|
emptyList()
|
||||||
}
|
}
|
||||||
}.toMap()
|
}.toMap()
|
||||||
|
|
||||||
val resolvedLibraries =
|
val libraryPaths = libraryMap.keys.toList()
|
||||||
KonanPluginSearchPathResolver(project).libraryResolver(KONAN_CURRENT_ABI_VERSION)
|
|
||||||
.resolveWithDependencies(libraryMap.keys.toList(), true, true)
|
val resolvedLibraries = KotlinNativePluginSearchPathResolver(libraryPaths)
|
||||||
|
.libraryResolver(KONAN_CURRENT_ABI_VERSION)
|
||||||
|
.resolveWithDependencies(libraryPaths)
|
||||||
|
|
||||||
return DefaultResolvedDescriptorsFactory.createResolved(
|
return DefaultResolvedDescriptorsFactory.createResolved(
|
||||||
resolvedLibraries,
|
resolvedLibraries,
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ package org.jetbrains.kotlin.ide.konan
|
|||||||
|
|
||||||
import com.intellij.openapi.roots.libraries.PersistentLibraryKind
|
import com.intellij.openapi.roots.libraries.PersistentLibraryKind
|
||||||
import com.intellij.openapi.vfs.VirtualFile
|
import com.intellij.openapi.vfs.VirtualFile
|
||||||
import org.jetbrains.konan.analyser.index.KonanMetaFileType
|
|
||||||
import org.jetbrains.kotlin.builtins.DefaultBuiltIns
|
import org.jetbrains.kotlin.builtins.DefaultBuiltIns
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||||
import org.jetbrains.kotlin.caches.resolve.IdePlatformKindResolution
|
import org.jetbrains.kotlin.caches.resolve.IdePlatformKindResolution
|
||||||
@@ -19,6 +18,7 @@ import org.jetbrains.kotlin.idea.caches.project.getModuleInfosFromIdeaModel
|
|||||||
import org.jetbrains.kotlin.idea.caches.resolve.PlatformAnalysisSettings
|
import org.jetbrains.kotlin.idea.caches.resolve.PlatformAnalysisSettings
|
||||||
import org.jetbrains.kotlin.konan.file.File
|
import org.jetbrains.kotlin.konan.file.File
|
||||||
import org.jetbrains.kotlin.konan.library.KLIB_FILE_EXTENSION
|
import org.jetbrains.kotlin.konan.library.KLIB_FILE_EXTENSION
|
||||||
|
import org.jetbrains.kotlin.konan.library.KLIB_METADATA_FILE_EXTENSION
|
||||||
import org.jetbrains.kotlin.konan.library.KONAN_STDLIB_NAME
|
import org.jetbrains.kotlin.konan.library.KONAN_STDLIB_NAME
|
||||||
import org.jetbrains.kotlin.konan.library.createKonanLibrary
|
import org.jetbrains.kotlin.konan.library.createKonanLibrary
|
||||||
import org.jetbrains.kotlin.konan.util.KonanFactories.DefaultDeserializedDescriptorFactory
|
import org.jetbrains.kotlin.konan.util.KonanFactories.DefaultDeserializedDescriptorFactory
|
||||||
@@ -29,7 +29,7 @@ class NativePlatformKindResolution : IdePlatformKindResolution {
|
|||||||
override fun isLibraryFileForPlatform(virtualFile: VirtualFile): Boolean {
|
override fun isLibraryFileForPlatform(virtualFile: VirtualFile): Boolean {
|
||||||
return if (virtualFile.isDirectory) {
|
return if (virtualFile.isDirectory) {
|
||||||
virtualFile.findChild("linkdata")?.takeIf { it.isDirectory }
|
virtualFile.findChild("linkdata")?.takeIf { it.isDirectory }
|
||||||
?.children?.any { it.extension == KonanMetaFileType.defaultExtension } == true
|
?.children?.any { it.extension == KLIB_METADATA_FILE_EXTENSION } == true
|
||||||
} else {
|
} else {
|
||||||
virtualFile.extension == KLIB_FILE_EXTENSION
|
virtualFile.extension == KLIB_FILE_EXTENSION
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,9 @@ import java.nio.file.Paths
|
|||||||
const val KLIB_FILE_EXTENSION = "klib"
|
const val KLIB_FILE_EXTENSION = "klib"
|
||||||
const val KLIB_FILE_EXTENSION_WITH_DOT = ".$KLIB_FILE_EXTENSION"
|
const val KLIB_FILE_EXTENSION_WITH_DOT = ".$KLIB_FILE_EXTENSION"
|
||||||
|
|
||||||
|
const val KLIB_METADATA_FILE_EXTENSION = "knm"
|
||||||
|
const val KLIB_METADATA_FILE_EXTENSION_WITH_DOT = ".$KLIB_METADATA_FILE_EXTENSION"
|
||||||
|
|
||||||
const val KONAN_STDLIB_NAME = "stdlib"
|
const val KONAN_STDLIB_NAME = "stdlib"
|
||||||
|
|
||||||
val KONAN_COMMON_LIBS_PATH: Path
|
val KONAN_COMMON_LIBS_PATH: Path
|
||||||
|
|||||||
@@ -8,15 +8,17 @@ package org.jetbrains.kotlin.konan.target
|
|||||||
import org.jetbrains.kotlin.konan.target.KonanTarget.*
|
import org.jetbrains.kotlin.konan.target.KonanTarget.*
|
||||||
import org.jetbrains.kotlin.konan.util.Named
|
import org.jetbrains.kotlin.konan.util.Named
|
||||||
|
|
||||||
enum class Family(val exeSuffix:String, val dynamicPrefix: String, val dynamicSuffix: String,
|
enum class Family(
|
||||||
val staticPrefix: String, val staticSuffix: String) {
|
val exeSuffix: String, val dynamicPrefix: String, val dynamicSuffix: String,
|
||||||
OSX ("kexe", "lib", "dylib", "lib", "a"),
|
val staticPrefix: String, val staticSuffix: String
|
||||||
IOS ("kexe", "lib", "dylib", "lib", "a"),
|
) {
|
||||||
LINUX ("kexe", "lib", "so" , "lib", "a"),
|
OSX("kexe", "lib", "dylib", "lib", "a"),
|
||||||
MINGW ("exe" , "" , "dll" , "lib", "a"),
|
IOS("kexe", "lib", "dylib", "lib", "a"),
|
||||||
ANDROID ("so" , "lib", "so" , "lib", "a"),
|
LINUX("kexe", "lib", "so", "lib", "a"),
|
||||||
WASM ("wasm", "" , "wasm" , "", "wasm"),
|
MINGW("exe", "", "dll", "lib", "a"),
|
||||||
ZEPHYR ("o" , "lib", "a" , "lib", "a")
|
ANDROID("so", "lib", "so", "lib", "a"),
|
||||||
|
WASM("wasm", "", "wasm", "", "wasm"),
|
||||||
|
ZEPHYR("o", "lib", "a", "lib", "a")
|
||||||
}
|
}
|
||||||
|
|
||||||
enum class Architecture(val bitness: Int) {
|
enum class Architecture(val bitness: Int) {
|
||||||
@@ -29,18 +31,18 @@ enum class Architecture(val bitness: Int) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
sealed class KonanTarget(override val name: String, val family: Family, val architecture: Architecture) : Named {
|
sealed class KonanTarget(override val name: String, val family: Family, val architecture: Architecture) : Named {
|
||||||
object ANDROID_ARM32 : KonanTarget( "android_arm32", Family.ANDROID, Architecture.ARM32)
|
object ANDROID_ARM32 : KonanTarget("android_arm32", Family.ANDROID, Architecture.ARM32)
|
||||||
object ANDROID_ARM64 : KonanTarget( "android_arm64", Family.ANDROID, Architecture.ARM64)
|
object ANDROID_ARM64 : KonanTarget("android_arm64", Family.ANDROID, Architecture.ARM64)
|
||||||
object IOS_ARM32 : KonanTarget( "ios_arm32", Family.IOS, Architecture.ARM32)
|
object IOS_ARM32 : KonanTarget("ios_arm32", Family.IOS, Architecture.ARM32)
|
||||||
object IOS_ARM64 : KonanTarget( "ios_arm64", Family.IOS, Architecture.ARM64)
|
object IOS_ARM64 : KonanTarget("ios_arm64", Family.IOS, Architecture.ARM64)
|
||||||
object IOS_X64 : KonanTarget( "ios_x64", Family.IOS, Architecture.X64)
|
object IOS_X64 : KonanTarget("ios_x64", Family.IOS, Architecture.X64)
|
||||||
object LINUX_X64 : KonanTarget( "linux_x64", Family.LINUX, Architecture.X64)
|
object LINUX_X64 : KonanTarget("linux_x64", Family.LINUX, Architecture.X64)
|
||||||
object MINGW_X64 : KonanTarget( "mingw_x64", Family.MINGW, Architecture.X64)
|
object MINGW_X64 : KonanTarget("mingw_x64", Family.MINGW, Architecture.X64)
|
||||||
object MACOS_X64 : KonanTarget( "macos_x64", Family.OSX, Architecture.X64)
|
object MACOS_X64 : KonanTarget("macos_x64", Family.OSX, Architecture.X64)
|
||||||
object LINUX_ARM32_HFP :KonanTarget( "linux_arm32_hfp", Family.LINUX, Architecture.ARM32)
|
object LINUX_ARM32_HFP : KonanTarget("linux_arm32_hfp", Family.LINUX, Architecture.ARM32)
|
||||||
object LINUX_MIPS32 : KonanTarget( "linux_mips32", Family.LINUX, Architecture.MIPS32)
|
object LINUX_MIPS32 : KonanTarget("linux_mips32", Family.LINUX, Architecture.MIPS32)
|
||||||
object LINUX_MIPSEL32 : KonanTarget( "linux_mipsel32", Family.LINUX, Architecture.MIPSEL32)
|
object LINUX_MIPSEL32 : KonanTarget("linux_mipsel32", Family.LINUX, Architecture.MIPSEL32)
|
||||||
object WASM32 : KonanTarget( "wasm32", Family.WASM, Architecture.WASM32)
|
object WASM32 : KonanTarget("wasm32", Family.WASM, Architecture.WASM32)
|
||||||
|
|
||||||
// Tunable targets
|
// Tunable targets
|
||||||
class ZEPHYR(val subName: String, val genericName: String = "zephyr") :
|
class ZEPHYR(val subName: String, val genericName: String = "zephyr") :
|
||||||
@@ -49,6 +51,23 @@ sealed class KonanTarget(override val name: String, val family: Family, val arch
|
|||||||
override fun toString() = name
|
override fun toString() = name
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: need a better way to enumerated predefined targets.
|
||||||
|
object PredefinedKonanTargets {
|
||||||
|
|
||||||
|
val ALL = listOf(
|
||||||
|
ANDROID_ARM32, ANDROID_ARM64,
|
||||||
|
IOS_ARM32, IOS_ARM64, IOS_X64,
|
||||||
|
LINUX_X64, LINUX_ARM32_HFP, LINUX_MIPS32, LINUX_MIPSEL32,
|
||||||
|
MINGW_X64,
|
||||||
|
MACOS_X64,
|
||||||
|
KonanTarget.WASM32
|
||||||
|
)
|
||||||
|
|
||||||
|
private val ALL_BY_NAME = ALL.associate { it.name to it }
|
||||||
|
|
||||||
|
fun getByName(name: String) = ALL_BY_NAME[name]
|
||||||
|
}
|
||||||
|
|
||||||
fun hostTargetSuffix(host: KonanTarget, target: KonanTarget) =
|
fun hostTargetSuffix(host: KonanTarget, target: KonanTarget) =
|
||||||
if (target == host) host.name else "${host.name}-${target.name}"
|
if (target == host) host.name else "${host.name}-${target.name}"
|
||||||
|
|
||||||
@@ -58,11 +77,11 @@ enum class CompilerOutputKind {
|
|||||||
},
|
},
|
||||||
DYNAMIC {
|
DYNAMIC {
|
||||||
override fun suffix(target: KonanTarget?) = ".${target!!.family.dynamicSuffix}"
|
override fun suffix(target: KonanTarget?) = ".${target!!.family.dynamicSuffix}"
|
||||||
override fun prefix(target: KonanTarget?) = "${target!!.family.dynamicPrefix}"
|
override fun prefix(target: KonanTarget?) = target!!.family.dynamicPrefix
|
||||||
},
|
},
|
||||||
STATIC {
|
STATIC {
|
||||||
override fun suffix(target: KonanTarget?) = ".${target!!.family.staticSuffix}"
|
override fun suffix(target: KonanTarget?) = ".${target!!.family.staticSuffix}"
|
||||||
override fun prefix(target: KonanTarget?) = "${target!!.family.staticPrefix}"
|
override fun prefix(target: KonanTarget?) = target!!.family.staticPrefix
|
||||||
},
|
},
|
||||||
FRAMEWORK {
|
FRAMEWORK {
|
||||||
override fun suffix(target: KonanTarget?): String = ".framework"
|
override fun suffix(target: KonanTarget?): String = ".framework"
|
||||||
@@ -80,22 +99,21 @@ enum class CompilerOutputKind {
|
|||||||
|
|
||||||
interface TargetManager {
|
interface TargetManager {
|
||||||
val target: KonanTarget
|
val target: KonanTarget
|
||||||
val targetName : String
|
val targetName: String
|
||||||
fun list() : Unit
|
fun list()
|
||||||
val hostTargetSuffix: String
|
val hostTargetSuffix: String
|
||||||
val targetSuffix: String
|
val targetSuffix: String
|
||||||
}
|
}
|
||||||
|
|
||||||
/** */
|
|
||||||
interface SubTargetProvider {
|
interface SubTargetProvider {
|
||||||
fun availableSubTarget(genericName: String): List<String>
|
fun availableSubTarget(genericName: String): List<String>
|
||||||
}
|
}
|
||||||
|
|
||||||
private class NoSubTargets: SubTargetProvider {
|
private class NoSubTargets : SubTargetProvider {
|
||||||
override fun availableSubTarget(genericName: String): List<String> = emptyList()
|
override fun availableSubTarget(genericName: String): List<String> = emptyList()
|
||||||
}
|
}
|
||||||
|
|
||||||
private class TargetManagerImpl(val userRequest: String?, val hostManager: HostManager): TargetManager {
|
private class TargetManagerImpl(val userRequest: String?, val hostManager: HostManager) : TargetManager {
|
||||||
override val target = determineCurrent()
|
override val target = determineCurrent()
|
||||||
override val targetName
|
override val targetName
|
||||||
get() = target.visibleName
|
get() = target.visibleName
|
||||||
@@ -125,24 +143,15 @@ open class HostManager(subtargetProvider: SubTargetProvider = NoSubTargets()) {
|
|||||||
|
|
||||||
fun targetManager(userRequest: String? = null): TargetManager = TargetManagerImpl(userRequest, this)
|
fun targetManager(userRequest: String? = null): TargetManager = TargetManagerImpl(userRequest, this)
|
||||||
|
|
||||||
// TODO: need a better way to enumerated predefined targets.
|
|
||||||
private val predefinedTargets = listOf(
|
|
||||||
KonanTarget.ANDROID_ARM32, ANDROID_ARM64,
|
|
||||||
IOS_ARM32, IOS_ARM64, IOS_X64,
|
|
||||||
LINUX_X64, LINUX_ARM32_HFP, LINUX_MIPS32, LINUX_MIPSEL32,
|
|
||||||
MINGW_X64,
|
|
||||||
MACOS_X64,
|
|
||||||
WASM32)
|
|
||||||
|
|
||||||
private val zephyrSubtargets = subtargetProvider.availableSubTarget("zephyr").map { ZEPHYR(it) }
|
private val zephyrSubtargets = subtargetProvider.availableSubTarget("zephyr").map { ZEPHYR(it) }
|
||||||
|
|
||||||
private val configurableSubtargets = zephyrSubtargets
|
private val configurableSubtargets = zephyrSubtargets
|
||||||
|
|
||||||
val targetValues: List<KonanTarget> by lazy {
|
val targetValues: List<KonanTarget> by lazy {
|
||||||
predefinedTargets + configurableSubtargets
|
PredefinedKonanTargets.ALL + configurableSubtargets
|
||||||
}
|
}
|
||||||
|
|
||||||
val targets = targetValues.associate{ it.visibleName to it }
|
val targets = targetValues.associate { it.visibleName to it }
|
||||||
|
|
||||||
fun toKonanTargets(names: Iterable<String>): List<KonanTarget> {
|
fun toKonanTargets(names: Iterable<String>): List<KonanTarget> {
|
||||||
return names.map {
|
return names.map {
|
||||||
@@ -160,9 +169,7 @@ open class HostManager(subtargetProvider: SubTargetProvider = NoSubTargets()) {
|
|||||||
|
|
||||||
fun targetByName(name: String): KonanTarget {
|
fun targetByName(name: String): KonanTarget {
|
||||||
if (name == "host") return host
|
if (name == "host") return host
|
||||||
val target = targets[resolveAlias(name)]
|
return targets[resolveAlias(name)] ?: throw TargetSupportException("Unknown target name: $name")
|
||||||
if (target == null) throw TargetSupportException("Unknown target name: $name")
|
|
||||||
return target
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val enabled: List<KonanTarget> by lazy {
|
val enabled: List<KonanTarget> by lazy {
|
||||||
@@ -203,7 +210,7 @@ open class HostManager(subtargetProvider: SubTargetProvider = NoSubTargets()) {
|
|||||||
javaOsName == "Mac OS X" -> "osx"
|
javaOsName == "Mac OS X" -> "osx"
|
||||||
javaOsName == "Linux" -> "linux"
|
javaOsName == "Linux" -> "linux"
|
||||||
javaOsName.startsWith("Windows") -> "windows"
|
javaOsName.startsWith("Windows") -> "windows"
|
||||||
else -> throw TargetSupportException("Unknown operating system: ${javaOsName}")
|
else -> throw TargetSupportException("Unknown operating system: $javaOsName")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -214,10 +221,10 @@ open class HostManager(subtargetProvider: SubTargetProvider = NoSubTargets()) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
val jniHostPlatformIncludeDir: String
|
val jniHostPlatformIncludeDir: String
|
||||||
get() = when(host) {
|
get() = when (host) {
|
||||||
KonanTarget.MACOS_X64 -> "darwin"
|
KonanTarget.MACOS_X64 -> "darwin"
|
||||||
KonanTarget.LINUX_X64 -> "linux"
|
KonanTarget.LINUX_X64 -> "linux"
|
||||||
KonanTarget.MINGW_X64 ->"win32"
|
KonanTarget.MINGW_X64 -> "win32"
|
||||||
else -> throw TargetSupportException("Unknown host: $host.")
|
else -> throw TargetSupportException("Unknown host: $host.")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -225,47 +232,48 @@ open class HostManager(subtargetProvider: SubTargetProvider = NoSubTargets()) {
|
|||||||
val javaArch = System.getProperty("os.arch")
|
val javaArch = System.getProperty("os.arch")
|
||||||
return when (javaArch) {
|
return when (javaArch) {
|
||||||
"x86_64" -> "x86_64"
|
"x86_64" -> "x86_64"
|
||||||
"amd64" -> "x86_64"
|
"amd64" -> "x86_64"
|
||||||
"arm64" -> "arm64"
|
"arm64" -> "arm64"
|
||||||
else -> throw TargetSupportException("Unknown hardware platform: ${javaArch}")
|
else -> throw TargetSupportException("Unknown hardware platform: $javaArch")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val host: KonanTarget = when (host_os()) {
|
val host: KonanTarget = when (host_os()) {
|
||||||
"osx" -> KonanTarget.MACOS_X64
|
"osx" -> KonanTarget.MACOS_X64
|
||||||
"linux" -> KonanTarget.LINUX_X64
|
"linux" -> KonanTarget.LINUX_X64
|
||||||
"windows" -> KonanTarget.MINGW_X64
|
"windows" -> KonanTarget.MINGW_X64
|
||||||
else -> throw TargetSupportException("Unknown host target: ${host_os()} ${host_arch()}")
|
else -> throw TargetSupportException("Unknown host target: ${host_os()} ${host_arch()}")
|
||||||
}
|
}
|
||||||
|
|
||||||
val hostIsMac = (host == KonanTarget.MACOS_X64)
|
val hostIsMac = (host == KonanTarget.MACOS_X64)
|
||||||
val hostIsLinux = (host == KonanTarget.LINUX_X64)
|
val hostIsLinux = (host == KonanTarget.LINUX_X64)
|
||||||
val hostIsMingw = (host == KonanTarget.MINGW_X64)
|
val hostIsMingw = (host == KonanTarget.MINGW_X64)
|
||||||
|
|
||||||
val hostSuffix get() = host.name
|
val hostSuffix get() = host.name
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
val hostName get() = host.name
|
val hostName
|
||||||
|
get() = host.name
|
||||||
|
|
||||||
val knownTargetTemplates = listOf("zephyr")
|
val knownTargetTemplates = listOf("zephyr")
|
||||||
|
|
||||||
private val targetAliasResolutions = mapOf(
|
private val targetAliasResolutions = mapOf(
|
||||||
"linux" to "linux_x64",
|
"linux" to "linux_x64",
|
||||||
"macbook" to "macos_x64",
|
"macbook" to "macos_x64",
|
||||||
"macos" to "macos_x64",
|
"macos" to "macos_x64",
|
||||||
"imac" to "macos_x64",
|
"imac" to "macos_x64",
|
||||||
"raspberrypi" to "linux_arm32_hfp",
|
"raspberrypi" to "linux_arm32_hfp",
|
||||||
"iphone32" to "ios_arm32",
|
"iphone32" to "ios_arm32",
|
||||||
"iphone" to "ios_arm64",
|
"iphone" to "ios_arm64",
|
||||||
"ipad" to "ios_arm64",
|
"ipad" to "ios_arm64",
|
||||||
"ios" to "ios_arm64",
|
"ios" to "ios_arm64",
|
||||||
"iphone_sim" to "ios_x64",
|
"iphone_sim" to "ios_x64",
|
||||||
"mingw" to "mingw_x64"
|
"mingw" to "mingw_x64"
|
||||||
)
|
)
|
||||||
|
|
||||||
private val targetAliases: Map<String, List<String>> by lazy {
|
private val targetAliases: Map<String, List<String>> by lazy {
|
||||||
val result = mutableMapOf<String, MutableList<String>>()
|
val result = mutableMapOf<String, MutableList<String>>()
|
||||||
targetAliasResolutions.entries.forEach {
|
targetAliasResolutions.entries.forEach {
|
||||||
result.getOrPut(it.value, { mutableListOf() } ).add(it.key)
|
result.getOrPut(it.value, { mutableListOf() }).add(it.key)
|
||||||
}
|
}
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
@@ -276,4 +284,4 @@ open class HostManager(subtargetProvider: SubTargetProvider = NoSubTargets()) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class TargetSupportException (message: String = "", cause: Throwable? = null) : Exception(message, cause)
|
class TargetSupportException(message: String = "", cause: Throwable? = null) : Exception(message, cause)
|
||||||
@@ -6,6 +6,7 @@
|
|||||||
package org.jetbrains.kotlin.konan.util
|
package org.jetbrains.kotlin.konan.util
|
||||||
|
|
||||||
val <T : Enum<T>> T.visibleName get() = name.toLowerCase()
|
val <T : Enum<T>> T.visibleName get() = name.toLowerCase()
|
||||||
|
|
||||||
interface Named {
|
interface Named {
|
||||||
val name: String
|
val name: String
|
||||||
val visibleName get() = name
|
val visibleName get() = name
|
||||||
|
|||||||
Reference in New Issue
Block a user