[Commonizer] Implement :native:kotlin-klib-commonizer:api with support for library commonization
- Implement new Gradle module ':native:kotlin-klib-commonizer' - Implement new NativeKlibCommonize task - Implement CommonizerTarget.identityString
This commit is contained in:
committed by
Space
parent
6d019d9544
commit
4500b6ce74
+30
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* 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.descriptors.commonizer
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.commonizer.utils.konanHome
|
||||
import org.jetbrains.kotlin.konan.target.KonanTarget
|
||||
import org.junit.Rule
|
||||
import org.junit.rules.TemporaryFolder
|
||||
import kotlin.test.Test
|
||||
|
||||
class CliCommonizerTest {
|
||||
|
||||
@get:Rule
|
||||
val temporaryOutputDirectory = TemporaryFolder()
|
||||
|
||||
@Test
|
||||
fun invokeCliWithEmptyArguments() {
|
||||
val commonizer = CliCommonizer(this::class.java.classLoader)
|
||||
commonizer.commonizeLibraries(
|
||||
konanHome = konanHome,
|
||||
inputLibraries = emptySet(),
|
||||
dependencyLibraries = emptySet(),
|
||||
outputCommonizerTarget = CommonizerTarget(KonanTarget.LINUX_X64, KonanTarget.MACOS_X64),
|
||||
outputDirectory = temporaryOutputDirectory.root
|
||||
)
|
||||
}
|
||||
}
|
||||
+80
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* 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.descriptors.commonizer
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.commonizer.utils.konanHome
|
||||
import org.jetbrains.kotlin.konan.target.KonanTarget.LINUX_ARM64
|
||||
import org.jetbrains.kotlin.konan.target.KonanTarget.LINUX_X64
|
||||
import org.junit.Rule
|
||||
import org.junit.rules.TemporaryFolder
|
||||
import java.io.File
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertTrue
|
||||
import kotlin.test.fail
|
||||
|
||||
class CommonizeLibcurlTest {
|
||||
|
||||
@get:Rule
|
||||
val temporaryOutputDirectory = TemporaryFolder()
|
||||
|
||||
@Test
|
||||
fun commonizeSuccessfully() {
|
||||
val libraries = File("testData/libcurl").walkTopDown().filter { it.isFile && it.extension == "klib" }.toSet()
|
||||
val commonizer = CliCommonizer(this::class.java.classLoader)
|
||||
|
||||
commonizer.commonizeLibraries(
|
||||
konanHome = konanHome,
|
||||
inputLibraries = libraries,
|
||||
dependencyLibraries = emptySet(),
|
||||
outputCommonizerTarget = CommonizerTarget(LINUX_ARM64, LINUX_X64),
|
||||
outputDirectory = temporaryOutputDirectory.root
|
||||
)
|
||||
|
||||
val x64OutputDirectory = temporaryOutputDirectory.root.resolve(CommonizerTarget(LINUX_X64).identityString)
|
||||
val arm64OutputDirectory = temporaryOutputDirectory.root.resolve(CommonizerTarget(LINUX_ARM64).identityString)
|
||||
val commonOutputDirectory = temporaryOutputDirectory.root.resolve(CommonizerTarget(LINUX_X64, LINUX_ARM64).identityString)
|
||||
|
||||
assertTrue(
|
||||
x64OutputDirectory.exists(),
|
||||
"Missing output directory for x64 target"
|
||||
)
|
||||
|
||||
assertTrue(
|
||||
arm64OutputDirectory.exists(),
|
||||
"Missing output directory for arm64 target"
|
||||
)
|
||||
|
||||
assertTrue(
|
||||
commonOutputDirectory.exists(),
|
||||
"Missing output directory for commonized x64&arm64 target"
|
||||
)
|
||||
|
||||
fun assertContainsKnmFiles(file: File) {
|
||||
assertTrue(
|
||||
file.walkTopDown().any { it.extension == "knm" },
|
||||
"Expected directory ${file.name} to contain at least one knm file"
|
||||
)
|
||||
}
|
||||
|
||||
assertContainsKnmFiles(x64OutputDirectory)
|
||||
assertContainsKnmFiles(arm64OutputDirectory)
|
||||
assertContainsKnmFiles(commonOutputDirectory)
|
||||
|
||||
fun assertContainsManifestWithContent(directory: File, content: String) {
|
||||
val manifest = directory.walkTopDown().firstOrNull { it.name == "manifest" }
|
||||
?: fail("${directory.name} does not contain any manifest")
|
||||
|
||||
assertTrue(
|
||||
content in manifest.readText(),
|
||||
"Expected manifest in ${directory.name} to contain $content\n${manifest.readText()}"
|
||||
)
|
||||
}
|
||||
|
||||
assertContainsManifestWithContent(x64OutputDirectory, "native_targets=linux_x64")
|
||||
assertContainsManifestWithContent(arm64OutputDirectory, "native_targets=linux_arm64")
|
||||
assertContainsManifestWithContent(commonOutputDirectory, "native_targets=linux_x64 linux_arm64")
|
||||
}
|
||||
}
|
||||
+137
@@ -0,0 +1,137 @@
|
||||
/*
|
||||
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* 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.descriptors.commonizer
|
||||
|
||||
import org.jetbrains.kotlin.konan.target.KonanTarget
|
||||
import org.jetbrains.kotlin.konan.target.KonanTarget.*
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
class CommonizerTargetIdentityStringTest {
|
||||
|
||||
@Test
|
||||
fun leafTargets() {
|
||||
KonanTarget.predefinedTargets.values.forEach { konanTarget ->
|
||||
assertEquals(konanTarget.name, CommonizerTarget(konanTarget).identityString)
|
||||
assertEquals(CommonizerTarget(konanTarget), parseCommonizerTarget(CommonizerTarget(konanTarget).identityString))
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `simple shared targets are invariant under konanTarget order`() {
|
||||
val macosFirst = CommonizerTarget(MACOS_X64, LINUX_X64)
|
||||
val linuxFirst = CommonizerTarget(LINUX_X64, MACOS_X64)
|
||||
|
||||
assertEquals(macosFirst, linuxFirst)
|
||||
assertEquals(macosFirst.identityString, linuxFirst.identityString)
|
||||
assertEquals(linuxFirst, parseCommonizerTarget(linuxFirst.identityString))
|
||||
assertEquals(macosFirst, parseCommonizerTarget(macosFirst.identityString))
|
||||
assertEquals(macosFirst, parseCommonizerTarget(linuxFirst.identityString))
|
||||
assertEquals(linuxFirst, parseCommonizerTarget(macosFirst.identityString))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `hierarchical commonizer targets`() {
|
||||
val hierarchy = SharedCommonizerTarget(
|
||||
CommonizerTarget(LINUX_X64, MACOS_X64),
|
||||
CommonizerTarget(IOS_ARM64, IOS_X64)
|
||||
)
|
||||
assertEquals(setOf(LINUX_X64, MACOS_X64, IOS_ARM64, IOS_X64), hierarchy.konanTargets)
|
||||
assertEquals(hierarchy, parseCommonizerTarget(hierarchy.identityString))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `multilevel hierarchical commonizer targets`() {
|
||||
val hierarchy = SharedCommonizerTarget(
|
||||
SharedCommonizerTarget(
|
||||
SharedCommonizerTarget(
|
||||
SharedCommonizerTarget(
|
||||
CommonizerTarget(LINUX_X64, MACOS_X64),
|
||||
CommonizerTarget(IOS_X64, IOS_ARM64)
|
||||
),
|
||||
CommonizerTarget(LINUX_ARM32_HFP)
|
||||
),
|
||||
CommonizerTarget(LINUX_MIPSEL32)
|
||||
),
|
||||
CommonizerTarget(WATCHOS_X86, WATCHOS_ARM64)
|
||||
)
|
||||
|
||||
assertEquals(hierarchy, parseCommonizerTarget(hierarchy.identityString))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `parsing CommonizerTarget`() {
|
||||
val target = parseCommonizerTarget("(x, (x, y, (a, b), (b, c)))")
|
||||
assertEquals(
|
||||
SharedCommonizerTarget(
|
||||
LeafCommonizerTarget("x"),
|
||||
SharedCommonizerTarget(
|
||||
LeafCommonizerTarget("x"),
|
||||
LeafCommonizerTarget("y"),
|
||||
SharedCommonizerTarget(
|
||||
LeafCommonizerTarget("a"),
|
||||
LeafCommonizerTarget("b"),
|
||||
),
|
||||
SharedCommonizerTarget(
|
||||
LeafCommonizerTarget("b"),
|
||||
LeafCommonizerTarget("c")
|
||||
)
|
||||
)
|
||||
),
|
||||
target
|
||||
)
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException::class)
|
||||
fun `fail parsing CommonizerTarget 1`() {
|
||||
parseCommonizerTarget("xxx,")
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException::class)
|
||||
fun `fail parsing CommonizerTarget 2`() {
|
||||
parseCommonizerTarget("")
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException::class)
|
||||
fun `fail parsing CommonizerTarget 3`() {
|
||||
parseCommonizerTarget("()")
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException::class)
|
||||
fun `fail parsing CommonizerTarget 4`() {
|
||||
parseCommonizerTarget("(xxx")
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException::class)
|
||||
fun `fail parsing CommonizerTarget 5`() {
|
||||
parseCommonizerTarget("xxx)")
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException::class)
|
||||
fun `fail parsing CommonizerTarget 6`() {
|
||||
parseCommonizerTarget("(xxx")
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException::class)
|
||||
fun `fail parsing CommonizerTarget 7`() {
|
||||
parseCommonizerTarget("(xxx yyy)")
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException::class)
|
||||
fun `fail parsing CommonizerTarget 8`() {
|
||||
parseCommonizerTarget(" ")
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException::class)
|
||||
fun `fail parsing CommonizerTarget 9`() {
|
||||
parseCommonizerTarget("xxx?")
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException::class)
|
||||
fun `fail parsing CommonizerTarget 10`() {
|
||||
parseCommonizerTarget("(x, (x, y)")
|
||||
}
|
||||
}
|
||||
+88
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* 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.descriptors.commonizer
|
||||
|
||||
import org.junit.Test
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
class CommonizerTargetPrettyNameTest {
|
||||
|
||||
@Test
|
||||
fun leafTargetNames() {
|
||||
listOf(
|
||||
Triple("foo", "[foo]", FOO),
|
||||
Triple("bar", "[bar]", BAR),
|
||||
Triple("baz_123", "[baz_123]", BAZ),
|
||||
).forEach { (name, prettyName, target: LeafCommonizerTarget) ->
|
||||
assertEquals(name, target.name)
|
||||
assertEquals(prettyName, target.prettyName)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun sharedTargetNames() {
|
||||
listOf(
|
||||
"[foo]" to SharedTarget(FOO),
|
||||
"[bar, foo]" to SharedTarget(FOO, BAR),
|
||||
"[bar, baz_123, foo]" to SharedTarget(FOO, BAR, BAZ),
|
||||
"[bar, baz_123, foo, [bar, foo]]" to SharedTarget(FOO, BAR, BAZ, SharedTarget(FOO, BAR))
|
||||
).forEach { (prettyName, target: SharedCommonizerTarget) ->
|
||||
assertEquals(prettyName, target.prettyName)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun prettyCommonizedName() {
|
||||
val sharedTarget = SharedTarget(FOO, BAR, BAZ)
|
||||
listOf(
|
||||
"[bar, baz_123, foo(*)]" to FOO,
|
||||
"[bar(*), baz_123, foo]" to BAR,
|
||||
"[bar, baz_123(*), foo]" to BAZ,
|
||||
"[bar, baz_123, foo]" to sharedTarget,
|
||||
).forEach { (prettyCommonizerName, target: CommonizerTarget) ->
|
||||
assertEquals(prettyCommonizerName, sharedTarget.prettyName(target))
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun prettyNestedName() {
|
||||
val target = parseCommonizerTarget("(a, b, (c, (d, e)))") as SharedCommonizerTarget
|
||||
|
||||
assertEquals(
|
||||
"[a, b, [c, [d, e]]]", target.prettyName
|
||||
)
|
||||
|
||||
assertEquals(
|
||||
"[a, b, [c, [d, e(*)]]]", target.prettyName(LeafCommonizerTarget("e"))
|
||||
)
|
||||
|
||||
assertEquals(
|
||||
"[a, b, [c, [d, e](*)]]", target.prettyName(parseCommonizerTarget("(d, e)"))
|
||||
)
|
||||
|
||||
assertEquals(
|
||||
"[a, b, [c, [d, e]](*)]", target.prettyName(parseCommonizerTarget("(c, (d, e))"))
|
||||
)
|
||||
|
||||
assertEquals(
|
||||
"[a, b(*), [c, [d, e]]]", target.prettyName(LeafCommonizerTarget("b"))
|
||||
)
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException::class)
|
||||
fun sharedTargetNoInnerTargets() {
|
||||
SharedCommonizerTarget(emptySet<CommonizerTarget>())
|
||||
}
|
||||
|
||||
private companion object {
|
||||
val FOO = LeafCommonizerTarget("foo")
|
||||
val BAR = LeafCommonizerTarget("bar")
|
||||
val BAZ = LeafCommonizerTarget("baz_123")
|
||||
|
||||
@Suppress("TestFunctionName")
|
||||
fun SharedTarget(vararg targets: CommonizerTarget) = SharedCommonizerTarget(linkedSetOf(*targets))
|
||||
}
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* 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.descriptors.commonizer.utils
|
||||
|
||||
import java.io.File
|
||||
|
||||
internal val konanHome: File
|
||||
get() {
|
||||
val konanHomePath = System.getenv("KONAN_HOME")?.toString() ?: error("Missing KONAN_HOME environment variable")
|
||||
return File(konanHomePath)
|
||||
}
|
||||
Reference in New Issue
Block a user