[Gradle] Add workarounds in CocoaPods plugin for compatibility with Xcode 14.3
Raise deployment target for 3rd-party pods if it's less then minimal supported by the new Xcode ^KT-57539 Verification Pending
This commit is contained in:
committed by
Space Team
parent
f7acbb5252
commit
ca0b0e61e8
+1
-1
@@ -5,7 +5,6 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.gradle.native
|
package org.jetbrains.kotlin.gradle.native
|
||||||
|
|
||||||
import org.gradle.api.logging.configuration.WarningMode
|
|
||||||
import org.jetbrains.kotlin.gradle.*
|
import org.jetbrains.kotlin.gradle.*
|
||||||
import org.jetbrains.kotlin.gradle.plugin.cocoapods.KotlinCocoapodsPlugin.Companion.DUMMY_FRAMEWORK_TASK_NAME
|
import org.jetbrains.kotlin.gradle.plugin.cocoapods.KotlinCocoapodsPlugin.Companion.DUMMY_FRAMEWORK_TASK_NAME
|
||||||
import org.jetbrains.kotlin.gradle.plugin.cocoapods.KotlinCocoapodsPlugin.Companion.POD_BUILD_TASK_NAME
|
import org.jetbrains.kotlin.gradle.plugin.cocoapods.KotlinCocoapodsPlugin.Companion.POD_BUILD_TASK_NAME
|
||||||
@@ -1742,6 +1741,7 @@ class CocoaPodsIT : BaseGradleIT() {
|
|||||||
spec.summary = 'CocoaPods test library'
|
spec.summary = 'CocoaPods test library'
|
||||||
spec.vendored_frameworks = 'build/cocoapods/framework/${frameworkName ?: "kotlin_library"}.framework'
|
spec.vendored_frameworks = 'build/cocoapods/framework/${frameworkName ?: "kotlin_library"}.framework'
|
||||||
spec.libraries = 'c++'
|
spec.libraries = 'c++'
|
||||||
|
spec.ios.deployment_target = '11.0'
|
||||||
spec.dependency 'pod_dependency', '1.0'
|
spec.dependency 'pod_dependency', '1.0'
|
||||||
spec.dependency 'subspec_dependency/Core', '1.0'
|
spec.dependency 'subspec_dependency/Core', '1.0'
|
||||||
spec.pod_target_xcconfig = {
|
spec.pod_target_xcconfig = {
|
||||||
|
|||||||
+1
-1
@@ -364,7 +364,7 @@ class GeneralNativeIT : BaseGradleIT() {
|
|||||||
frameworkPaths.forEach { assertFileExists(it) }
|
frameworkPaths.forEach { assertFileExists(it) }
|
||||||
|
|
||||||
assertTrue(fileInWorkingDir(headerPaths[0]).readText().contains("+ (int32_t)exported"))
|
assertTrue(fileInWorkingDir(headerPaths[0]).readText().contains("+ (int32_t)exported"))
|
||||||
val xcodeMajorVersion = Xcode!!.currentVersion.split(".")[0].toInt()
|
val xcodeMajorVersion = Xcode!!.currentVersion.major
|
||||||
|
|
||||||
// Check that by default release frameworks have bitcode embedded.
|
// Check that by default release frameworks have bitcode embedded.
|
||||||
withNativeCommandLineArguments(":linkMainReleaseFrameworkIos") { arguments ->
|
withNativeCommandLineArguments(":linkMainReleaseFrameworkIos") { arguments ->
|
||||||
|
|||||||
+2
-8
@@ -15,6 +15,7 @@ import org.jetbrains.kotlin.gradle.transformProjectWithPluginsDsl
|
|||||||
import org.jetbrains.kotlin.gradle.util.modify
|
import org.jetbrains.kotlin.gradle.util.modify
|
||||||
import org.jetbrains.kotlin.gradle.utils.NativeCompilerDownloader
|
import org.jetbrains.kotlin.gradle.utils.NativeCompilerDownloader
|
||||||
import org.jetbrains.kotlin.gradle.utils.Xcode
|
import org.jetbrains.kotlin.gradle.utils.Xcode
|
||||||
|
import org.jetbrains.kotlin.gradle.utils.XcodeVersion
|
||||||
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.konan.target.presetName
|
import org.jetbrains.kotlin.konan.target.presetName
|
||||||
@@ -252,15 +253,8 @@ class NativeDownloadAndPlatformLibsIT : BaseGradleIT() {
|
|||||||
Assume.assumeTrue(maven != MAVEN_CENTRAL)
|
Assume.assumeTrue(maven != MAVEN_CENTRAL)
|
||||||
|
|
||||||
if (HostManager.hostIsMac) {
|
if (HostManager.hostIsMac) {
|
||||||
val xcodeVersion = Xcode!!.currentVersion
|
|
||||||
val versionSplit = xcodeVersion.split("(\\s+|\\.|-)".toRegex())
|
|
||||||
check(versionSplit.size >= 2) {
|
|
||||||
"Unrecognised version of Xcode $xcodeVersion was split to $versionSplit"
|
|
||||||
}
|
|
||||||
val major = versionSplit[0].toInt()
|
|
||||||
val minor = versionSplit[1].toInt()
|
|
||||||
// Building platform libs require Xcode 14.1
|
// Building platform libs require Xcode 14.1
|
||||||
Assume.assumeTrue(major >= 14 && minor >= 1)
|
Assume.assumeTrue(Xcode!!.currentVersion >= XcodeVersion(14, 1))
|
||||||
}
|
}
|
||||||
|
|
||||||
with(transformNativeTestProjectWithPluginDsl("native-download-maven")) {
|
with(transformNativeTestProjectWithPluginDsl("native-download-maven")) {
|
||||||
|
|||||||
+2
@@ -22,5 +22,7 @@ kotlin {
|
|||||||
homepage = "https://github.com/JetBrains/kotlin"
|
homepage = "https://github.com/JetBrains/kotlin"
|
||||||
pod("pod_dependency", "1.0", project.file("../pod_dependency"))
|
pod("pod_dependency", "1.0", project.file("../pod_dependency"))
|
||||||
pod("subspec_dependency/Core", "1.0", project.file("../subspec_dependency"))
|
pod("subspec_dependency/Core", "1.0", project.file("../subspec_dependency"))
|
||||||
|
|
||||||
|
ios.deploymentTarget = "11.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -7,4 +7,4 @@ target 'ios-app' do
|
|||||||
pod 'subspec_dependency', :path => '../subspec_dependency'
|
pod 'subspec_dependency', :path => '../subspec_dependency'
|
||||||
pod 'kotlin_library', :path => '../kotlin-library'
|
pod 'kotlin_library', :path => '../kotlin-library'
|
||||||
#import_pod_directive
|
#import_pod_directive
|
||||||
end
|
end
|
||||||
|
|||||||
+2
@@ -24,5 +24,7 @@ kotlin {
|
|||||||
pod("pod_dependency", "1.0", project.file("../pod_dependency/pod_dependency.podspec"))
|
pod("pod_dependency", "1.0", project.file("../pod_dependency/pod_dependency.podspec"))
|
||||||
pod("subspec_dependency/Core", "1.0", project.file("../subspec_dependency"))
|
pod("subspec_dependency/Core", "1.0", project.file("../subspec_dependency"))
|
||||||
podfile = project.file("../ios-app/Podfile")
|
podfile = project.file("../ios-app/Podfile")
|
||||||
|
|
||||||
|
ios.deploymentTarget = "11.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
@@ -8,4 +8,6 @@ Pod::Spec.new do |spec|
|
|||||||
spec.summary = 'foo'
|
spec.summary = 'foo'
|
||||||
spec.source_files = 'src/*'
|
spec.source_files = 'src/*'
|
||||||
spec.public_header_files = 'src/*.h'
|
spec.public_header_files = 'src/*.h'
|
||||||
|
|
||||||
|
spec.ios.deployment_target = '11.0'
|
||||||
end
|
end
|
||||||
+2
@@ -12,4 +12,6 @@ Pod::Spec.new do |spec|
|
|||||||
core.source_files = "src/*"
|
core.source_files = "src/*"
|
||||||
core.public_header_files = "src/*.h"
|
core.public_header_files = "src/*.h"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
spec.ios.deployment_target = '11.0'
|
||||||
end
|
end
|
||||||
+1
@@ -537,6 +537,7 @@ open class KotlinCocoapodsPlugin : Plugin<Project> {
|
|||||||
task.family.set(family)
|
task.family.set(family)
|
||||||
task.platformSettings.set(platformSettings)
|
task.platformSettings.set(platformSettings)
|
||||||
task.pods.set(cocoapodsExtension.pods)
|
task.pods.set(cocoapodsExtension.pods)
|
||||||
|
task.xcodeVersion.set(Xcode?.currentVersion)
|
||||||
}
|
}
|
||||||
|
|
||||||
project.registerTask<PodInstallSyntheticTask>(family.toPodInstallSyntheticTaskName) { task ->
|
project.registerTask<PodInstallSyntheticTask>(family.toPodInstallSyntheticTaskName) { task ->
|
||||||
|
|||||||
+56
-17
@@ -14,6 +14,7 @@ import org.gradle.api.tasks.*
|
|||||||
import org.jetbrains.kotlin.gradle.plugin.cocoapods.CocoapodsExtension.*
|
import org.jetbrains.kotlin.gradle.plugin.cocoapods.CocoapodsExtension.*
|
||||||
import org.jetbrains.kotlin.gradle.plugin.cocoapods.cocoapodsBuildDirs
|
import org.jetbrains.kotlin.gradle.plugin.cocoapods.cocoapodsBuildDirs
|
||||||
import org.jetbrains.kotlin.gradle.plugin.cocoapods.platformLiteral
|
import org.jetbrains.kotlin.gradle.plugin.cocoapods.platformLiteral
|
||||||
|
import org.jetbrains.kotlin.gradle.utils.XcodeVersion
|
||||||
import org.jetbrains.kotlin.konan.target.Family
|
import org.jetbrains.kotlin.konan.target.Family
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
@@ -49,6 +50,9 @@ abstract class PodGenTask : CocoapodsTask() {
|
|||||||
@get:Nested
|
@get:Nested
|
||||||
internal abstract val pods: ListProperty<CocoapodsDependency>
|
internal abstract val pods: ListProperty<CocoapodsDependency>
|
||||||
|
|
||||||
|
@get:Input
|
||||||
|
internal abstract val xcodeVersion: Property<XcodeVersion>
|
||||||
|
|
||||||
@get:OutputFile
|
@get:OutputFile
|
||||||
val podfile: Provider<File> = family.map { project.cocoapodsBuildDirs.synthetic(it).resolve("Podfile") }
|
val podfile: Provider<File> = family.map { project.cocoapodsBuildDirs.synthetic(it).resolve("Podfile") }
|
||||||
|
|
||||||
@@ -59,18 +63,18 @@ abstract class PodGenTask : CocoapodsTask() {
|
|||||||
val podfile = this.podfile.get()
|
val podfile = this.podfile.get()
|
||||||
podfile.createNewFile()
|
podfile.createNewFile()
|
||||||
|
|
||||||
val podfileContent = getPodfileContent(specRepos, family.get().platformLiteral)
|
val podfileContent = getPodfileContent(specRepos, family.get())
|
||||||
podfile.writeText(podfileContent)
|
podfile.writeText(podfileContent)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getPodfileContent(specRepos: Collection<String>, xcodeTarget: String) =
|
private fun getPodfileContent(specRepos: Collection<String>, family: Family) =
|
||||||
buildString {
|
buildString {
|
||||||
|
|
||||||
specRepos.forEach {
|
specRepos.forEach {
|
||||||
appendLine("source '$it'")
|
appendLine("source '$it'")
|
||||||
}
|
}
|
||||||
|
|
||||||
appendLine("target '$xcodeTarget' do")
|
appendLine("target '${family.platformLiteral}' do")
|
||||||
if (useLibraries.get().not()) {
|
if (useLibraries.get().not()) {
|
||||||
appendLine("\tuse_frameworks!")
|
appendLine("\tuse_frameworks!")
|
||||||
}
|
}
|
||||||
@@ -97,20 +101,55 @@ abstract class PodGenTask : CocoapodsTask() {
|
|||||||
}
|
}
|
||||||
}.forEach { appendLine("\t$it") }
|
}.forEach { appendLine("\t$it") }
|
||||||
appendLine("end\n")
|
appendLine("end\n")
|
||||||
//disable signing for all synthetic pods KT-54314
|
|
||||||
append(
|
appendLine(
|
||||||
"""
|
"""
|
||||||
post_install do |installer|
|
|post_install do |installer|
|
||||||
installer.pods_project.targets.each do |target|
|
| installer.pods_project.targets.each do |target|
|
||||||
target.build_configurations.each do |config|
|
| target.build_configurations.each do |config|
|
||||||
config.build_settings['EXPANDED_CODE_SIGN_IDENTITY'] = ""
|
|
|
||||||
config.build_settings['CODE_SIGNING_REQUIRED'] = "NO"
|
| # Disable signing for all synthetic pods KT-54314
|
||||||
config.build_settings['CODE_SIGNING_ALLOWED'] = "NO"
|
| config.build_settings['EXPANDED_CODE_SIGN_IDENTITY'] = ""
|
||||||
end
|
| config.build_settings['CODE_SIGNING_REQUIRED'] = "NO"
|
||||||
end
|
| config.build_settings['CODE_SIGNING_ALLOWED'] = "NO"
|
||||||
end
|
| ${insertXcode143DeploymentTargetWorkarounds(family)}
|
||||||
""".trimIndent()
|
| end
|
||||||
|
| end
|
||||||
|
|end
|
||||||
|
""".trimMargin()
|
||||||
)
|
)
|
||||||
appendLine()
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
private fun insertXcode143DeploymentTargetWorkarounds(family: Family): String {
|
||||||
|
if (xcodeVersion.get() < XcodeVersion(14, 3)) {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
class Spec(val property: String, val major: Int, val minor: Int)
|
||||||
|
|
||||||
|
val minDeploymentTargetSpec = when (family) {
|
||||||
|
Family.IOS -> Spec("IPHONEOS_DEPLOYMENT_TARGET", 11, 0)
|
||||||
|
Family.OSX -> Spec("MACOSX_DEPLOYMENT_TARGET", 10, 13)
|
||||||
|
Family.TVOS -> Spec("TVOS_DEPLOYMENT_TARGET", 11, 0)
|
||||||
|
Family.WATCHOS -> Spec("WATCHOS_DEPLOYMENT_TARGET", 4, 0)
|
||||||
|
else -> error("Family $family is not an Apple platform")
|
||||||
|
}
|
||||||
|
|
||||||
|
return minDeploymentTargetSpec.run {
|
||||||
|
"""
|
||||||
|
|
|
||||||
|
| deployment_target_split = config.build_settings['$property']&.split('.')
|
||||||
|
| deployment_target_major = deployment_target_split&.first&.to_i
|
||||||
|
| deployment_target_minor = deployment_target_split&.second&.to_i
|
||||||
|
|
|
||||||
|
| if deployment_target_major && deployment_target_minor then
|
||||||
|
| if deployment_target_major < $major || (deployment_target_major == $major && deployment_target_minor < $minor) then
|
||||||
|
| version = "#{$major}.#{$minor}"
|
||||||
|
| puts "Deployment target for #{target} #{config} has been raised to #{version}. See KT-57741 for more details"
|
||||||
|
| config.build_settings['$property'] = version
|
||||||
|
| end
|
||||||
|
| end
|
||||||
|
""".trimMargin()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+24
-3
@@ -15,21 +15,42 @@ 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 org.jetbrains.kotlin.util.capitalizeDecapitalize.toUpperCaseAsciiOnly
|
import org.jetbrains.kotlin.util.capitalizeDecapitalize.toUpperCaseAsciiOnly
|
||||||
|
import java.io.Serializable
|
||||||
|
|
||||||
@InternalKotlinGradlePluginApi
|
@InternalKotlinGradlePluginApi
|
||||||
val Xcode = XcodeUtils.INSTANCE
|
val Xcode = XcodeUtils.INSTANCE
|
||||||
|
|
||||||
|
@InternalKotlinGradlePluginApi
|
||||||
|
data class XcodeVersion(val major: Int, val minor: Int) : Serializable, Comparable<XcodeVersion> {
|
||||||
|
override fun compareTo(other: XcodeVersion): Int {
|
||||||
|
return when (val majorComparison = major.compareTo(other.major)) {
|
||||||
|
0 -> minor.compareTo(other.minor)
|
||||||
|
else -> majorComparison
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@InternalKotlinGradlePluginApi
|
@InternalKotlinGradlePluginApi
|
||||||
class XcodeUtils private constructor() {
|
class XcodeUtils private constructor() {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
internal val INSTANCE: XcodeUtils? =
|
internal val INSTANCE: XcodeUtils? =
|
||||||
if (HostManager.hostIsMac) XcodeUtils() else null
|
if (HostManager.hostIsMac) XcodeUtils() else null
|
||||||
|
|
||||||
|
internal fun parseFromXcodebuild(output: String): XcodeVersion? {
|
||||||
|
val version = output.lines()[0].removePrefix("Xcode ")
|
||||||
|
val split = version.split("(\\s+|\\.|-)".toRegex())
|
||||||
|
return XcodeVersion(
|
||||||
|
major = split[0].toIntOrNull() ?: return null,
|
||||||
|
minor = split.getOrNull(1)?.toIntOrNull() ?: return null,
|
||||||
|
)
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val currentVersion: String by lazy {
|
val currentVersion: XcodeVersion by lazy {
|
||||||
val out = runCommand(listOf("/usr/bin/xcrun", "xcodebuild", "-version"))
|
val out = runCommand(listOf("/usr/bin/xcrun", "xcodebuild", "-version"))
|
||||||
out.lines()[0].removePrefix("Xcode ")
|
parseFromXcodebuild(out) ?: XcodeVersion(1, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
private val defaultTestDevices: Map<Family, String> by lazy {
|
private val defaultTestDevices: Map<Family, String> by lazy {
|
||||||
@@ -66,7 +87,7 @@ class XcodeUtils private constructor() {
|
|||||||
fun getDefaultTestDeviceId(target: KonanTarget): String? = defaultTestDevices[target.family]
|
fun getDefaultTestDeviceId(target: KonanTarget): String? = defaultTestDevices[target.family]
|
||||||
|
|
||||||
fun defaultBitcodeEmbeddingMode(target: KonanTarget, buildType: NativeBuildType): BitcodeEmbeddingMode {
|
fun defaultBitcodeEmbeddingMode(target: KonanTarget, buildType: NativeBuildType): BitcodeEmbeddingMode {
|
||||||
if (currentVersion.split(".")[0].toInt() < 14) {
|
if (currentVersion.major < 14) {
|
||||||
if (target.family in listOf(IOS, WATCHOS, TVOS) && target.architecture in listOf(ARM32, ARM64)) {
|
if (target.family in listOf(IOS, WATCHOS, TVOS) && target.architecture in listOf(ARM32, ARM64)) {
|
||||||
when (buildType) {
|
when (buildType) {
|
||||||
NativeBuildType.RELEASE -> return BitcodeEmbeddingMode.BITCODE
|
NativeBuildType.RELEASE -> return BitcodeEmbeddingMode.BITCODE
|
||||||
|
|||||||
+31
@@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
* 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.utils
|
||||||
|
|
||||||
|
import org.junit.Test
|
||||||
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
|
class XcodeVersionTest {
|
||||||
|
@Test
|
||||||
|
fun testParsing() {
|
||||||
|
assertEquals(XcodeVersion(14, 1), XcodeUtils.parseFromXcodebuild("Xcode 14.1\nBuild version 14B47b\n"))
|
||||||
|
assertEquals(XcodeVersion(14, 3), XcodeUtils.parseFromXcodebuild("Xcode 14.3\nBuild version 14E222b\n"))
|
||||||
|
assertEquals(XcodeVersion(1, 0), XcodeUtils.parseFromXcodebuild("Xcode 1.0 RC\nBuild version 7B85\n"))
|
||||||
|
assertEquals(XcodeVersion(1, 15), XcodeUtils.parseFromXcodebuild("Xcode 1.15-RC\nBuild version 7B85\n"))
|
||||||
|
assertEquals(XcodeVersion(14, 1), XcodeUtils.parseFromXcodebuild("Xcode 14.1.1.3.2.1.123\nBuild version 14B47b\n"))
|
||||||
|
assertEquals(null, XcodeUtils.parseFromXcodebuild("Xcode 14\nBuild version 14B47b\n"))
|
||||||
|
assertEquals(null, XcodeUtils.parseFromXcodebuild("XC 14.1\nBuild version 14B47b\n"))
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testComparison() {
|
||||||
|
assert(XcodeVersion(3, 2) == XcodeVersion(3, 2))
|
||||||
|
assert(XcodeVersion(3, 2) > XcodeVersion(2, 14))
|
||||||
|
assert(XcodeVersion(3, 2) > XcodeVersion(3, 1))
|
||||||
|
assert(XcodeVersion(3, 2) < XcodeVersion(3, 3))
|
||||||
|
assert(XcodeVersion(4, 0) > XcodeVersion(3, 3))
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user