Skip to content

Commit 0853eaa

Browse files
authored
Merge pull request #219 from owenv/platform-version-take-2
Reapply "Use platform_version to pass deployment target info to the linker"
2 parents 0666f04 + 7f74442 commit 0853eaa

File tree

4 files changed

+294
-61
lines changed

4 files changed

+294
-61
lines changed

Sources/SwiftDriver/Jobs/DarwinToolchain+LinkerSupport.swift

Lines changed: 29 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212
import TSCBasic
13+
import TSCUtility
1314
import SwiftOptions
1415

1516
extension DarwinToolchain {
@@ -112,49 +113,36 @@ extension DarwinToolchain {
112113
commandLine.appendPath(clangRTPath)
113114
}
114115

116+
private func addPlatformVersionArg(to commandLine: inout [Job.ArgTemplate],
117+
for triple: Triple, sdkPath: VirtualPath?) {
118+
assert(triple.isDarwin)
119+
let platformName = triple.darwinPlatform!.linkerPlatformName
120+
let platformVersion = triple.darwinLinkerPlatformVersion
121+
let sdkVersion: Version
122+
if let sdkPath = sdkPath,
123+
let sdkInfo = getTargetSDKInfo(sdkPath: sdkPath) {
124+
sdkVersion = sdkInfo.sdkVersion(for: triple)
125+
} else {
126+
sdkVersion = Version(0, 0, 0)
127+
}
128+
129+
commandLine.append(.flag("-platform_version"))
130+
commandLine.append(.flag(platformName))
131+
commandLine.append(.flag(platformVersion.description))
132+
commandLine.append(.flag(sdkVersion.description))
133+
}
134+
115135
private func addDeploymentTargetArgs(
116136
to commandLine: inout [Job.ArgTemplate],
117137
targetTriple: Triple,
118-
targetVariantTriple: Triple?
138+
targetVariantTriple: Triple?,
139+
sdkPath: VirtualPath?
119140
) {
120-
// FIXME: Properly handle deployment targets.
121-
122-
let flag: String
123-
124-
switch targetTriple.darwinPlatform! {
125-
case .iOS(.device):
126-
flag = "-iphoneos_version_min"
127-
case .iOS(.simulator):
128-
flag = "-ios_simulator_version_min"
129-
case .iOS(.catalyst):
130-
flag = "-maccatalyst_version_min"
131-
case .macOS:
132-
flag = "-macosx_version_min"
133-
case .tvOS(.device):
134-
flag = "-tvos_version_min"
135-
case .tvOS(.simulator):
136-
flag = "-tvos_simulator_version_min"
137-
case .watchOS(.device):
138-
flag = "-watchos_version_min"
139-
case .watchOS(.simulator):
140-
flag = "-watchos_simulator_version_min"
141-
}
142-
143-
commandLine.appendFlag(flag)
144-
commandLine.appendFlag(targetTriple.version().description)
145-
146-
if let variant = targetVariantTriple {
147-
if targetTriple.isiOS {
148-
assert(targetTriple.isValidForZipperingWithTriple(variant))
149-
assert(variant.isMacOSX)
150-
commandLine.appendFlag("-macosx_version_min")
151-
commandLine.appendFlag(variant.version().description)
152-
} else {
153-
assert(targetTriple.isValidForZipperingWithTriple(variant))
154-
assert(variant.isMacCatalyst)
155-
commandLine.appendFlag("-maccatalyst_version_min")
156-
commandLine.appendFlag(variant.version().description)
157-
}
141+
addPlatformVersionArg(to: &commandLine, for: targetTriple, sdkPath: sdkPath)
142+
if let variantTriple = targetVariantTriple {
143+
assert(targetTriple.isValidForZipperingWithTriple(variantTriple))
144+
addPlatformVersionArg(to: &commandLine, for: variantTriple,
145+
sdkPath: sdkPath)
158146
}
159147
}
160148

@@ -284,7 +272,8 @@ extension DarwinToolchain {
284272
addDeploymentTargetArgs(
285273
to: &commandLine,
286274
targetTriple: targetTriple,
287-
targetVariantTriple: targetVariantTriple
275+
targetVariantTriple: targetVariantTriple,
276+
sdkPath: try sdkPath.map(VirtualPath.init(path:))
288277
)
289278
try addProfileGenerationArgs(
290279
to: &commandLine,

Sources/SwiftDriver/Toolchains/DarwinToolchain.swift

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ public final class DarwinToolchain: Toolchain {
137137
case .iOSVersionAboveMaximumDeploymentTarget(let version):
138138
return "iOS \(version) does not support 32-bit programs"
139139
case .unsupportedTargetVariant(variant: let variant):
140-
return "unsupported '\(variant.isiOS ? "-target" : "-target-variant")' value '\(variant)'; use 'ios-macabi' instead"
140+
return "unsupported '\(variant.isiOS ? "-target-variant" : "-target")' value '\(variant.triple)'; use 'ios-macabi' instead"
141141
case .argumentNotSupported(let argument):
142142
return "\(argument) is no longer supported for Apple platforms"
143143
case .darwinOnlySupportsLibCxx:
@@ -208,14 +208,14 @@ public final class DarwinToolchain: Toolchain {
208208
}
209209
}
210210

211-
private struct DarwinSDKInfo: Decodable {
212-
enum CodingKeys: String, CodingKey {
211+
struct DarwinSDKInfo: Decodable {
212+
private enum CodingKeys: String, CodingKey {
213213
case version = "Version"
214214
case versionMap = "VersionMap"
215215
}
216216

217217
struct VersionMap: Decodable {
218-
enum CodingKeys: String, CodingKey {
218+
private enum CodingKeys: String, CodingKey {
219219
case macOSToCatalystMapping = "macOS_iOSMac"
220220
}
221221

@@ -242,8 +242,8 @@ public final class DarwinToolchain: Toolchain {
242242
}
243243
}
244244

245-
var version: Version
246-
var versionMap: VersionMap
245+
private var version: Version
246+
private var versionMap: VersionMap
247247

248248
init(from decoder: Decoder) throws {
249249
let keyedContainer = try decoder.container(keyedBy: CodingKeys.self)
@@ -272,7 +272,7 @@ public final class DarwinToolchain: Toolchain {
272272
// SDK info is computed lazily. This should not generally be accessed directly.
273273
private var _sdkInfo: DarwinSDKInfo? = nil
274274

275-
private func getTargetSDKInfo(sdkPath: VirtualPath) -> DarwinSDKInfo? {
275+
func getTargetSDKInfo(sdkPath: VirtualPath) -> DarwinSDKInfo? {
276276
if let info = _sdkInfo {
277277
return info
278278
} else {

Sources/SwiftDriver/Utilities/Triple+Platforms.swift

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,29 @@ public enum DarwinPlatform: Hashable {
102102
}
103103
}
104104

105+
/// The name the linker uses to identify this platform.
106+
public var linkerPlatformName: String {
107+
switch self {
108+
case .macOS:
109+
return "macos"
110+
case .iOS(.device):
111+
return "ios"
112+
case .iOS(.simulator):
113+
return "ios-simulator"
114+
case .iOS(.catalyst):
115+
return "mac-catalyst"
116+
case .tvOS(.device):
117+
return "tvos"
118+
case .tvOS(.simulator):
119+
return "tvos-simulator"
120+
case .watchOS(.device):
121+
return "watchos"
122+
case .watchOS(.simulator):
123+
return "watchos-simulator"
124+
}
125+
}
126+
127+
105128
/// The name used to identify this platform in compiler_rt file names.
106129
public var libraryNameSuffix: String {
107130
switch self {
@@ -184,6 +207,53 @@ extension Triple {
184207
}
185208
}
186209

210+
// The Darwin platform version used for linking.
211+
public var darwinLinkerPlatformVersion: Version {
212+
precondition(self.isDarwin)
213+
switch darwinPlatform! {
214+
case .macOS:
215+
// The integrated driver falls back to `osVersion` for ivalid macOS
216+
// versions, this decision might be worth revisiting.
217+
let macVersion = _macOSVersion ?? osVersion
218+
// The first deployment of arm64 for macOS is version 11
219+
if macVersion.major < 11 && arch == .aarch64 {
220+
return Version(11, 0, 0)
221+
}
222+
223+
return macVersion
224+
case .iOS(.catalyst):
225+
// Mac Catalyst on arm was introduced with an iOS deployment target of
226+
// 14.0; the linker doesn't want to see a deployment target before that.
227+
if _iOSVersion.major < 14 && arch == .aarch64 {
228+
return Version(14, 0, 0)
229+
}
230+
231+
// Mac Catalyst was introduced with an iOS deployment target of 13.0;
232+
// the linker doesn't want to see a deployment target before that.
233+
if _iOSVersion.major < 13 {
234+
return Version(13, 0, 0)
235+
}
236+
237+
return _iOSVersion
238+
case .iOS(.device), .iOS(.simulator), .tvOS(_):
239+
// The first deployment of arm64 simulators is iOS/tvOS 14.0;
240+
// the linker doesn't want to see a deployment target before that.
241+
if _isSimulatorEnvironment && _iOSVersion.major < 14 && arch == .aarch64 {
242+
return Version(14, 0, 0)
243+
}
244+
245+
return _iOSVersion
246+
case .watchOS(_):
247+
// The first deployment of arm64 simulators is watchOS 7;
248+
// the linker doesn't want to see a deployment target before that.
249+
if _isSimulatorEnvironment && osVersion.major < 7 && arch == .aarch64 {
250+
return Version(7, 0, 0)
251+
}
252+
253+
return osVersion
254+
}
255+
}
256+
187257
/// The platform name, i.e. the name clang uses to identify this target in its
188258
/// resource directory.
189259
///

0 commit comments

Comments
 (0)