[Gradle] Don't create fat frameworks from single binary framework
KT-55751 Verification Pending
This commit is contained in:
committed by
Space Team
parent
371e1205c0
commit
427ef8fc47
+8
-104
@@ -10,7 +10,6 @@ import org.gradle.api.DefaultTask
|
|||||||
import org.gradle.api.NamedDomainObjectCollection
|
import org.gradle.api.NamedDomainObjectCollection
|
||||||
import org.gradle.api.Project
|
import org.gradle.api.Project
|
||||||
import org.gradle.api.Task
|
import org.gradle.api.Task
|
||||||
import org.gradle.api.artifacts.Configuration
|
|
||||||
import org.gradle.api.artifacts.Dependency
|
import org.gradle.api.artifacts.Dependency
|
||||||
import org.gradle.api.attributes.Attribute
|
import org.gradle.api.attributes.Attribute
|
||||||
import org.gradle.api.attributes.AttributeContainer
|
import org.gradle.api.attributes.AttributeContainer
|
||||||
@@ -24,6 +23,7 @@ import org.gradle.api.tasks.Exec
|
|||||||
import org.gradle.api.tasks.TaskProvider
|
import org.gradle.api.tasks.TaskProvider
|
||||||
import org.gradle.language.base.plugins.LifecycleBasePlugin
|
import org.gradle.language.base.plugins.LifecycleBasePlugin
|
||||||
import org.jetbrains.kotlin.gradle.dsl.KotlinNativeCompilerOptions
|
import org.jetbrains.kotlin.gradle.dsl.KotlinNativeCompilerOptions
|
||||||
|
import org.jetbrains.kotlin.gradle.dsl.multiplatformExtensionOrNull
|
||||||
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation.Companion.TEST_COMPILATION_NAME
|
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation.Companion.TEST_COMPILATION_NAME
|
||||||
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilationInfo.KPM
|
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilationInfo.KPM
|
||||||
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.Companion.KOTLIN_NATIVE_IGNORE_INCORRECT_DEPENDENCIES
|
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.Companion.KOTLIN_NATIVE_IGNORE_INCORRECT_DEPENDENCIES
|
||||||
@@ -47,12 +47,9 @@ import org.jetbrains.kotlin.gradle.testing.internal.kotlinTestRegistry
|
|||||||
import org.jetbrains.kotlin.gradle.testing.testTaskName
|
import org.jetbrains.kotlin.gradle.testing.testTaskName
|
||||||
import org.jetbrains.kotlin.gradle.utils.Xcode
|
import org.jetbrains.kotlin.gradle.utils.Xcode
|
||||||
import org.jetbrains.kotlin.gradle.utils.klibModuleName
|
import org.jetbrains.kotlin.gradle.utils.klibModuleName
|
||||||
import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName
|
|
||||||
import org.jetbrains.kotlin.gradle.utils.newInstance
|
import org.jetbrains.kotlin.gradle.utils.newInstance
|
||||||
import org.jetbrains.kotlin.konan.target.HostManager
|
import org.jetbrains.kotlin.konan.target.HostManager
|
||||||
import org.jetbrains.kotlin.konan.target.KonanTarget
|
import org.jetbrains.kotlin.konan.target.KonanTarget
|
||||||
import org.jetbrains.kotlin.util.capitalizeDecapitalize.capitalizeAsciiOnly
|
|
||||||
import org.jetbrains.kotlin.util.capitalizeDecapitalize.toLowerCaseAsciiOnly
|
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
open class KotlinNativeTargetConfigurator<T : KotlinNativeTarget> : AbstractKotlinTargetConfigurator<T>(
|
open class KotlinNativeTargetConfigurator<T : KotlinNativeTarget> : AbstractKotlinTargetConfigurator<T>(
|
||||||
@@ -66,7 +63,7 @@ open class KotlinNativeTargetConfigurator<T : KotlinNativeTarget> : AbstractKotl
|
|||||||
// this afterEvaluate comes from NativeCompilerOptions
|
// this afterEvaluate comes from NativeCompilerOptions
|
||||||
val compilationCompilerOptions = binary.compilation.compilerOptions
|
val compilationCompilerOptions = binary.compilation.compilerOptions
|
||||||
val konanPropertiesBuildService = KonanPropertiesBuildService.registerIfAbsent(project)
|
val konanPropertiesBuildService = KonanPropertiesBuildService.registerIfAbsent(project)
|
||||||
val result = registerTask<KotlinNativeLink>(
|
val linkTask = registerTask<KotlinNativeLink>(
|
||||||
binary.linkTaskName, listOf(binary)
|
binary.linkTaskName, listOf(binary)
|
||||||
) {
|
) {
|
||||||
val target = binary.target
|
val target = binary.target
|
||||||
@@ -81,12 +78,12 @@ open class KotlinNativeTargetConfigurator<T : KotlinNativeTarget> : AbstractKotl
|
|||||||
|
|
||||||
|
|
||||||
if (binary !is TestExecutable) {
|
if (binary !is TestExecutable) {
|
||||||
tasks.named(binary.compilation.target.artifactsTaskName).dependsOn(result)
|
tasks.named(binary.compilation.target.artifactsTaskName).dependsOn(linkTask)
|
||||||
locateOrRegisterTask<Task>(LifecycleBasePlugin.ASSEMBLE_TASK_NAME).dependsOn(result)
|
locateOrRegisterTask<Task>(LifecycleBasePlugin.ASSEMBLE_TASK_NAME).dependsOn(linkTask)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (binary is Framework) {
|
if (binary is Framework) {
|
||||||
createFrameworkArtifact(binary, result)
|
createFrameworkArtifact(binary, linkTask)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -102,102 +99,6 @@ open class KotlinNativeTargetConfigurator<T : KotlinNativeTarget> : AbstractKotl
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun Project.createFrameworkArtifact(
|
|
||||||
binary: Framework,
|
|
||||||
linkTask: TaskProvider<KotlinNativeLink>
|
|
||||||
) {
|
|
||||||
fun <T : Task> Configuration.configureConfiguration(taskProvider: TaskProvider<T>) {
|
|
||||||
project.afterEvaluate {
|
|
||||||
val task = taskProvider.get()
|
|
||||||
val artifactFile = when (task) {
|
|
||||||
is FatFrameworkTask -> task.fatFramework
|
|
||||||
else -> binary.outputFile
|
|
||||||
}
|
|
||||||
val linkArtifact = project.artifacts.add(name, artifactFile) { artifact ->
|
|
||||||
artifact.name = name
|
|
||||||
artifact.extension = "framework"
|
|
||||||
artifact.type = "binary"
|
|
||||||
artifact.classifier = "framework"
|
|
||||||
artifact.builtBy(task)
|
|
||||||
}
|
|
||||||
project.extensions.getByType(org.gradle.api.internal.plugins.DefaultArtifactPublicationSet::class.java)
|
|
||||||
.addCandidate(linkArtifact)
|
|
||||||
artifacts.add(linkArtifact)
|
|
||||||
attributes.attribute(KotlinPlatformType.attribute, binary.target.platformType)
|
|
||||||
attributes.attribute(
|
|
||||||
project.artifactTypeAttribute,
|
|
||||||
NativeArtifactFormat.FRAMEWORK
|
|
||||||
)
|
|
||||||
attributes.attribute(
|
|
||||||
KotlinNativeTarget.kotlinNativeBuildTypeAttribute,
|
|
||||||
binary.buildType.name
|
|
||||||
)
|
|
||||||
if (attributes.getAttribute(Framework.frameworkTargets) == null) {
|
|
||||||
attributes.attribute(
|
|
||||||
Framework.frameworkTargets,
|
|
||||||
setOf(binary.target.konanTarget.name)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
// capture type parameter T
|
|
||||||
fun <T> copyAttribute(key: Attribute<T>, from: AttributeContainer, to: AttributeContainer) {
|
|
||||||
to.attribute(key, from.getAttribute(key)!!)
|
|
||||||
}
|
|
||||||
binary.attributes.keySet().filter { it != KotlinNativeTarget.konanTargetAttribute }.forEach {
|
|
||||||
copyAttribute(it, binary.attributes, this.attributes)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun configureFatFramework() {
|
|
||||||
val fatFrameworkConfigurationName = lowerCamelCaseName(
|
|
||||||
binary.name,
|
|
||||||
binary.target.konanTarget.family.name.toLowerCaseAsciiOnly(),
|
|
||||||
"fat"
|
|
||||||
)
|
|
||||||
val fatFrameworkTaskName = "link${fatFrameworkConfigurationName.capitalizeAsciiOnly()}"
|
|
||||||
|
|
||||||
val fatFrameworkTask = if (fatFrameworkTaskName in tasks.names) {
|
|
||||||
tasks.named(fatFrameworkTaskName, FatFrameworkTask::class.java)
|
|
||||||
} else {
|
|
||||||
tasks.register(fatFrameworkTaskName, FatFrameworkTask::class.java) {
|
|
||||||
it.baseName = binary.baseName
|
|
||||||
it.destinationDir = it.destinationDir.resolve(binary.buildType.name.toLowerCaseAsciiOnly())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fatFrameworkTask.configure {
|
|
||||||
try {
|
|
||||||
it.from(binary)
|
|
||||||
} catch (e: Exception) {
|
|
||||||
logger.warn("Cannot add binary ${binary.name} dependency to default fat framework", e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// maybeCreate is not used as it does not provide way to configure once
|
|
||||||
val fatConfiguration =
|
|
||||||
configurations.findByName(fatFrameworkConfigurationName) ?: configurations.create(fatFrameworkConfigurationName) {
|
|
||||||
it.isCanBeConsumed = true
|
|
||||||
it.isCanBeResolved = false
|
|
||||||
it.configureConfiguration(fatFrameworkTask)
|
|
||||||
}
|
|
||||||
|
|
||||||
fatConfiguration.attributes.attribute(
|
|
||||||
Framework.frameworkTargets,
|
|
||||||
(fatConfiguration.attributes.getAttribute(Framework.frameworkTargets) ?: setOf<String>()) + binary.target.konanTarget.name
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
configurations.create(lowerCamelCaseName(binary.name, binary.target.name)) {
|
|
||||||
it.isCanBeConsumed = true
|
|
||||||
it.isCanBeResolved = false
|
|
||||||
it.configureConfiguration(linkTask)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (FatFrameworkTask.isSupportedTarget(binary.target)) {
|
|
||||||
configureFatFramework()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun Project.createRunTask(binary: Executable) {
|
private fun Project.createRunTask(binary: Executable) {
|
||||||
val taskName = binary.runTaskName ?: return
|
val taskName = binary.runTaskName ?: return
|
||||||
registerTask<Exec>(taskName) { exec ->
|
registerTask<Exec>(taskName) { exec ->
|
||||||
@@ -337,6 +238,9 @@ open class KotlinNativeTargetConfigurator<T : KotlinNativeTarget> : AbstractKotl
|
|||||||
target.binaries.all {
|
target.binaries.all {
|
||||||
project.createLinkTask(it)
|
project.createLinkTask(it)
|
||||||
}
|
}
|
||||||
|
project.runOnceAfterEvaluated("Create fat frameworks") {
|
||||||
|
project.multiplatformExtensionOrNull?.createFatFrameworks()
|
||||||
|
}
|
||||||
project.runOnceAfterEvaluated("Sync language settings for NativeLinkTask") {
|
project.runOnceAfterEvaluated("Sync language settings for NativeLinkTask") {
|
||||||
target.binaries.all { binary ->
|
target.binaries.all { binary ->
|
||||||
project.syncLanguageSettingsToLinkTask(binary)
|
project.syncLanguageSettingsToLinkTask(binary)
|
||||||
|
|||||||
+121
@@ -0,0 +1,121 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2023 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.gradle.targets.native
|
||||||
|
|
||||||
|
import org.gradle.api.Project
|
||||||
|
import org.gradle.api.artifacts.Configuration
|
||||||
|
import org.gradle.api.provider.Provider
|
||||||
|
import org.gradle.api.tasks.TaskProvider
|
||||||
|
import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.KotlinNativeTargetConfigurator
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.internal.artifactTypeAttribute
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.mpp.Framework
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.mpp.NativeBuildType
|
||||||
|
import org.jetbrains.kotlin.gradle.tasks.FatFrameworkTask
|
||||||
|
import org.jetbrains.kotlin.gradle.tasks.KotlinNativeLink
|
||||||
|
import org.jetbrains.kotlin.gradle.utils.getOrCreate
|
||||||
|
import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName
|
||||||
|
import org.jetbrains.kotlin.gradle.utils.markConsumable
|
||||||
|
import org.jetbrains.kotlin.util.capitalizeDecapitalize.capitalizeAsciiOnly
|
||||||
|
import org.jetbrains.kotlin.util.capitalizeDecapitalize.toLowerCaseAsciiOnly
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Contains common data between frameworks that can be bundled to a fat framework.
|
||||||
|
*/
|
||||||
|
private data class FrameworkGroupDescription(
|
||||||
|
val frameworkName: String,
|
||||||
|
val targetFamilyName: String,
|
||||||
|
val baseName: String,
|
||||||
|
val buildType: NativeBuildType
|
||||||
|
)
|
||||||
|
|
||||||
|
private val Framework.frameworkGroupDescription
|
||||||
|
get() = FrameworkGroupDescription(
|
||||||
|
frameworkName = name,
|
||||||
|
targetFamilyName = target.konanTarget.family.name.toLowerCaseAsciiOnly(),
|
||||||
|
baseName = baseName,
|
||||||
|
buildType = buildType
|
||||||
|
)
|
||||||
|
|
||||||
|
internal fun Project.createFrameworkArtifact(binaryFramework: Framework, linkTask: TaskProvider<KotlinNativeLink>) {
|
||||||
|
val frameworkConfiguration = configurations.getOrCreate(binaryFramework.binaryFrameworkConfigurationName, invokeWhenCreated = {
|
||||||
|
it.markConsumable()
|
||||||
|
it.applyBinaryFrameworkAttributes(project, binaryFramework.frameworkGroupDescription, listOf(binaryFramework.target))
|
||||||
|
})
|
||||||
|
|
||||||
|
addFrameworkArtifact(frameworkConfiguration, linkTask.flatMap { it.outputFile })
|
||||||
|
}
|
||||||
|
|
||||||
|
internal fun KotlinMultiplatformExtension.createFatFrameworks() {
|
||||||
|
targets
|
||||||
|
.filterIsInstance<KotlinNativeTarget>()
|
||||||
|
.filter { FatFrameworkTask.isSupportedTarget(it) }
|
||||||
|
.flatMap { it.binaries }
|
||||||
|
.filterIsInstance<Framework>()
|
||||||
|
.groupBy { it.frameworkGroupDescription }
|
||||||
|
.filter { (_, frameworks) -> frameworks.size > 1 }
|
||||||
|
.forEach { (groupDescription, frameworks) -> project.createFatFramework(groupDescription, frameworks) }
|
||||||
|
}
|
||||||
|
|
||||||
|
private val Framework.binaryFrameworkConfigurationName get() = lowerCamelCaseName(name, target.name)
|
||||||
|
private val FrameworkGroupDescription.fatFrameworkConfigurationName get() = lowerCamelCaseName(frameworkName, targetFamilyName, "fat")
|
||||||
|
|
||||||
|
private fun Configuration.applyBinaryFrameworkAttributes(
|
||||||
|
project: Project,
|
||||||
|
frameworkDescription: FrameworkGroupDescription,
|
||||||
|
targets: List<KotlinNativeTarget>
|
||||||
|
) {
|
||||||
|
with(attributes) {
|
||||||
|
attribute(KotlinPlatformType.attribute, KotlinPlatformType.native)
|
||||||
|
attribute(project.artifactTypeAttribute, KotlinNativeTargetConfigurator.NativeArtifactFormat.FRAMEWORK)
|
||||||
|
attribute(KotlinNativeTarget.kotlinNativeBuildTypeAttribute, frameworkDescription.buildType.name)
|
||||||
|
attribute(Framework.frameworkTargets, targets.map { it.konanTarget.name }.toSet())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun Project.addFrameworkArtifact(configuration: Configuration, artifactFile: Provider<File>) {
|
||||||
|
val frameworkArtifact = artifacts.add(configuration.name, artifactFile) { artifact ->
|
||||||
|
artifact.name = name
|
||||||
|
artifact.extension = "framework"
|
||||||
|
artifact.type = "binary"
|
||||||
|
artifact.classifier = "framework"
|
||||||
|
}
|
||||||
|
project.extensions.getByType(org.gradle.api.internal.plugins.DefaultArtifactPublicationSet::class.java)
|
||||||
|
.addCandidate(frameworkArtifact)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun Project.createFatFramework(groupDescription: FrameworkGroupDescription, frameworks: List<Framework>) {
|
||||||
|
require(frameworks.size > 1) { "Can't create binary fat framework from a single framework" }
|
||||||
|
val fatFrameworkConfigurationName = groupDescription.fatFrameworkConfigurationName
|
||||||
|
val fatFrameworkTaskName = "link${fatFrameworkConfigurationName.capitalizeAsciiOnly()}"
|
||||||
|
|
||||||
|
val fatFrameworkTask = if (fatFrameworkTaskName in tasks.names) {
|
||||||
|
tasks.named(fatFrameworkTaskName, FatFrameworkTask::class.java)
|
||||||
|
} else {
|
||||||
|
tasks.register(fatFrameworkTaskName, FatFrameworkTask::class.java) {
|
||||||
|
it.baseName = groupDescription.baseName
|
||||||
|
it.destinationDir = it.destinationDir.resolve(groupDescription.buildType.name.toLowerCaseAsciiOnly())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fatFrameworkTask.configure {
|
||||||
|
try {
|
||||||
|
it.from(frameworks)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
logger.warn("Cannot make fat framework from frameworks: ${frameworks.map { it.name }}", e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val fatFrameworkConfiguration = project.configurations.getOrCreate(fatFrameworkConfigurationName, invokeWhenCreated = {
|
||||||
|
it.markConsumable()
|
||||||
|
it.applyBinaryFrameworkAttributes(project, groupDescription, targets = frameworks.map(Framework::target))
|
||||||
|
})
|
||||||
|
|
||||||
|
addFrameworkArtifact(fatFrameworkConfiguration, fatFrameworkTask.map { it.fatFramework })
|
||||||
|
}
|
||||||
+93
@@ -0,0 +1,93 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2023 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.gradle.unitTests
|
||||||
|
|
||||||
|
import org.gradle.api.Project
|
||||||
|
import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
|
||||||
|
import org.jetbrains.kotlin.gradle.util.buildProjectWithMPP
|
||||||
|
import org.jetbrains.kotlin.gradle.util.kotlin
|
||||||
|
import kotlin.test.*
|
||||||
|
|
||||||
|
class FatFrameworksTest {
|
||||||
|
@Test
|
||||||
|
fun `two apple frameworks get bundled to a fat framework`() {
|
||||||
|
val project = buildProjectWithMPP {
|
||||||
|
kotlin {
|
||||||
|
iosX64 { binaries.framework("foo", listOf(DEBUG)) }
|
||||||
|
iosArm64 { binaries.framework("foo", listOf(DEBUG)) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
project.evaluate()
|
||||||
|
project.configurations.names.also(::println)
|
||||||
|
project.assertConfigurationExists("fooDebugFrameworkIosX64")
|
||||||
|
project.assertConfigurationExists("fooDebugFrameworkIosArm64")
|
||||||
|
project.assertConfigurationExists("fooDebugFrameworkIosFat")
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `single binary framework doesn't produce a fat framework`() {
|
||||||
|
val project = buildProjectWithMPP {
|
||||||
|
kotlin {
|
||||||
|
iosX64 { binaries.framework("foo", listOf(DEBUG)) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
project.evaluate()
|
||||||
|
project.assertConfigurationExists("fooDebugFrameworkIosX64")
|
||||||
|
project.assertConfigurationDoesntExist("fooDebugFrameworkIosFat")
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `fat framework grouping -- different families`() = testFatFrameworkGrouping(
|
||||||
|
"fooDebugFrameworkIosFat",
|
||||||
|
"fooDebugFrameworkOsxFat",
|
||||||
|
) {
|
||||||
|
iosX64 { binaries.framework("foo", listOf(DEBUG)) }
|
||||||
|
iosArm64 { binaries.framework("foo", listOf(DEBUG)) }
|
||||||
|
macosX64 { binaries.framework("foo", listOf(DEBUG)) }
|
||||||
|
macosArm64 { binaries.framework("foo", listOf(DEBUG)) }
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `fat framework grouping -- different families and different names within one family`() = testFatFrameworkGrouping(
|
||||||
|
"fooDebugFrameworkOsxFat",
|
||||||
|
) {
|
||||||
|
iosX64 { binaries.framework("foo", listOf(DEBUG)) }
|
||||||
|
iosArm64 { binaries.framework("bar", listOf(DEBUG)) }
|
||||||
|
macosX64 { binaries.framework("foo", listOf(DEBUG)) }
|
||||||
|
macosArm64 { binaries.framework("foo", listOf(DEBUG)) }
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `fat framework grouping -- build types intersection`() = testFatFrameworkGrouping(
|
||||||
|
"fooReleaseFrameworkIosFat",
|
||||||
|
) {
|
||||||
|
iosX64 { binaries.framework("foo", listOf(RELEASE)) }
|
||||||
|
iosArm64 { binaries.framework("foo", listOf(DEBUG, RELEASE)) }
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun testFatFrameworkGrouping(
|
||||||
|
vararg allExpectedFatFrameworks: String,
|
||||||
|
configureTargets: KotlinMultiplatformExtension.() -> Unit,
|
||||||
|
) {
|
||||||
|
val project = buildProjectWithMPP {
|
||||||
|
kotlin {
|
||||||
|
configureTargets()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
project.evaluate()
|
||||||
|
val allFatFrameworks = project.configurations.names.filter { it.endsWith("Fat") }.toSet()
|
||||||
|
assertEquals(allExpectedFatFrameworks.toSet(), allFatFrameworks)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun Project.assertConfigurationDoesntExist(name: String) {
|
||||||
|
val configuration = project.configurations.findByName(name)
|
||||||
|
if (configuration != null) fail("'$name' configuration was not expected")
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun Project.assertConfigurationExists(name: String) {
|
||||||
|
project.configurations.findByName(name) ?: fail("'$name' configuration was expected to be created")
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user