Skip to content

Commit

Permalink
[K/N] Pick minimal iOS/tvOS depending on the Xcode version
Browse files Browse the repository at this point in the history
ld from Xcode 15 beta 5 incorrectly parses dylib version if it was built
with version < 12.0.

In the master branch we simply solved the problem by bumping
minOsVersion to 12.0. However, in 1.9.10 we have to support both Xcode 14
as well as Xcode 15. Thus, we a added a bit of logic that checks Xcode
version and sets minOsVersion depending on it.

^KT-60758
  • Loading branch information
sbogolepov authored and qodana-bot committed Aug 11, 2023
1 parent b1aa582 commit 955598c
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 5 deletions.
10 changes: 10 additions & 0 deletions kotlin-native/konan/konan.properties
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,10 @@ minVersion.tvos = 9.0
# 7.0 for watchos_x64, watchos_simulator_arm64
minVersion.watchos = 5.0

# Workaround for Xcode 15. See KT-60758
minVersionSinceXcode15.ios = 12.0
minVersionSinceXcode15.tvos = 12.0

toolchainDependency.mingw_x64 = msys2-mingw-w64-x86_64-2
toolchainDependency.mingw_x86 = msys2-mingw-w64-i686-2
toolchainDependency.linux_x64 = x86_64-unknown-linux-gnu-gcc-8.3.0-glibc-2.19-kernel-4.9-2
Expand Down Expand Up @@ -244,6 +248,7 @@ linkerDynamicFlags.ios_arm64 = -dylib
linkerKonanFlags.ios_arm64 = -lSystem -lc++ -lobjc -framework Foundation -framework UIKit
linkerOptimizationFlags.ios_arm64 = -dead_strip
osVersionMin.ios_arm64 = $minVersion.ios
osVersionMinSinceXcode15.ios_arm64 = $minVersionSinceXcode15.ios
sdkVersion.ios_arm64 = $sdkVersion.ios
osVersionMinFlagLd.ios_arm64 = -ios_version_min

Expand All @@ -270,6 +275,7 @@ linkerNoDebugFlags.ios_x64 = -S
stripFlags.ios_x64 = -S
linkerDynamicFlags.ios_x64 = -dylib
osVersionMin.ios_x64 = $minVersion.ios
osVersionMinSinceXcode15.ios_x64 = $minVersionSinceXcode15.ios
sdkVersion.ios_x64 = $sdkVersion.ios
osVersionMinFlagLd.ios_x64 = -ios_simulator_version_min

Expand All @@ -295,6 +301,7 @@ linkerNoDebugFlags.ios_simulator_arm64 = -S
stripFlags.ios_simulator_arm64 = -S
linkerDynamicFlags.ios_simulator_arm64 = -dylib
osVersionMin.ios_simulator_arm64 = $minVersion.ios
osVersionMinSinceXcode15.ios_simulator_arm64 = $minVersionSinceXcode15.ios
sdkVersion.ios_simulator_arm64 = $sdkVersion.ios
osVersionMinFlagLd.ios_simulator_arm64 = -ios_simulator_version_min

Expand All @@ -320,6 +327,7 @@ linkerNoDebugFlags.tvos_x64 = -S
stripFlags.tvos_x64 = -S
linkerDynamicFlags.tvos_x64 = -dylib
osVersionMin.tvos_x64 = $minVersion.tvos
osVersionMinSinceXcode15.tvos_x64 = $minVersionSinceXcode15.tvos
sdkVersion.tvos_x64 = $sdkVersion.tvos
osVersionMinFlagLd.tvos_x64 = -tvos_simulator_version_min

Expand All @@ -344,6 +352,7 @@ linkerNoDebugFlags.tvos_simulator_arm64 = -S
stripFlags.tvos_simulator_arm64 = -S
linkerDynamicFlags.tvos_simulator_arm64 = -dylib
osVersionMin.tvos_simulator_arm64 = $minVersion.tvos
osVersionMinSinceXcode15.tvos_simulator_arm64 = $minVersionSinceXcode15.tvos
sdkVersion.tvos_simulator_arm64 = $sdkVersion.tvos
osVersionMinFlagLd.tvos_simulator_arm64 = -tvos_simulator_version_min

