Gradle, native: Support watchOS and tvOS in CocoaPods plugin

Issue #KT-34329 fixed
This commit is contained in:
Ilya Matveev
2019-10-16 13:57:25 +03:00
parent 4df4c58a05
commit 3a234d46ed
3 changed files with 30 additions and 25 deletions
@@ -62,6 +62,10 @@ class CocoaPodsIT : BaseGradleIT() {
spec.pod_target_xcconfig = {
'KOTLIN_TARGET[sdk=iphonesimulator*]' => 'ios_x64',
'KOTLIN_TARGET[sdk=iphoneos*]' => 'ios_arm',
'KOTLIN_TARGET[sdk=watchsimulator*]' => 'watchos_x86',
'KOTLIN_TARGET[sdk=watchos*]' => 'watchos_arm',
'KOTLIN_TARGET[sdk=appletvsimulator*]' => 'tvos_x64',
'KOTLIN_TARGET[sdk=appletvos*]' => 'tvos_arm64',
'KOTLIN_TARGET[sdk=macosx*]' => 'macos_x64'
}
@@ -19,7 +19,6 @@ import org.jetbrains.kotlin.gradle.plugin.whenEvaluated
import org.jetbrains.kotlin.gradle.tasks.*
import org.jetbrains.kotlin.gradle.utils.asValidTaskName
import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName
import org.jetbrains.kotlin.konan.target.Family
import org.jetbrains.kotlin.konan.target.HostManager
import org.jetbrains.kotlin.konan.target.KonanTarget
import java.io.File
@@ -88,7 +87,10 @@ open class KotlinCocoapodsPlugin: Plugin<Project> {
) {
val fatTargets = requestedPlatforms.associate { it to kotlinExtension.targetsForPlatform(it) }
check(fatTargets.values.any { it.isNotEmpty() }) { "The project doesn't contain a target for iOS device" }
check(fatTargets.values.any { it.isNotEmpty() }) {
"The project must have a target for at least one of the following platforms: " +
"${requestedPlatforms.joinToString { it.visibleName }}."
}
fatTargets.forEach { platform, targets ->
check(targets.size <= 1) {
"The project has more than one target for the requested platform: `${platform.visibleName}`"
@@ -132,27 +134,21 @@ open class KotlinCocoapodsPlugin: Plugin<Project> {
val requestedTargetName = project.findProperty(TARGET_PROPERTY)?.toString() ?: return@whenEvaluated
val requestedBuildType = project.findProperty(CONFIGURATION_PROPERTY)?.toString()?.toUpperCase() ?: return@whenEvaluated
if (requestedTargetName == KOTLIN_TARGET_FOR_DEVICE) {
// We create a fat framework only for device platforms: iosArm64, iosArm32, watchosArm32, watchosArm64 and tvosArm64.
val devicePlatforms = listOf(
KonanTarget.IOS_ARM64,
KonanTarget.IOS_ARM32,
KonanTarget.WATCHOS_ARM32,
KonanTarget.WATCHOS_ARM64,
KonanTarget.TVOS_ARM64
)
val deviceTargets = devicePlatforms.flatMap { kotlinExtension.targetsForPlatform(it) }
// We create a fat framework only for device platforms which have several
// device architectures: iosArm64, iosArm32, watchosArm32 and watchosArm64.
val frameworkPlatforms: List<KonanTarget> = when (requestedTargetName) {
KOTLIN_TARGET_FOR_IOS_DEVICE -> listOf(KonanTarget.IOS_ARM64, KonanTarget.IOS_ARM32)
KOTLIN_TARGET_FOR_WATCHOS_DEVICE -> listOf(KonanTarget.WATCHOS_ARM32, KonanTarget.WATCHOS_ARM64)
else -> listOf(HostManager().targetByName(requestedTargetName)) // A requested target doesn't require building a fat framework.
}
if (deviceTargets.size == 1) {
// Fast path: there is only one device target. There is no need to build a fat framework.
createSyncForRegularFramework(project, kotlinExtension, requestedBuildType, deviceTargets.single().konanTarget)
} else {
// There are several device targets so we need to build a fat framework.
createSyncForFatFramework(project, kotlinExtension, requestedBuildType, devicePlatforms)
}
val frameworkTargets = frameworkPlatforms.flatMap { kotlinExtension.targetsForPlatform(it) }
if (frameworkTargets.size == 1) {
// Fast path: there is only one device target. There is no need to build a fat framework.
createSyncForRegularFramework(project, kotlinExtension, requestedBuildType, frameworkTargets.single().konanTarget)
} else {
// A requested target doesn't require building a fat framework.
createSyncForRegularFramework(project, kotlinExtension, requestedBuildType, HostManager().targetByName(requestedTargetName))
// There are several device targets so we need to build a fat framework.
createSyncForFatFramework(project, kotlinExtension, requestedBuildType, frameworkPlatforms)
}
}
@@ -266,7 +262,7 @@ open class KotlinCocoapodsPlugin: Plugin<Project> {
// Used in Xcode script phase to indicate that the framework is being built for a device
// so we should generate a fat framework with arm32 and arm64 binaries.
const val KOTLIN_TARGET_FOR_DEVICE = "ios_arm"
const val KOTLIN_TARGET_FOR_IOS_DEVICE = "ios_arm"
const val KOTLIN_TARGET_FOR_WATCHOS_DEVICE = "watchos_arm"
}
}
@@ -12,7 +12,8 @@ import org.gradle.api.tasks.wrapper.Wrapper
import org.jetbrains.kotlin.gradle.plugin.cocoapods.CocoapodsExtension
import org.jetbrains.kotlin.gradle.plugin.cocoapods.KotlinCocoapodsPlugin
import org.jetbrains.kotlin.gradle.plugin.cocoapods.KotlinCocoapodsPlugin.Companion.GENERATE_WRAPPER_PROPERTY
import org.jetbrains.kotlin.gradle.plugin.cocoapods.KotlinCocoapodsPlugin.Companion.KOTLIN_TARGET_FOR_DEVICE
import org.jetbrains.kotlin.gradle.plugin.cocoapods.KotlinCocoapodsPlugin.Companion.KOTLIN_TARGET_FOR_IOS_DEVICE
import org.jetbrains.kotlin.gradle.plugin.cocoapods.KotlinCocoapodsPlugin.Companion.KOTLIN_TARGET_FOR_WATCHOS_DEVICE
import org.jetbrains.kotlin.gradle.plugin.cocoapods.KotlinCocoapodsPlugin.Companion.SYNC_TASK_NAME
import org.jetbrains.kotlin.gradle.plugin.cocoapods.asValidFrameworkName
import org.jetbrains.kotlin.gradle.plugin.cocoapods.cocoapodsBuildDirs
@@ -75,7 +76,11 @@ open class PodspecTask : DefaultTask() {
|
| spec.pod_target_xcconfig = {
| 'KOTLIN_TARGET[sdk=iphonesimulator*]' => 'ios_x64',
| 'KOTLIN_TARGET[sdk=iphoneos*]' => '$KOTLIN_TARGET_FOR_DEVICE',
| 'KOTLIN_TARGET[sdk=iphoneos*]' => '$KOTLIN_TARGET_FOR_IOS_DEVICE',
| 'KOTLIN_TARGET[sdk=watchsimulator*]' => 'watchos_x86',
| 'KOTLIN_TARGET[sdk=watchos*]' => '$KOTLIN_TARGET_FOR_WATCHOS_DEVICE',
| 'KOTLIN_TARGET[sdk=appletvsimulator*]' => 'tvos_x64',
| 'KOTLIN_TARGET[sdk=appletvos*]' => 'tvos_arm64',
| 'KOTLIN_TARGET[sdk=macosx*]' => 'macos_x64'
| }
|