Skip to content

Commit db30803

Browse files
committed
Use swift-driver triple
Removes and replaces the custom LLVM Triple type from the Basics module with the implementation from SwiftDrvier. This change allows spm to understand all triples that swift-driver already does and resolves some issues surrounding incorrect triple parsing. For example the Basics.Triple was not able to parse 'armv7em-apple-none-eabihf-macho' where as SwiftDriver.Triple can.
1 parent 8bf6bd7 commit db30803

File tree

6 files changed

+106
-194
lines changed

6 files changed

+106
-194
lines changed

Package.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,7 @@ let package = Package(
152152
.product(name: "DequeModule", package: "swift-collections"),
153153
.product(name: "OrderedCollections", package: "swift-collections"),
154154
.product(name: "SwiftToolsSupport-auto", package: "swift-tools-support-core"),
155+
.product(name: "SwiftDriver", package: "swift-driver"),
155156
.product(name: "SystemPackage", package: "swift-system"),
156157
],
157158
exclude: ["CMakeLists.txt"]

Sources/Basics/Triple.swift

Lines changed: 47 additions & 180 deletions
Original file line numberDiff line numberDiff line change
@@ -10,173 +10,36 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212

13-
import protocol Foundation.CustomNSError
14-
import var Foundation.NSLocalizedDescriptionKey
15-
1613
import enum TSCBasic.JSON
1714
import class TSCBasic.Process
15+
import struct SwiftDriver.Triple
1816

