[Native] Add simple symbol mechanism to konan.properties

Java Properties format is extremely trivial and does not support any
kind of references or variables. It makes konan.properties repetitive.
This commits adds support of perl-like `$` sigil which allows to
reference properties inside values.
This commit is contained in:
Sergey Bogolepov
2020-09-14 22:05:09 +07:00
parent fc35b5398c
commit 5a0a853d9b
3 changed files with 54 additions and 1 deletions

View File

@@ -69,3 +69,51 @@ fun Properties.keepOnlyDefaultProfiles() {
// TODO: it actually affects only resolution made in :dependencies,
// that's why we assume that 'default' profile comes first (and check this above).
}
/**
* Wraps [propertyList] with resolving mechanism. See [String.resolveValue].
*/
fun Properties.resolvablePropertyList(
key: String, suffix: String? = null, escapeInQuotes: Boolean = false,
visitedProperties: MutableSet<String> = mutableSetOf()
): List<String> = propertyList(key, suffix, escapeInQuotes).flatMap {
// We need to create a copy of a visitedProperties to avoid collisions
// between different elements of the list.
it.resolveValue(this, visitedProperties.toMutableSet())
}
/**
* Wraps [propertyString] with resolving mechanism. See [String.resolveValue].
*/
fun Properties.resolvablePropertyString(
key: String, suffix: String? = null,
visitedProperties: MutableSet<String> = mutableSetOf()
): String? = propertyString(key, suffix)
?.split(' ')
?.flatMap { it.resolveValue(this, visitedProperties) }
?.joinToString(" ")
/**
* Adds trivial symbol resolving mechanism to properties files.
*
* Given the following properties file:
*
* key0 = value1 value2
* key1 = value3 $key0
* key2 = $key1
*
* "$key1".resolveValue(properties) will return List("value3", "value1", "value2")
*/
private fun String.resolveValue(properties: Properties, visitedProperties: MutableSet<String> = mutableSetOf()): List<String> =
when {
startsWith("$") -> {
val property = this.substringAfter('$')
// Keep track of visited properties to avoid running in circles.
if (!visitedProperties.add(property)) {
error("Circular dependency: ${visitedProperties.joinToString()}")
}
properties.resolvablePropertyList(property, visitedProperties = visitedProperties)
}
else -> listOf(this)
}

View File

@@ -12,6 +12,7 @@ import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider
import org.jetbrains.kotlin.gradle.plugin.mpp.isAtLeast
import org.jetbrains.kotlin.gradle.utils.NativeCompilerDownloader
import org.jetbrains.kotlin.konan.CompilerVersion
import org.jetbrains.kotlin.konan.properties.resolvablePropertyString
import org.jetbrains.kotlin.konan.target.HostManager
import org.jetbrains.kotlin.konan.target.KonanTarget
import org.jetbrains.kotlin.konan.util.DependencyDirectories
@@ -104,7 +105,7 @@ internal abstract class AbstractKotlinNativeCInteropRunner(toolName: String, pro
project.file("${project.konanHome}/konan/konan.properties").inputStream().use(::load)
}
konanProperties.getProperty("llvmHome.mingw_x64")?.let { toolchainDir ->
konanProperties.resolvablePropertyString("llvmHome.mingw_x64")?.let { toolchainDir ->
DependencyDirectories.defaultDependenciesRoot
.resolve("$toolchainDir/bin")
.absolutePath

View File

@@ -43,6 +43,10 @@ class Distribution(
fun additionalPropertyFiles(genericName: String) =
preconfiguredPropertyFiles(genericName) + userPropertyFiles(genericName)
/**
* Please note that konan.properties uses simple resolving mechanism.
* See [org.jetbrains.kotlin.konan.properties.resolveValue].
*/
val properties by lazy {
val result = Properties()