Added property for overriding konan distribution location

#KT-50463 Fixed

Merge-request: KT-MR-10310
Merged-by: Dmitrii Krasnov <Dmitrii.Krasnov@jetbrains.com>
This commit is contained in:
Dmitrii Krasnov
2023-07-12 12:36:51 +00:00
committed by Space Team
parent 2f7f69ed4f
commit f2816a5531
32 changed files with 174 additions and 108 deletions
@@ -48,6 +48,7 @@ fun copyK2NativeCompilerArguments(from: K2NativeCompilerArguments, to: K2NativeC
to.includeBinaries = from.includeBinaries?.copyOf()
to.includes = from.includes?.copyOf()
to.incrementalCacheDir = from.incrementalCacheDir
to.konanDataDir = from.konanDataDir
to.lazyIrForCaches = from.lazyIrForCaches
to.libraries = from.libraries?.copyOf()
to.libraryToAddToCache = from.libraryToAddToCache
@@ -469,6 +469,9 @@ class K2NativeCompilerArguments : CommonCompilerArguments() {
@Argument(value = "-Xsave-llvm-ir-directory", description = "Directory that should contain results of -Xsave-llvm-ir-after=<phase>")
var saveLlvmIrDirectory: String? = null
@Argument(value = "-Xkonan-data-dir", description = "Custom path for konan distributions location")
var konanDataDir: String? = null
override fun configureAnalysisFlags(collector: MessageCollector, languageVersion: LanguageVersion): MutableMap<AnalysisFlag<*>, Any> =
super.configureAnalysisFlags(collector, languageVersion).also {
val optInList = it[AnalysisFlags.optIn] as List<*>
@@ -44,9 +44,9 @@ private fun makeDependencyAssigner(targets: List<String>, defFiles: List<File>,
CompositeDependencyAssigner(targets.map { makeDependencyAssignerForTarget(it, defFiles, runFromDaemon) })
private fun makeDependencyAssignerForTarget(target: String, defFiles: List<File>, runFromDaemon: Boolean): SingleTargetDependencyAssigner {
val tool = prepareTool(target, KotlinPlatform.NATIVE, runFromDaemon)
val cinteropArguments = CInteropArguments()
cinteropArguments.argParser.parse(arrayOf())
val tool = prepareTool(target, KotlinPlatform.NATIVE, runFromDaemon, konanDataDir = cinteropArguments.konanDataDir)
val libraries = defFiles.parallelStream().map {
it to buildNativeLibrary(
tool,
@@ -16,10 +16,7 @@
package org.jetbrains.kotlin.native.interop.tool
import kotlinx.cli.ArgParser
import kotlinx.cli.ArgType
import kotlinx.cli.*
import org.jetbrains.kotlin.native.interop.gen.jvm.GenerationMode
const val HEADER_FILTER_ADDITIONAL_SEARCH_PREFIX = "headerFilterAdditionalSearchPrefix"
const val NODEFAULTLIBS_DEPRECATED = "nodefaultlibs"
@@ -35,6 +32,7 @@ const val FOREIGN_EXCEPTION_MODE = "Xforeign-exception-mode"
const val DUMP_BRIDGES = "Xdump-bridges"
const val DISABLE_EXCEPTION_PRETTIFIER = "Xdisable-exception-prettifier"
const val USER_SETUP_HINT = "Xuser-setup-hint"
const val KONAN_DATA_DIR = "Xkonan-data-dir"
// TODO: unify camel and snake cases.
// Possible solution is to accept both cases
@@ -74,6 +72,8 @@ open class CommonInteropArguments(val argParser: ArgParser) {
fullName = "Xoverride-konan-properties",
description = "Override konan.properties.values"
).multiple().delimiter(";")
val konanDataDir by argParser.option(ArgType.String, KONAN_DATA_DIR,
description = "Path to konan and dependencies root folder")
}
open class CInteropArguments(argParser: ArgParser =
@@ -22,8 +22,8 @@ import org.jetbrains.kotlin.konan.target.AbstractToolConfig
import org.jetbrains.kotlin.native.interop.gen.jvm.KotlinPlatform
import org.jetbrains.kotlin.native.interop.indexer.Language
class ToolConfig(userProvidedTargetName: String?, flavor: KotlinPlatform, propertyOverrides: Map<String, String>)
: AbstractToolConfig(KonanHomeProvider.determineKonanHome(), userProvidedTargetName, propertyOverrides) {
class ToolConfig(userProvidedTargetName: String?, flavor: KotlinPlatform, propertyOverrides: Map<String, String>, konanDataDir: String? = null)
: AbstractToolConfig(KonanHomeProvider.determineKonanHome(), userProvidedTargetName, propertyOverrides, konanDataDir) {
val clang = when (flavor) {
KotlinPlatform.JVM -> platform.clangForJni
@@ -259,7 +259,7 @@ private fun processCLib(
cinteropArguments.argParser.printError("-def or -pkg should be provided!")
}
val tool = prepareTool(cinteropArguments.target, flavor, runFromDaemon, parseKeyValuePairs(cinteropArguments.overrideKonanProperties))
val tool = prepareTool(cinteropArguments.target, flavor, runFromDaemon, parseKeyValuePairs(cinteropArguments.overrideKonanProperties), konanDataDir = cinteropArguments.konanDataDir)
val def = DefFile(defFile, tool.substitutions)
val isLinkerOptsSetByUser = (cinteropArguments.linkerOpts.valueOrigin == ArgParser.ValueOrigin.SET_BY_USER) ||
@@ -480,7 +480,7 @@ private fun getLibraryResolver(
repos,
libraries.filter { it.contains(org.jetbrains.kotlin.konan.file.File.separator) },
target,
Distribution(KonanHomeProvider.determineKonanHome())
Distribution(KonanHomeProvider.determineKonanHome(), konanDataDir = cinteropArguments.konanDataDir)
).libraryResolver()
}
@@ -498,8 +498,8 @@ private fun resolveDependencies(
).getFullList(TopologicalLibraryOrder)
}
internal fun prepareTool(target: String?, flavor: KotlinPlatform, runFromDaemon: Boolean, propertyOverrides: Map<String, String> = emptyMap()) =
ToolConfig(target, flavor, propertyOverrides).also {
internal fun prepareTool(target: String?, flavor: KotlinPlatform, runFromDaemon: Boolean, propertyOverrides: Map<String, String> = emptyMap(), konanDataDir: String? = null) =
ToolConfig(target, flavor, propertyOverrides, konanDataDir).also {
if (!runFromDaemon) it.prepare() // Daemon prepares the tool himself. (See KonanToolRunner.kt)
}
@@ -42,7 +42,8 @@ class KonanConfig(val project: Project, val configuration: CompilerConfiguration
configuration.get(KonanConfigKeys.KONAN_HOME) ?: KonanHomeProvider.determineKonanHome(),
false,
configuration.get(KonanConfigKeys.RUNTIME_FILE),
overridenProperties
overridenProperties,
configuration.get(KonanConfigKeys.KONAN_DATA_DIR)
)
}
@@ -165,6 +165,7 @@ class KonanConfigKeys {
val SERIALIZED_DEPENDENCIES: CompilerConfigurationKey<String?> = CompilerConfigurationKey.create("path to serialized dependencies for native linking")
val SAVE_DEPENDENCIES_PATH: CompilerConfigurationKey<String?> = CompilerConfigurationKey.create("path to save serialized dependencies to")
val SAVE_LLVM_IR_DIRECTORY: CompilerConfigurationKey<String?> = CompilerConfigurationKey.create("directory to store LLVM IR from phases")
val KONAN_DATA_DIR: CompilerConfigurationKey<String?> = CompilerConfigurationKey.create("directory for storing konan dependencies, cache and prebuilds")
}
}
@@ -306,6 +306,7 @@ fun CompilerConfiguration.setupFromArguments(arguments: K2NativeCompilerArgument
putIfNotNull(SERIALIZED_DEPENDENCIES, parseSerializedDependencies(arguments, this@setupFromArguments))
putIfNotNull(SAVE_DEPENDENCIES_PATH, arguments.saveDependenciesPath)
putIfNotNull(SAVE_LLVM_IR_DIRECTORY, arguments.saveLlvmIrDirectory)
putIfNotNull(KONAN_DATA_DIR, arguments.konanDataDir)
}
private fun String.absoluteNormalizedFile() = java.io.File(this).absoluteFile.normalize()
+6 -1
View File
@@ -54,8 +54,13 @@ apply plugin: "kotlin.native.build-tools-conventions"
ext {
distDir = UtilsKt.getKotlinNativeDist(project)
dependenciesDir = DependencyProcessor.defaultDependenciesRoot
// TODO(Dmitrii Krasnov): remove else branch after KT-50463 will be in current bootstrap
def konanDataDir = project.findProperty('konan.data.dir')
dependenciesDir = konanDataDir != null ?
DependencyDirectories.INSTANCE.getDependenciesRoot(konanDataDir.toString())
: DependencyDirectories.defaultDependenciesRoot
experimentalEnabled = project.hasProperty("org.jetbrains.kotlin.native.experimentalTargets")
// TODO(Dmitrii Krasnov): add konanDataDir to the buildDistribution after KT-50463 will be in current bootstrap
platformManager = new PlatformManager(DistributionKt.buildDistribution(projectDir.absolutePath),
ext.experimentalEnabled)
-4
View File
@@ -5,14 +5,10 @@
import groovy.transform.stc.ClosureParams
import groovy.transform.stc.FromString
import org.jetbrains.kotlin.konan.target.*
import static org.jetbrains.kotlin.konan.target.KonanTarget.*
import org.jetbrains.kotlin.konan.util.Named
import org.jetbrains.kotlin.konan.properties.KonanPropertiesLoader
import org.jetbrains.kotlin.konan.util.ArchiveType
import org.jetbrains.kotlin.konan.util.DependencyProcessor
import static org.jetbrains.kotlin.konan.util.VisibleNamedKt.getVisibleName
buildscript {
apply from: "$rootDir/kotlin-native/gradle/kotlinGradlePlugin.gradle"
@@ -20,6 +20,7 @@ import org.jetbrains.kotlin.konan.library.KonanLibrary
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.DependencyDirectories
import org.jetbrains.kotlin.konan.util.DependencyProcessor
import org.jetbrains.kotlin.konan.util.KonanHomeProvider
import org.jetbrains.kotlin.library.KLIB_FILE_EXTENSION_WITH_DOT
@@ -93,7 +94,8 @@ object KlibToolLogger : Logger {
override fun log(message: String) = println(message)
}
val defaultRepository = File(DependencyProcessor.localKonanDir.resolve("klib").absolutePath)
// TODO(Dmitrii Krasnov): I'm not sure that we should put konan distribution dir here
val defaultRepository = File(DependencyDirectories.localKonanDir.resolve("klib").absolutePath)
open class ModuleDeserializer(val library: ByteArray) {
protected val moduleHeader: KlibMetadataProtoBuf.Header
-1
View File
@@ -30,7 +30,6 @@ minimalXcodeVersion=12.5
downloadingAttempts = 10
downloadingAttemptIntervalMs = 3000
homeDependencyCache = .konan/cache
# Appendix that is used for smaller version of LLVM distributions.
reducedLlvmAppendix = compact
+1
View File
@@ -43,6 +43,7 @@ project.logger.info("kotlin_root: $kotlin_root")
globalProperties.load(new java.io.FileReader(project.file("$kotlin_root/gradle.properties")))
ext.kotlinNativeVersionInResources = true
// TODO(Dmitrii Krasnov): add konanDataDir to the buildDistribution after KT-50463 will be in current bootstrap
def platformManager = new PlatformManager(DistributionKt.buildDistribution(UtilsKt.getKotlinNativeDist(project).path), false)
def kotlinDist = null
if (hasProperty("kotlin_dist")) {
@@ -46,8 +46,8 @@ import org.jetbrains.kotlin.konan.target.HostManager
import org.jetbrains.kotlin.konan.target.KonanTarget
import org.jetbrains.kotlin.konan.target.buildDistribution
import org.jetbrains.kotlin.konan.target.customerDistribution
import org.jetbrains.kotlin.konan.util.DependencyProcessor
import org.jetbrains.kotlin.*
import org.jetbrains.kotlin.konan.util.DependencyDirectories
import java.io.File
import javax.inject.Inject
@@ -166,7 +166,7 @@ internal fun Project.konanCompilerName(): String =
"kotlin-native-${project.simpleOsName}-${project.konanVersion}"
internal fun Project.konanCompilerDownloadDir(): String =
DependencyProcessor.localKonanDir.resolve(project.konanCompilerName()).absolutePath
DependencyDirectories.localKonanDir.resolve(project.konanCompilerName()).absolutePath
// region Useful extensions and functions ---------------------------------------
@@ -119,13 +119,18 @@ fun generatePlatformLibraries(args: Array<String>) = usingNativeMemoryAllocator
description = "Override konan.properties.values"
).multiple().delimiter(";")
val konanDataDir by argParser.option(ArgType.String,
fullName = "Xkonan-data-dir",
description = "Path to konan and dependencies root folder")
argParser.parse(args)
val distribution = Distribution(
KonanHomeProvider.determineKonanHome(),
onlyDefaultProfiles = false,
runtimeFileOverride = null,
propertyOverrides = parseKeyValuePairs(overrideKonanProperties)
propertyOverrides = parseKeyValuePairs(overrideKonanProperties),
konanDataDir = konanDataDir
)
val platformManager = PlatformManager(distribution)
@@ -163,6 +168,11 @@ fun generatePlatformLibraries(args: Array<String>) = usingNativeMemoryAllocator
add("-Xoverride-konan-properties")
add(overrideKonanProperties.joinToString(";"))
}
konanDataDir?.let {
add("-Xkonan-data-dir")
add(it)
}
}
)
@@ -40,7 +40,9 @@ fun invokeInterop(flavor: String, args: Array<String>, runFromDaemon: Boolean):
val repos = arguments.repo
val targetRequest = if (arguments is CInteropArguments) arguments.target
else (arguments as JSInteropArguments).target.toString()
val target = PlatformManager(KonanHomeProvider.determineKonanHome()).targetManager(targetRequest).target
val target = PlatformManager(
KonanHomeProvider.determineKonanHome(),
konanDataDir = arguments.konanDataDir).targetManager(targetRequest).target
val cinteropArgsToCompiler = Interop().interop(flavor, args,
InternalInteropOptions(generatedDir.absolutePath,
@@ -126,7 +126,7 @@ abstract class KotlinToolRunner(
}
}
fun run(args: List<String>) {
open fun run(args: List<String>) {
checkClasspath()
if (mustRunViaExec) runViaExec(args) else runInProcess(args)
@@ -37,6 +37,9 @@ internal val Project.konanVersion: String
get() = PropertiesProvider(this).nativeVersion
?: NativeCompilerDownloader.DEFAULT_KONAN_VERSION
internal val Project.konanDataDir: String?
get() = PropertiesProvider(this).konanDataDir
internal fun Project.getKonanCacheKind(target: KonanTarget): NativeCacheKind {
val commonCacheKind = PropertiesProvider(this).nativeCacheKind
val targetCacheKind = PropertiesProvider(this).nativeCacheKindForTarget(target)
@@ -69,7 +72,7 @@ private val Project.kotlinNativeCompilerJar: String
internal abstract class KotlinNativeToolRunner(
protected val toolName: String,
private val settings: Settings,
executionContext: GradleExecutionContext
executionContext: GradleExecutionContext,
) : KotlinToolRunner(executionContext) {
class Settings(
@@ -78,7 +81,8 @@ internal abstract class KotlinNativeToolRunner(
val konanPropertiesFile: File,
val useXcodeMessageStyle: Boolean,
val jvmArgs: List<String>,
val classpath: FileCollection
val classpath: FileCollection,
val konanDataDir: String?,
) {
companion object {
fun fromProject(project: Project) = Settings(
@@ -87,7 +91,8 @@ internal abstract class KotlinNativeToolRunner(
konanPropertiesFile = project.file("${project.konanHome}/konan/konan.properties"),
useXcodeMessageStyle = project.useXcodeMessageStyle,
jvmArgs = project.jvmArgs,
classpath = project.files(project.kotlinNativeCompilerJar, "${project.konanHome}/konan/lib/trove4j.jar")
classpath = project.files(project.kotlinNativeCompilerJar, "${project.konanHome}/konan/lib/trove4j.jar"),
konanDataDir = project.konanDataDir
)
}
}
@@ -131,13 +136,21 @@ internal abstract class KotlinNativeToolRunner(
override fun transformArgs(args: List<String>) = listOf(toolName) + args
final override fun getCustomJvmArgs() = settings.jvmArgs
final override fun run(args: List<String>) {
super.run(args + extractArgsFromSettings())
}
private fun extractArgsFromSettings(): List<String> {
return settings.konanDataDir?.let { listOf("-Xkonan-data-dir", it) } ?: emptyList()
}
}
/** A common ancestor for all runners that run the cinterop tool. */
internal abstract class AbstractKotlinNativeCInteropRunner(
toolName: String,
settings: Settings,
executionContext: GradleExecutionContext
executionContext: GradleExecutionContext,
) : KotlinNativeToolRunner(toolName, settings, executionContext) {
override val mustRunViaExec get() = true
@@ -160,7 +173,7 @@ internal abstract class AbstractKotlinNativeCInteropRunner(
}
konanProperties.resolvablePropertyString("llvmHome.mingw_x64")?.let { toolchainDir ->
DependencyDirectories.defaultDependenciesRoot
DependencyDirectories.getDependenciesRoot(settings.konanDataDir)
.resolve("$toolchainDir/bin")
.absolutePath
}
@@ -193,7 +206,7 @@ private constructor(
/** Kotlin/Native compiler runner */
internal class KotlinNativeCompilerRunner(
private val settings: Settings,
executionContext: GradleExecutionContext
executionContext: GradleExecutionContext,
) : KotlinNativeToolRunner("konanc", settings.parent, executionContext) {
class Settings(
val parent: KotlinNativeToolRunner.Settings,
@@ -231,7 +244,7 @@ internal class KotlinNativeCompilerRunner(
/** Platform libraries generation tool. Runs the cinterop tool under the hood. */
internal class KotlinNativeLibraryGenerationRunner(
private val settings: Settings,
executionContext: GradleExecutionContext
executionContext: GradleExecutionContext,
) :
AbstractKotlinNativeCInteropRunner("generatePlatformLibraries", settings, executionContext) {
@@ -535,6 +535,13 @@ internal class PropertiesProvider private constructor(private val project: Proje
val suppressExperimentalArtifactsDslWarning: Boolean
get() = booleanProperty(KOTLIN_NATIVE_SUPPRESS_EXPERIMENTAL_ARTIFACTS_DSL_WARNING) ?: false
/**
* Allows the user to specify a custom location for the Kotlin/Native distribution.
* This property takes precedence over the 'KONAN_DATA_DIR' environment variable.
*/
val konanDataDir: String?
get() = property(PropertyNames.KONAN_DATA_DIR)
/**
* Retrieves a comma-separated list of browsers to use when running karma tests for [target]
* @see KOTLIN_JS_KARMA_BROWSERS
@@ -632,6 +639,7 @@ internal class PropertiesProvider private constructor(private val project: Proje
const val KOTLIN_SUPPRESS_GRADLE_PLUGIN_ERRORS = "kotlin.internal.suppressGradlePluginErrors"
const val KOTLIN_NATIVE_IGNORE_DISABLED_TARGETS = "kotlin.native.ignoreDisabledTargets"
const val KOTLIN_NATIVE_SUPPRESS_EXPERIMENTAL_ARTIFACTS_DSL_WARNING = "kotlin.native.suppressExperimentalArtifactsDslWarning"
const val KONAN_DATA_DIR = "konan.data.dir"
}
companion object {
@@ -40,7 +40,9 @@ class NativeCompilerDownloader(
}
val compilerDirectory: File
get() = DependencyDirectories.localKonanDir.resolve(dependencyNameWithOsAndVersion)
get() = DependencyDirectories
.getLocalKonanDir(project.kotlinPropertiesProvider.konanDataDir)
.resolve(dependencyNameWithOsAndVersion)
private val logger: Logger
get() = project.logger
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.gradle.targets.native.internal
import org.gradle.api.Project
import org.jetbrains.kotlin.compilerRunner.KotlinNativeLibraryGenerationRunner
import org.jetbrains.kotlin.compilerRunner.getKonanCacheKind
import org.jetbrains.kotlin.compilerRunner.konanDataDir
import org.jetbrains.kotlin.compilerRunner.konanHome
import org.jetbrains.kotlin.gradle.dsl.NativeCacheKind
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider
@@ -28,7 +29,7 @@ import java.util.concurrent.ConcurrentHashMap
internal class PlatformLibrariesGenerator(val project: Project, val konanTarget: KonanTarget) {
private val distribution =
customerDistribution(project.konanHome)
customerDistribution(project.konanHome, konanDataDir = project.konanDataDir)
private val platformLibsDirectory =
File(distribution.platformLibs(konanTarget)).absoluteFile
@@ -353,6 +353,10 @@ internal constructor(
@get:Internal // these sources are normally a subset of `source` ones which are already tracked
val commonSources: ConfigurableFileCollection = project.files()
@Optional
@get:Input
val konanDataDir: String? = project.konanDataDir
@get:Nested
override val multiplatformStructure: K2MultiplatformStructure = objectFactory.newInstance()
@@ -941,7 +945,7 @@ internal class CacheBuilder(
}
private fun ensureCompilerProvidedLibsPrecached() {
val distribution = Distribution(settings.runnerSettings.parent.konanHome)
val distribution = Distribution(settings.runnerSettings.parent.konanHome, konanDataDir = settings.runnerSettings.parent.konanDataDir)
val platformLibs = mutableListOf<File>().apply {
this += File(distribution.stdlib)
this += File(distribution.platformLibs(konanTarget)).listFiles().orEmpty()
@@ -7,8 +7,8 @@ package org.jetbrains.kotlin.konan.target
import org.jetbrains.kotlin.konan.util.defaultTargetSubstitutions
abstract class AbstractToolConfig(konanHome: String, userProvidedTargetName: String?, propertyOverrides: Map<String, String>) {
private val distribution = Distribution(konanHome, propertyOverrides = propertyOverrides)
abstract class AbstractToolConfig(konanHome: String, userProvidedTargetName: String?, propertyOverrides: Map<String, String>, konanDataDir: String? = null) {
private val distribution = Distribution(konanHome, propertyOverrides = propertyOverrides, konanDataDir = konanDataDir)
private val platformManager = PlatformManager(distribution)
private val targetManager = platformManager.targetManager(userProvidedTargetName)
private val host = HostManager.host
@@ -21,10 +21,10 @@ import org.jetbrains.kotlin.konan.properties.Properties
import org.jetbrains.kotlin.konan.util.InternalServer
class AppleConfigurablesImpl(
target: KonanTarget,
properties: Properties,
baseDir: String?
) : AppleConfigurables, KonanPropertiesLoader(target, properties, baseDir) {
target: KonanTarget,
properties: Properties,
dependenciesDir: String?
) : AppleConfigurables, KonanPropertiesLoader(target, properties, dependenciesDir) {
private val sdkDependency = this.targetSysRoot!!
private val toolchainDependency = this.targetToolchain!!
@@ -18,33 +18,33 @@ package org.jetbrains.kotlin.konan.target
import org.jetbrains.kotlin.konan.properties.*
class GccConfigurablesImpl(target: KonanTarget, properties: Properties, baseDir: String?)
: GccConfigurables, KonanPropertiesLoader(target, properties, baseDir), ConfigurablesWithEmulator {
class GccConfigurablesImpl(target: KonanTarget, properties: Properties, dependenciesRoot: String?)
: GccConfigurables, KonanPropertiesLoader(target, properties, dependenciesRoot), ConfigurablesWithEmulator {
override val dependencies: List<String>
get() = super.dependencies + listOfNotNull(emulatorDependency)
}
class AndroidConfigurablesImpl(target: KonanTarget, properties: Properties, baseDir: String?)
: AndroidConfigurables, KonanPropertiesLoader(target, properties, baseDir)
class AndroidConfigurablesImpl(target: KonanTarget, properties: Properties, dependenciesRoot: String?)
: AndroidConfigurables, KonanPropertiesLoader(target, properties, dependenciesRoot)
class WasmConfigurablesImpl(target: KonanTarget, properties: Properties, baseDir: String?)
: WasmConfigurables, KonanPropertiesLoader(target, properties, baseDir)
class WasmConfigurablesImpl(target: KonanTarget, properties: Properties, dependenciesRoot: String?)
: WasmConfigurables, KonanPropertiesLoader(target, properties, dependenciesRoot)
class ZephyrConfigurablesImpl(target: KonanTarget, properties: Properties, baseDir: String?)
: ZephyrConfigurables, KonanPropertiesLoader(target, properties, baseDir)
class ZephyrConfigurablesImpl(target: KonanTarget, properties: Properties, dependenciesRoot: String?)
: ZephyrConfigurables, KonanPropertiesLoader(target, properties, dependenciesRoot)
fun loadConfigurables(target: KonanTarget, properties: Properties, baseDir: String?): Configurables = when (target.family) {
Family.LINUX -> GccConfigurablesImpl(target, properties, baseDir)
fun loadConfigurables(target: KonanTarget, properties: Properties, dependenciesRoot: String?): Configurables = when (target.family) {
Family.LINUX -> GccConfigurablesImpl(target, properties, dependenciesRoot)
Family.TVOS, Family.WATCHOS, Family.IOS, Family.OSX -> AppleConfigurablesImpl(target, properties, baseDir)
Family.TVOS, Family.WATCHOS, Family.IOS, Family.OSX -> AppleConfigurablesImpl(target, properties, dependenciesRoot)
Family.ANDROID -> AndroidConfigurablesImpl(target, properties, baseDir)
Family.ANDROID -> AndroidConfigurablesImpl(target, properties, dependenciesRoot)
Family.MINGW -> MingwConfigurablesImpl(target, properties, baseDir)
Family.MINGW -> MingwConfigurablesImpl(target, properties, dependenciesRoot)
Family.WASM -> WasmConfigurablesImpl(target, properties, baseDir)
Family.WASM -> WasmConfigurablesImpl(target, properties, dependenciesRoot)
Family.ZEPHYR -> ZephyrConfigurablesImpl(target, properties, baseDir)
Family.ZEPHYR -> ZephyrConfigurablesImpl(target, properties, dependenciesRoot)
}
@@ -16,15 +16,17 @@ class Distribution private constructor(private val serialized: Serialized) : jav
konanHome: String,
onlyDefaultProfiles: Boolean = false,
runtimeFileOverride: String? = null,
propertyOverrides: Map<String, String>? = null
) : this(Serialized(konanHome, onlyDefaultProfiles, runtimeFileOverride, propertyOverrides))
propertyOverrides: Map<String, String>? = null,
konanDataDir: String? = null
) : this(Serialized(konanHome, onlyDefaultProfiles, runtimeFileOverride, propertyOverrides, konanDataDir))
val konanHome by serialized::konanHome
private val onlyDefaultProfiles by serialized::onlyDefaultProfiles
private val runtimeFileOverride by serialized::runtimeFileOverride
private val propertyOverrides by serialized::propertyOverrides
private val konanDataDir by serialized::konanDataDir
val localKonanDir = DependencyDirectories.localKonanDir
val localKonanDir = DependencyDirectories.getLocalKonanDir(konanDataDir)
val konanSubdir = "$konanHome/konan"
val mainPropertyFileName = "$konanSubdir/konan.properties"
@@ -99,7 +101,9 @@ class Distribution private constructor(private val serialized: Serialized) : jav
val launcherFiles = listOf("launcher.bc")
val dependenciesDir = DependencyDirectories.defaultDependenciesRoot.absolutePath
val dependenciesDir = DependencyDirectories
.getDependenciesRoot(konanDataDir)
.absolutePath
val subTargetProvider = object: SubTargetProvider {
override fun availableSubTarget(genericName: String) =
@@ -127,6 +131,7 @@ class Distribution private constructor(private val serialized: Serialized) : jav
val onlyDefaultProfiles: Boolean,
val runtimeFileOverride: String?,
val propertyOverrides: Map<String, String>?,
val konanDataDir: String?,
) : java.io.Serializable {
companion object {
private const val serialVersionUID: Long = 0L
@@ -139,4 +144,8 @@ class Distribution private constructor(private val serialized: Serialized) : jav
// TODO: Move into K/N?
fun buildDistribution(konanHome: String) = Distribution(konanHome,true, null)
fun buildDistribution(konanHome: String, konanDataDir: String?) = Distribution(konanHome,true, null, konanDataDir = konanDataDir)
fun customerDistribution(konanHome: String) = Distribution(konanHome,false, null)
fun customerDistribution(konanHome: String, konanDataDir: String?) = Distribution(konanHome,false, null, konanDataDir = konanDataDir)
@@ -34,10 +34,12 @@ interface TargetableExternalStorage {
fun downloadDependencies()
}
abstract class KonanPropertiesLoader(override val target: KonanTarget,
val properties: Properties,
private val baseDir: String? = null,
private val host: KonanTarget = HostManager.host) : Configurables {
abstract class KonanPropertiesLoader(
override val target: KonanTarget,
val properties: Properties,
private val dependenciesRoot: String?,
private val host: KonanTarget = HostManager.host,
) : Configurables {
private val predefinedLlvmDistributions: Set<String> =
properties.propertyList("predefinedLlvmDistributions").toSet()
@@ -87,13 +89,13 @@ abstract class KonanPropertiesLoader(override val target: KonanTarget,
override fun absolute(value: String?): String =
dependencyProcessor!!.resolve(value!!).absolutePath
private val dependencyProcessor by lazy {
baseDir?.let {
dependenciesRoot?.let {
DependencyProcessor(
dependenciesRoot = File(baseDir),
properties = this,
archiveType = defaultArchiveTypeByHost(host)
dependenciesRoot = File(dependenciesRoot),
properties = this,
archiveType = defaultArchiveTypeByHost(host)
){ url, currentBytes, totalBytes ->
print("\n(KonanProperies) Downloading dependency: $url (${currentBytes}/${totalBytes}). ")
print("\n(KonanProperties) Downloading dependency: $url (${currentBytes}/${totalBytes}). ")
}
}
}
@@ -16,10 +16,7 @@
package org.jetbrains.kotlin.konan.target
import org.jetbrains.kotlin.konan.util.DependencyProcessor
class Platform(val configurables: Configurables)
: Configurables by configurables {
class Platform(val configurables: Configurables) : Configurables by configurables {
val clang: ClangArgs.Native by lazy {
ClangArgs.Native(configurables)
@@ -35,15 +32,15 @@ class Platform(val configurables: Configurables)
}
class PlatformManager private constructor(private val serialized: Serialized) :
HostManager(serialized.distribution, serialized.experimental), java.io.Serializable {
HostManager(serialized.distribution, serialized.experimental), java.io.Serializable {
constructor(konanHome: String, experimental: Boolean = false) : this(Distribution(konanHome), experimental)
constructor(konanHome: String, experimental: Boolean = false, konanDataDir: String? = null) : this(Distribution(konanHome, konanDataDir = konanDataDir), experimental)
constructor(distribution: Distribution, experimental: Boolean = false) : this(Serialized(distribution, experimental))
private val distribution by serialized::distribution
private val loaders = enabled.map {
it to loadConfigurables(it, distribution.properties, DependencyProcessor.defaultDependenciesRoot.absolutePath)
it to loadConfigurables(it, distribution.properties, distribution.dependenciesDir)
}.toMap()
private val platforms = loaders.map {
@@ -58,8 +55,8 @@ class PlatformManager private constructor(private val serialized: Serialized) :
private fun writeReplace(): Any = serialized
private data class Serialized(
val distribution: Distribution,
val experimental: Boolean
val distribution: Distribution,
val experimental: Boolean,
) : java.io.Serializable {
companion object {
private const val serialVersionUID: Long = 0L
@@ -11,8 +11,8 @@ import org.jetbrains.kotlin.konan.properties.KonanPropertiesLoader
import org.jetbrains.kotlin.konan.properties.Properties
import java.nio.file.Paths
class MingwConfigurablesImpl(target: KonanTarget, properties: Properties, baseDir: String?)
: MingwConfigurables, KonanPropertiesLoader(target, properties, baseDir) {
class MingwConfigurablesImpl(target: KonanTarget, properties: Properties, dependenciesRoot: String?) : MingwConfigurables,
KonanPropertiesLoader(target, properties, dependenciesRoot) {
override val windowsKit: WindowsKit by lazy {
when (windowsSdkPartsProvider) {
WindowsSdkPartsProvider.InternalServer -> createCustomWindowsKitPath(Paths.get(absolute(windowsKitParts)))
@@ -8,13 +8,31 @@ package org.jetbrains.kotlin.konan.util
import java.io.File
object DependencyDirectories {
private const val DEPENDENCIES_FOLDER_NAME = "dependencies"
private const val CACHE_FOLDER_NAME = "cache"
@JvmStatic
val localKonanDir: File
get() = File(System.getenv("KONAN_DATA_DIR") ?: (System.getProperty("user.home") + File.separator + ".konan"))
get() = getLocalKonanDir()
@JvmStatic
val defaultDependenciesRoot: File
get() = localKonanDir.resolve("dependencies")
get() = getDependenciesRoot()
val defaultDependencyCacheDir: File
get() = localKonanDir.resolve("cache")
fun getLocalKonanDir(konanDataDir: String? = null): File {
return File(
konanDataDir
?: System.getenv("KONAN_DATA_DIR")
?: (System.getProperty("user.home") + File.separator + ".konan")
)
}
fun getDependenciesRoot(konanDataDir: String? = null): File {
return getLocalKonanDir(konanDataDir).resolve(DEPENDENCIES_FOLDER_NAME)
}
fun getDependencyCacheDir(konanDataDir: String? = null): File {
return getLocalKonanDir(konanDataDir).resolve(CACHE_FOLDER_NAME)
}
}
@@ -27,12 +27,10 @@ import java.net.InetAddress
import java.net.URL
import java.net.UnknownHostException
import java.nio.file.Paths
import java.util.concurrent.locks.ReentrantLock
import kotlin.concurrent.withLock
private val Properties.dependenciesUrl : String
private val Properties.dependenciesUrl: String
get() = getProperty("dependenciesUrl")
?: throw IllegalStateException("No such property in konan.properties: dependenciesUrl")
?: throw IllegalStateException("No such property in konan.properties: dependenciesUrl")
private val Properties.airplaneMode : Boolean
get() = getProperty("airplaneMode")?.toBoolean() ?: false
@@ -84,17 +82,19 @@ sealed class DependencySource {
* Inspects [dependencies] and downloads all the missing ones into [dependenciesDirectory] from [dependenciesUrl].
* If [airplaneMode] is true will throw a RuntimeException instead of downloading.
*/
class DependencyProcessor(dependenciesRoot: File,
private val dependenciesUrl: String,
dependencyToCandidates: Map<String, List<DependencySource>>,
homeDependencyCache: File = defaultDependencyCacheDir,
private val airplaneMode: Boolean = false,
maxAttempts: Int = DependencyDownloader.DEFAULT_MAX_ATTEMPTS,
attemptIntervalMs: Long = DependencyDownloader.DEFAULT_ATTEMPT_INTERVAL_MS,
customProgressCallback: ProgressCallback? = null,
private val keepUnstable: Boolean = true,
private val deleteArchives: Boolean = true,
private val archiveType: ArchiveType = ArchiveType.systemDefault) {
class DependencyProcessor(
dependenciesRoot: File,
private val dependenciesUrl: String,
dependencyToCandidates: Map<String, List<DependencySource>>,
homeDependencyCache: File = DependencyDirectories.getDependencyCacheDir(dependenciesRoot.absolutePath),
private val airplaneMode: Boolean = false,
maxAttempts: Int = DependencyDownloader.DEFAULT_MAX_ATTEMPTS,
attemptIntervalMs: Long = DependencyDownloader.DEFAULT_ATTEMPT_INTERVAL_MS,
customProgressCallback: ProgressCallback? = null,
private val keepUnstable: Boolean = true,
private val deleteArchives: Boolean = true,
private val archiveType: ArchiveType = ArchiveType.systemDefault,
) {
private val dependenciesDirectory by lazy {
dependenciesRoot.apply { mkdirs() }
@@ -222,16 +222,6 @@ class DependencyProcessor(dependenciesRoot: File,
}
companion object {
val localKonanDir: File
get() = File(System.getenv("KONAN_DATA_DIR") ?: (System.getProperty("user.home") + File.separator + ".konan"))
@JvmStatic
val defaultDependenciesRoot: File
get() = localKonanDir.resolve("dependencies")
val defaultDependencyCacheDir: File
get() = localKonanDir.resolve("cache")
val isInternalSeverAvailable: Boolean
get() = InternalServer.isAvailable
}