Expand All @@ -368,6 +377,7 @@ linkerDynamicFlags.tvos_arm64 = -dylib
linkerKonanFlags.tvos_arm64 = -lSystem -lc++ -lobjc -framework Foundation -framework UIKit
linkerOptimizationFlags.tvos_arm64 = -dead_strip
osVersionMin.tvos_arm64 = $minVersion.tvos
osVersionMinSinceXcode15.tvos_arm64 = $minVersionSinceXcode15.tvos
sdkVersion.tvos_arm64 = $sdkVersion.tvos
osVersionMinFlagLd.tvos_arm64 = -tvos_version_min

Expand Down
38 changes: 33 additions & 5 deletions native/utils/src/org/jetbrains/kotlin/konan/target/Apple.kt
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,24 @@ class AppleConfigurablesImpl(
XcodePartsProvider.InternalServer -> absolute(sdkDependency)
}

override val osVersionMin: String by lazy {
// A hack only for 1.9.10 where we need to keep the old defaults for Xcode 14 (min version 9.0)
// and the new ones for Xcode 15 (min version 12.0).
if (target.family == Family.IOS || target.family == Family.TVOS) {
when (val xcodePartsProvider1 = xcodePartsProvider) {
is XcodePartsProvider.Local -> {
if (checkXcodeVersion("15.0.0", xcodePartsProvider1.xcode.version)) {
return@lazy targetString("osVersionMinSinceXcode15")!!
}
}
is XcodePartsProvider.InternalServer -> {
// Build server case. Here we use Xcode 14, so we don't need a workaround here.
}
}
}
super.osVersionMin
}

override val absoluteTargetToolchain: String get() = when (val provider = xcodePartsProvider) {
is XcodePartsProvider.Local -> provider.xcode.toolchain
XcodePartsProvider.InternalServer -> absolute(toolchainDependency)
Expand All @@ -60,15 +78,25 @@ class AppleConfigurablesImpl(
if (properties.getProperty("ignoreXcodeVersionCheck") != "true") {
properties.getProperty("minimalXcodeVersion")?.let { minimalXcodeVersion ->
val currentXcodeVersion = xcode.version
checkXcodeVersion(minimalXcodeVersion, currentXcodeVersion)
if (!checkXcodeVersion(minimalXcodeVersion, currentXcodeVersion)) {
error("Unsupported Xcode version $currentXcodeVersion, minimal supported version is $minimalXcodeVersion.")
}
}
}

XcodePartsProvider.Local(xcode)
}
}

private fun checkXcodeVersion(minimalVersion: String, currentVersion: String) {
/**
* Checks if the current Xcode version meets the minimal version requirement.
*
* @param minimalVersion The minimal Xcode version to check against.
* @param currentVersion The current Xcode version.
* @return true if the current Xcode version is greater than or equal to the minimal version,
* false otherwise.
*/
private fun checkXcodeVersion(minimalVersion: String, currentVersion: String): Boolean {
// Xcode versions contain only numbers (even betas).
// But we still split by '-' and whitespaces to take into account versions like 11.2-beta.
val minimalVersionParts = minimalVersion.split("(\\s+|\\.|-)".toRegex()).map { it.toIntOrNull() ?: 0 }
Expand All @@ -80,11 +108,11 @@ class AppleConfigurablesImpl(
val minimalPart = minimalVersionParts.getOrElse(i) { 0 }

when {
currentPart > minimalPart -> return
currentPart < minimalPart ->
error("Unsupported Xcode version $currentVersion, minimal supported version is $minimalVersion.")
currentPart > minimalPart -> return true
currentPart < minimalPart -> return false
}
}
return true
}

private sealed class XcodePartsProvider {
Expand Down

0 comments on commit 955598c

Please sign in to comment.