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 = { spec.pod_target_xcconfig = {
'KOTLIN_TARGET[sdk=iphonesimulator*]' => 'ios_x64', 'KOTLIN_TARGET[sdk=iphonesimulator*]' => 'ios_x64',
'KOTLIN_TARGET[sdk=iphoneos*]' => 'ios_arm', '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' '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.tasks.*
import org.jetbrains.kotlin.gradle.utils.asValidTaskName import org.jetbrains.kotlin.gradle.utils.asValidTaskName
import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName 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.HostManager
import org.jetbrains.kotlin.konan.target.KonanTarget import org.jetbrains.kotlin.konan.target.KonanTarget
import java.io.File import java.io.File
@@ -88,7 +87,10 @@ open class KotlinCocoapodsPlugin: Plugin<Project> {
) { ) {
val fatTargets = requestedPlatforms.associate { it to kotlinExtension.targetsForPlatform(it) } 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 -> fatTargets.forEach { platform, targets ->
check(targets.size <= 1) { check(targets.size <= 1) {
"The project has more than one target for the requested platform: `${platform.visibleName}`" "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 requestedTargetName = project.findProperty(TARGET_PROPERTY)?.toString() ?: return@whenEvaluated
val requestedBuildType = project.findProperty(CONFIGURATION_PROPERTY)?.toString()?.toUpperCase() ?: 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 which have several
// We create a fat framework only for device platforms: iosArm64, iosArm32, watchosArm32, watchosArm64 and tvosArm64. // device architectures: iosArm64, iosArm32, watchosArm32 and watchosArm64.
val devicePlatforms = listOf( val frameworkPlatforms: List<KonanTarget> = when (requestedTargetName) {
KonanTarget.IOS_ARM64, KOTLIN_TARGET_FOR_IOS_DEVICE -> listOf(KonanTarget.IOS_ARM64, KonanTarget.IOS_ARM32)
KonanTarget.IOS_ARM32, KOTLIN_TARGET_FOR_WATCHOS_DEVICE -> listOf(KonanTarget.WATCHOS_ARM32, KonanTarget.WATCHOS_ARM64)
KonanTarget.WATCHOS_ARM32, else -> listOf(HostManager().targetByName(requestedTargetName)) // A requested target doesn't require building a fat framework.
KonanTarget.WATCHOS_ARM64, }
KonanTarget.TVOS_ARM64
)
val deviceTargets = devicePlatforms.flatMap { kotlinExtension.targetsForPlatform(it) }
if (deviceTargets.size == 1) { val frameworkTargets = frameworkPlatforms.flatMap { kotlinExtension.targetsForPlatform(it) }
// Fast path: there is only one device target. There is no need to build a fat framework. if (frameworkTargets.size == 1) {
createSyncForRegularFramework(project, kotlinExtension, requestedBuildType, deviceTargets.single().konanTarget) // Fast path: there is only one device target. There is no need to build a fat framework.
} else { createSyncForRegularFramework(project, kotlinExtension, requestedBuildType, frameworkTargets.single().konanTarget)
// There are several device targets so we need to build a fat framework.
createSyncForFatFramework(project, kotlinExtension, requestedBuildType, devicePlatforms)
}
} else { } else {
// A requested target doesn't require building a fat framework. // There are several device targets so we need to build a fat framework.
createSyncForRegularFramework(project, kotlinExtension, requestedBuildType, HostManager().targetByName(requestedTargetName)) 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 // 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. // 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.CocoapodsExtension
import org.jetbrains.kotlin.gradle.plugin.cocoapods.KotlinCocoapodsPlugin 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.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.KotlinCocoapodsPlugin.Companion.SYNC_TASK_NAME
import org.jetbrains.kotlin.gradle.plugin.cocoapods.asValidFrameworkName import org.jetbrains.kotlin.gradle.plugin.cocoapods.asValidFrameworkName
import org.jetbrains.kotlin.gradle.plugin.cocoapods.cocoapodsBuildDirs import org.jetbrains.kotlin.gradle.plugin.cocoapods.cocoapodsBuildDirs
@@ -75,7 +76,11 @@ open class PodspecTask : DefaultTask() {
| |
| spec.pod_target_xcconfig = { | spec.pod_target_xcconfig = {
| 'KOTLIN_TARGET[sdk=iphonesimulator*]' => 'ios_x64', | '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' | 'KOTLIN_TARGET[sdk=macosx*]' => 'macos_x64'
| } | }
| |