Custom name support for fat frameworks
#KT-30805
This commit is contained in:
committed by
Space
parent
ce107d06d4
commit
0b6d2cd21a
+49
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.gradle.native
|
|||||||
import org.jetbrains.kotlin.gradle.BaseGradleIT
|
import org.jetbrains.kotlin.gradle.BaseGradleIT
|
||||||
import org.jetbrains.kotlin.gradle.GradleVersionRequired
|
import org.jetbrains.kotlin.gradle.GradleVersionRequired
|
||||||
import org.jetbrains.kotlin.gradle.transformProjectWithPluginsDsl
|
import org.jetbrains.kotlin.gradle.transformProjectWithPluginsDsl
|
||||||
|
import org.jetbrains.kotlin.gradle.util.addBeforeSubstring
|
||||||
import org.jetbrains.kotlin.gradle.util.checkedReplace
|
import org.jetbrains.kotlin.gradle.util.checkedReplace
|
||||||
import org.jetbrains.kotlin.gradle.util.modify
|
import org.jetbrains.kotlin.gradle.util.modify
|
||||||
import org.jetbrains.kotlin.gradle.util.runProcess
|
import org.jetbrains.kotlin.gradle.util.runProcess
|
||||||
@@ -146,6 +147,54 @@ class FatFrameworkIT : BaseGradleIT() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testCustomName() {
|
||||||
|
with(transformProjectWithPluginsDsl("smoke", directoryPrefix = "native-fat-framework")) {
|
||||||
|
gradleBuildScript().modify {
|
||||||
|
it.addBeforeSubstring("baseName = \"custom\"\n","from(frameworksToMerge)")
|
||||||
|
}
|
||||||
|
|
||||||
|
build("fat") {
|
||||||
|
val binary = fileInWorkingDir("build/fat-framework/custom.framework/custom")
|
||||||
|
with(runProcess(listOf("otool", "-D", binary.absolutePath), project.projectDir)) {
|
||||||
|
assertSuccessful()
|
||||||
|
assertTrue { output.lines().any { it.contains("@rpath/custom.framework/custom") } }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testDifferentTypes() {
|
||||||
|
with(transformProjectWithPluginsDsl("smoke", directoryPrefix = "native-fat-framework")) {
|
||||||
|
gradleBuildScript().modify {
|
||||||
|
it.checkedReplace("iosArm32()", "iosArm32{binaries.framework {isStatic = true}}")
|
||||||
|
.checkedReplace("iosArm64()", "iosArm64{binaries.framework {isStatic = false}}")
|
||||||
|
.checkedReplace("iosX64()", "iosX64{binaries.framework {isStatic = false}}")
|
||||||
|
.addBeforeSubstring("//", "binaries.framework(listOf(DEBUG))")
|
||||||
|
}
|
||||||
|
build("fat") {
|
||||||
|
assertFailed()
|
||||||
|
assertContains("All input frameworks must be either static or dynamic")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testAllStatic() {
|
||||||
|
with(transformProjectWithPluginsDsl("smoke", directoryPrefix = "native-fat-framework")) {
|
||||||
|
gradleBuildScript().modify {
|
||||||
|
it.checkedReplace("iosArm32()", "iosArm32{binaries.framework {isStatic = true}}")
|
||||||
|
.checkedReplace("iosArm64()", "iosArm64{binaries.framework {isStatic = true}}")
|
||||||
|
.checkedReplace("iosX64()", "iosX64{binaries.framework {isStatic = true}}")
|
||||||
|
.addBeforeSubstring("//", "binaries.framework(listOf(DEBUG))")
|
||||||
|
}
|
||||||
|
build("fat") {
|
||||||
|
assertSuccessful()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@BeforeClass
|
@BeforeClass
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
|
|||||||
+35
-6
@@ -134,9 +134,9 @@ open class FatFrameworkTask : DefaultTask() {
|
|||||||
* Adds the specified frameworks in this fat framework.
|
* Adds the specified frameworks in this fat framework.
|
||||||
*/
|
*/
|
||||||
fun from(frameworks: Iterable<Framework>) {
|
fun from(frameworks: Iterable<Framework>) {
|
||||||
frameworks.forEach {
|
frameworks.forEach { framework ->
|
||||||
val arch = it.konanTarget.architecture
|
val arch = framework.konanTarget.architecture
|
||||||
val family = it.konanTarget.family
|
val family = framework.konanTarget.family
|
||||||
val fatFrameworkFamily = getFatFrameworkFamily()
|
val fatFrameworkFamily = getFatFrameworkFamily()
|
||||||
require(fatFrameworkFamily == null || family == fatFrameworkFamily) {
|
require(fatFrameworkFamily == null || family == fatFrameworkFamily) {
|
||||||
"Cannot add a binary with platform family '${family.visibleName}' to the fat framework:\n" +
|
"Cannot add a binary with platform family '${family.visibleName}' to the fat framework:\n" +
|
||||||
@@ -149,8 +149,20 @@ open class FatFrameworkTask : DefaultTask() {
|
|||||||
"This fat framework already has a binary for architecture `${arch.name.toLowerCase()}` " +
|
"This fat framework already has a binary for architecture `${arch.name.toLowerCase()}` " +
|
||||||
"(${alreadyAdded.name} for target `${alreadyAdded.target.name}`)"
|
"(${alreadyAdded.name} for target `${alreadyAdded.target.name}`)"
|
||||||
}
|
}
|
||||||
archToFramework[arch] = it
|
|
||||||
dependsOn(it.linkTask)
|
require(archToFramework.all { it.value.isStatic == framework.isStatic }) {
|
||||||
|
fun Framework.staticOrDynamic(): String = if (isStatic) "static" else "dynamic"
|
||||||
|
|
||||||
|
buildString {
|
||||||
|
append("Cannot create a fat framework from:\n")
|
||||||
|
archToFramework.forEach { append("${it.value.baseName} - ${it.key.name.toLowerCase()} - ${it.value.staticOrDynamic()}\n") }
|
||||||
|
append("${framework.baseName} - ${arch.name.toLowerCase()} - ${framework.staticOrDynamic()}\n")
|
||||||
|
append("All input frameworks must be either static or dynamic")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
archToFramework[arch] = framework
|
||||||
|
dependsOn(framework.linkTask)
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -218,9 +230,26 @@ open class FatFrameworkTask : DefaultTask() {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun mergeBinaries(outputFile: File) =
|
private fun runInstallNameTool(file: File, frameworkName: String) {
|
||||||
|
project.exec { exec ->
|
||||||
|
exec.executable = "install_name_tool"
|
||||||
|
exec.args = listOf(
|
||||||
|
"-id",
|
||||||
|
"@rpath/${frameworkName}.framework/${frameworkName}",
|
||||||
|
file.absolutePath
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun mergeBinaries(outputFile: File) {
|
||||||
|
|
||||||
runLipo(archToFramework.values.map { it.files.binary }, outputFile)
|
runLipo(archToFramework.values.map { it.files.binary }, outputFile)
|
||||||
|
|
||||||
|
if (archToFramework.values.any{ it.isStatic.not() && it.baseName != fatFrameworkName }) {
|
||||||
|
runInstallNameTool(outputFile, fatFrameworkName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun mergeHeaders(outputFile: File) = outputFile.writer().use { writer ->
|
private fun mergeHeaders(outputFile: File) = outputFile.writer().use { writer ->
|
||||||
|
|
||||||
val headerContents = archToFramework.mapValues { (_, framework) ->
|
val headerContents = archToFramework.mapValues { (_, framework) ->
|
||||||
|
|||||||
Reference in New Issue
Block a user