19-
/// Triple - Helper class for working with Destination.target values
20-
///
21-
/// Used for parsing values such as `x86_64-apple-macosx10.10` into
22-
/// set of enums. For os/arch/abi based conditions in build plan.
23-
///
24-
/// @see Destination.target
25-
/// @see https://github.com/apple/swift-llvm/blob/stable/include/llvm/ADT/Triple.h
26-
///
27-
public struct Triple: Encodable, Equatable, Sendable {
28-
public let tripleString: String
29-
30-
public let arch: Arch
31-
public let vendor: Vendor
32-
public let os: OS
33-
public let abi: ABI
34-
public let osVersion: String?
35-
public let abiVersion: String?
36-
37-
public enum Error: Swift.Error {
38-
case badFormat(triple: String)
39-
case unknownArch(arch: String)
40-
case unknownOS(os: String)
41-
}
42-
43-
public enum Arch: String, Encodable, Sendable {
44-
case x86_64
45-
case x86_64h
46-
case i686
47-
case powerpc
48-
case powerpc64le
49-
case s390x
50-
case aarch64
51-
case amd64
52-
case armv7
53-
case armv7em
54-
case armv6
55-
case armv5
56-
case arm
57-
case arm64
58-
case arm64e
59-
case wasm32
60-
case riscv64
61-
case mips
62-
case mipsel
63-
case mips64
64-
case mips64el
65-
}
66-
67-
public enum Vendor: String, Encodable, Sendable {
68-
case unknown
69-
case apple
70-
}
71-
72-
public enum OS: String, Encodable, CaseIterable, Sendable {
73-
case darwin
74-
case macOS = "macosx"
75-
case linux
76-
case windows
77-
case wasi
78-
case openbsd
79-
// 'OS' suffix purely to avoid name clash with Optional.none
80-
case noneOS = "none"
81-
}
82-
83-
public enum ABI: Encodable, Equatable, RawRepresentable, Sendable {
84-
case unknown
85-
case android
86-
case other(name: String)
87-
88-
public init?(rawValue: String) {
89-
if rawValue.hasPrefix(ABI.android.rawValue) {
90-
self = .android
91-
} else if let version = rawValue.firstIndex(where: { $0.isNumber }) {
92-
self = .other(name: String(rawValue[..<version]))
93-
} else {
94-
self = .other(name: rawValue)
95-
}
96-
}
97-
98-
public var rawValue: String {
99-
switch self {
100-
case .android: return "android"
101-
case .other(let name): return name
102-
case .unknown: return "unknown"
103-
}
104-
}
105-
106-
public static func == (lhs: ABI, rhs: ABI) -> Bool {
107-
switch (lhs, rhs) {
108-
case (.unknown, .unknown):
109-
return true
110-
case (.android, .android):
111-
return true
112-
case (.other(let lhsName), .other(let rhsName)):
113-
return lhsName == rhsName
114-
default:
115-
return false
116-
}
117-
}
118-
}
119-
120-
public init(_ string: String) throws {
121-
let components = string.split(separator: "-").map(String.init)
122-
123-
guard components.count == 3 || components.count == 4 else {
124-
throw Error.badFormat(triple: string)
125-
}
126-
127-
guard let arch = Arch(rawValue: components[0]) else {
128-
throw Error.unknownArch(arch: components[0])
129-
}
130-
131-
let vendor = Vendor(rawValue: components[1]) ?? .unknown
132-
133-
guard let os = Triple.parseOS(components[2]) else {
134-
throw Error.unknownOS(os: components[2])
135-
}
136-
137-
let osVersion = Triple.parseVersion(components[2])
138-
139-
let abi = components.count > 3 ? Triple.ABI(rawValue: components[3]) : nil
140-
let abiVersion = components.count > 3 ? Triple.parseVersion(components[3]) : nil
17+
public typealias Triple = SwiftDriver.Triple
14118

142-
self.tripleString = string
143-
self.arch = arch
144-
self.vendor = vendor
145-
self.os = os
146-
self.osVersion = osVersion
147-
self.abi = abi ?? .unknown
148-
self.abiVersion = abiVersion
149-
}
150-
151-
fileprivate static func parseOS(_ string: String) -> OS? {
152-
var candidates = OS.allCases.map { (name: $0.rawValue, value: $0) }
153-
// LLVM target triples support this alternate spelling as well.
154-
candidates.append((name: "macos", value: .macOS))
155-
return candidates.first(where: { string.hasPrefix($0.name) })?.value
19+
extension Triple {
20+
public init(_ description: String) throws {
21+
self.init(description, normalizing: false)
15622
}
23+
}
15724

158-
fileprivate static func parseVersion(_ string: String) -> String? {
159-
let candidate = String(string.drop(while: { $0.isLetter }))
160-
if candidate != string && !candidate.isEmpty {
161-
return candidate
162-
}
163-
164-
return nil
165-
}
25+
extension Triple {
26+
public static let macOS = try! Self("x86_64-apple-macosx")
27+
}
16628

29+
extension Triple {
16730
public func isApple() -> Bool {
16831
vendor == .apple
16932
}
17033

17134
public func isAndroid() -> Bool {
172-
os == .linux && abi == .android
35+
os == .linux && environment == .android
17336
}
17437

17538
public func isDarwin() -> Bool {
17639
switch (vendor, os) {
17740
case (.apple, .noneOS):
17841
return false
179-
case (.apple, _), (_, .macOS), (_, .darwin):
42+
case (.apple, _), (_, .macosx), (_, .darwin):
18043
return true
18144
default:
18245
return false
@@ -188,7 +51,7 @@ public struct Triple: Encodable, Equatable, Sendable {
18851
}
18952

19053
public func isWindows() -> Bool {
191-
os == .windows
54+
os == .win32
19255
}
19356

19457
public func isWASI() -> Bool {
@@ -204,7 +67,18 @@ public struct Triple: Encodable, Equatable, Sendable {
20467
/// This is currently meant for Apple platforms only.
20568
public func tripleString(forPlatformVersion version: String) -> String {
20669
precondition(isDarwin())
207-
return String(self.tripleString.dropLast(self.osVersion?.count ?? 0)) + version
70+
// This function did not handle triples with a specific environments and
71+
// object formats previously to using SwiftDriver.Triple and still does
72+
// not.
73+
return """
74+
\(self.archName)-\
75+
\(self.vendorName)-\
76+
\(self.osNameUnversioned)\(version)
77+
"""
78+
}
79+
80+
public var tripleString: String {
81+
self.triple
20882
}
20983

21084
/// Determine the versioned host triple using the Swift compiler.
@@ -235,6 +109,7 @@ public struct Triple: Encodable, Equatable, Sendable {
235109
"Target info does not contain a triple string (\(error.interpolationDescription)).\nTarget info: \(parsedTargetInfo)"
236110
)
237111
}
112+
238113
// Parse the triple string.
239114
do {
240115
return try Triple(tripleString)
@@ -244,18 +119,13 @@ public struct Triple: Encodable, Equatable, Sendable {
244119
)
245120
}
246121
}
247-
248-
public static func == (lhs: Triple, rhs: Triple) -> Bool {
249-
lhs.arch == rhs.arch && lhs.vendor == rhs.vendor && lhs.os == rhs.os && lhs.abi == rhs.abi && lhs
250-
.osVersion == rhs.osVersion && lhs.abiVersion == rhs.abiVersion
251-
}
252122
}
253123

254124
extension Triple {
255125
/// The file prefix for dynamic libraries
256126
public var dynamicLibraryPrefix: String {
257127
switch os {
258-
case .windows:
128+
case .win32:
259129
return ""
260130
default:
261131
return "lib"
@@ -264,32 +134,42 @@ extension Triple {
264134

265135
/// The file extension for dynamic libraries (eg. `.dll`, `.so`, or `.dylib`)
266136
public var dynamicLibraryExtension: String {
137+
guard let os = self.os else {
138+
fatalError("Cannot create dynamic libraries unknown os.")
139+
}
140+
267141
switch os {
268-
case .darwin, .macOS:
142+
case .darwin, .macosx:
269143
return ".dylib"
270144
case .linux, .openbsd:
271145
return ".so"
272-
case .windows:
146+
case .win32:
273147
return ".dll"
274148
case .wasi:
275149
return ".wasm"
276-
case .noneOS:
277-
fatalError("Cannot create dynamic libraries for os \"none\".")
150+
default:
151+
fatalError("Cannot create dynamic libraries for os \"\(os)\".")
278152
}
279153
}
280154

281155
public var executableExtension: String {
156+
guard let os = self.os else {
157+
return ""
158+
}
159+
282160
switch os {
283-
case .darwin, .macOS:
161+
case .darwin, .macosx:
284162
return ""
285163
case .linux, .openbsd:
286164
return ""
287165
case .wasi:
288166
return ".wasm"
289-
case .windows:
167+
case .win32:
290168
return ".exe"
291169
case .noneOS:
292170
return ""
171+
default:
172+
return ""
293173
}
294174
}
295175

@@ -301,7 +181,7 @@ extension Triple {
301181
/// The file extension for Foundation-style bundle.
302182
public var nsbundleExtension: String {
303183
switch os {
304-
case .darwin, .macOS:
184+
case .darwin, .macosx:
305185
return ".bundle"
306186
default:
307187
// See: https://github.com/apple/swift-corelibs-foundation/blob/master/Docs/FHS%20Bundles.md
@@ -314,21 +194,8 @@ extension Triple: CustomStringConvertible {
314194
public var description: String { tripleString }
315195
}
316196

317-
extension Triple.Error: CustomNSError {
318-
public var errorUserInfo: [String: Any] {
319-
[NSLocalizedDescriptionKey: "\(self)"]
320-
}
321-
}
322-
323-
extension Triple.Error: CustomStringConvertible {
324-
public var description: String {
325-
switch self {
326-
case .badFormat(let triple):
327-
return "couldn't parse triple string \(triple)"
328-
case .unknownArch(let arch):
329-
return "unknown architecture \(arch)"
330-
case .unknownOS(let os):
331-
return "unknown OS \(os)"
332-
}
197+
extension Triple: Equatable {
198+
public static func == (lhs: Self, rhs: Self) -> Bool {
199+
lhs.triple == rhs.triple
333200
}
334201
}

Sources/PackageModel/UserToolchain.swift

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -382,11 +382,11 @@ public final class UserToolchain: Toolchain {
382382
// the merged swiftmodules. XCTest followed suit.
383383
"-I",
384384
AbsolutePath(
385-
validating: "usr/lib/swift/windows/\(triple.arch)",
385+
validating: "usr/lib/swift/windows/\(triple.arch?.rawValue ?? "unknown")",
386386
relativeTo: installation
387387
).pathString,
388388
"-L",
389-
AbsolutePath(validating: "usr/lib/swift/windows/\(triple.arch)", relativeTo: installation)
389+
AbsolutePath(validating: "usr/lib/swift/windows/\(triple.arch?.rawValue ?? "unknown")", relativeTo: installation)
390390
.pathString,
391391
]
392392

@@ -716,32 +716,32 @@ public final class UserToolchain: Toolchain {
716716
// (~5.7), we always had a singular installed SDK. Prefer the
717717
// new variant which has an architecture subdirectory in `bin`
718718
// if available.
719-
switch triple.arch {
720-
case .x86_64, .x86_64h:
719+
switch triple.archName {
720+
case "x86_64", "x86_64h":
721721
let path: AbsolutePath =
722722
xctest.appending("usr")
723723
.appending("bin64")
724724
if localFileSystem.exists(path) {
725725
return path
726726
}
727727

728-
case .i686:
728+
case "i686":
729729
let path: AbsolutePath =
730730
xctest.appending("usr")
731731
.appending("bin32")
732732
if localFileSystem.exists(path) {
733733
return path
734734
}
735735

736-
case .armv7:
736+
case "armv7":
737737
let path: AbsolutePath =
738738
xctest.appending("usr")
739739
.appending("bin32a")
740740
if localFileSystem.exists(path) {
741741
return path
742742
}
743743

744-
case .arm64:
744+
case "arm64":
745745
let path: AbsolutePath =
746746
xctest.appending("usr")
747747
.appending("bin64a")

0 commit comments

Comments
 (0)