-
Notifications
You must be signed in to change notification settings - Fork 5.6k
/
Apple.kt
145 lines (128 loc) · 5.73 KB
/
Apple.kt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
/*
* Copyright 2010-2018 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed -> in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.konan.target
import org.jetbrains.kotlin.konan.properties.KonanPropertiesLoader
import org.jetbrains.kotlin.konan.properties.Properties
import org.jetbrains.kotlin.konan.util.InternalServer
import kotlin.math.max
class AppleConfigurablesImpl(
target: KonanTarget,
properties: Properties,
baseDir: String?
) : AppleConfigurables, KonanPropertiesLoader(target, properties, baseDir) {
private val sdkDependency = this.targetSysRoot!!
private val toolchainDependency = this.targetToolchain!!
private val xcodeAddonDependency = this.additionalToolsDir!!
override val absoluteTargetSysRoot: String get() = when (val provider = xcodePartsProvider) {
is XcodePartsProvider.Local -> provider.xcode.pathToPlatformSdk(platformName())
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)
}
override val absoluteAdditionalToolsDir: String get() = when (val provider = xcodePartsProvider) {
is XcodePartsProvider.Local -> provider.xcode.additionalTools
XcodePartsProvider.InternalServer -> absolute(additionalToolsDir)
}
override val dependencies get() = super.dependencies + when (xcodePartsProvider) {
is XcodePartsProvider.Local -> emptyList()
XcodePartsProvider.InternalServer -> listOf(sdkDependency, toolchainDependency, xcodeAddonDependency)
}
private val xcodePartsProvider by lazy {
if (InternalServer.isAvailable) {
XcodePartsProvider.InternalServer
} else {
val xcode = Xcode.findCurrent()
if (properties.getProperty("ignoreXcodeVersionCheck") != "true") {
properties.getProperty("minimalXcodeVersion")?.let { minimalXcodeVersion ->
val currentXcodeVersion = xcode.version
if (!checkXcodeVersion(minimalXcodeVersion, currentXcodeVersion)) {
error("Unsupported Xcode version $currentXcodeVersion, minimal supported version is $minimalXcodeVersion.")
}
}
}
XcodePartsProvider.Local(xcode)
}
}
/**
* 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 }
val currentVersionParts = currentVersion.split("(\\s+|\\.|-)".toRegex()).map { it.toIntOrNull() ?: 0 }
val size = max(minimalVersionParts.size, currentVersionParts.size)
for (i in 0 until size) {
val currentPart = currentVersionParts.getOrElse(i) { 0 }
val minimalPart = minimalVersionParts.getOrElse(i) { 0 }
when {
currentPart > minimalPart -> return true
currentPart < minimalPart -> return false
}
}
return true
}
private sealed class XcodePartsProvider {
class Local(val xcode: Xcode) : XcodePartsProvider()
object InternalServer : XcodePartsProvider()
}
}
/**
* Name of an Apple platform as in Xcode.app/Contents/Developer/Platforms.
*/
fun AppleConfigurables.platformName(): String = when (target.family) {
Family.OSX -> "MacOSX"
Family.IOS -> if (targetTriple.isSimulator) {
"iPhoneSimulator"
} else {
"iPhoneOS"
}
Family.TVOS -> if (targetTriple.isSimulator) {
"AppleTVSimulator"
} else {
"AppleTVOS"
}
Family.WATCHOS -> if (targetTriple.isSimulator) {
"WatchSimulator"
} else {
"WatchOS"
}
else -> error("Not an Apple target: $target")
}