Allow prefix and relative path in resolvable properties.
It allows us to move more logic to konan.properties from ClangArgs. E.g., something like `-$absoluteTargetSysRoot/usr/include/c++/4.9.4`
This commit is contained in:
@@ -107,13 +107,33 @@ fun Properties.resolvablePropertyString(
|
||||
*/
|
||||
private fun String.resolveValue(properties: Properties, visitedProperties: MutableSet<String> = mutableSetOf()): List<String> =
|
||||
when {
|
||||
startsWith("$") -> {
|
||||
val property = this.substringAfter('$')
|
||||
contains("$") -> {
|
||||
val prefix = this.substringBefore('$', missingDelimiterValue = "")
|
||||
val withoutSigil = this.substringAfter('$')
|
||||
val property = withoutSigil.substringBefore('/')
|
||||
val relative = withoutSigil.substringAfter('/', missingDelimiterValue = "")
|
||||
// Keep track of visited properties to avoid running in circles.
|
||||
if (!visitedProperties.add(property)) {
|
||||
error("Circular dependency: ${visitedProperties.joinToString()}")
|
||||
}
|
||||
properties.resolvablePropertyList(property, visitedProperties = visitedProperties)
|
||||
val substitutionResult = properties.resolvablePropertyList(property, visitedProperties = visitedProperties)
|
||||
when {
|
||||
substitutionResult.size > 1 -> when {
|
||||
relative.isNotEmpty() ->
|
||||
error("Cannot append `/$relative` to multiple values: ${substitutionResult.joinToString()}")
|
||||
prefix.isNotEmpty() ->
|
||||
error("Cannot add prefix `$prefix` to multiple values: ${substitutionResult.joinToString()}")
|
||||
else -> substitutionResult
|
||||
}
|
||||
else -> substitutionResult.map {
|
||||
// Avoid repeated '/' at the end.
|
||||
if (relative.isNotEmpty()) {
|
||||
"$prefix${it.dropLastWhile { it == '/' }}/$relative"
|
||||
} else {
|
||||
"$prefix$it"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else -> listOf(this)
|
||||
}
|
||||
|
||||
+55
@@ -65,6 +65,61 @@ class ResolvablePropertiesTests {
|
||||
props.resolvablePropertyString("k1")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `trivial relative path`() {
|
||||
val props = propertiesOf(
|
||||
"k1" to "v1",
|
||||
"k2" to "\$k1/sysroot"
|
||||
)
|
||||
assertEquals("v1/sysroot", props.resolvablePropertyString("k2"))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `two-fold relative path`() {
|
||||
val props = propertiesOf(
|
||||
"k1" to "v1",
|
||||
"k2" to "\$k1/toolchain",
|
||||
"k3" to "\$k2/sysroot"
|
||||
)
|
||||
assertEquals("v1/toolchain/sysroot", props.resolvablePropertyString("k3"))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `absolute path`() {
|
||||
val props = propertiesOf(
|
||||
"k1" to "/",
|
||||
"k2" to "\$k1/bin"
|
||||
)
|
||||
assertEquals("/bin", props.resolvablePropertyString("k2"))
|
||||
}
|
||||
|
||||
@Test(expected = java.lang.IllegalStateException::class)
|
||||
fun `incorrect relative path`() {
|
||||
val props = propertiesOf(
|
||||
"k1" to "v1 v2",
|
||||
"k2" to "\$k1/sysroot"
|
||||
)
|
||||
props.resolvablePropertyString("k2")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `simple prefix`() {
|
||||
val props = propertiesOf(
|
||||
"k1" to "v1",
|
||||
"k2" to "--key=\$k1"
|
||||
)
|
||||
assertEquals("--key=v1", props.resolvablePropertyString("k2"))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `with prefix and relative`() {
|
||||
val props = propertiesOf(
|
||||
"absoluteTargetSysRoot" to "/",
|
||||
"include" to "-I\$absoluteTargetSysRoot/usr/include/c++/4.9.4"
|
||||
)
|
||||
assertEquals("-I/usr/include/c++/4.9.4", props.resolvablePropertyString("include"))
|
||||
}
|
||||
|
||||
companion object {
|
||||
private fun propertiesOf(vararg pairs: Pair<String, Any>): Properties =
|
||||
Properties().also {
|
||||
|
||||
Reference in New Issue
Block a user