Skip to content

Commit c0f7bb7

Browse files
committed
TSCUtility: support additional spellings for ARM
ARM uses `armv[4-9]-?[arm]` as the arch field to encode the ISA version and the core type for ARMv7. Use the custom parsing logic similar to the other fields to accommodate the spelling.
1 parent 71dcf5a commit c0f7bb7

File tree

2 files changed

+127
-3
lines changed

2 files changed

+127
-3
lines changed

Sources/TSCUtility/Triple.swift

+121-3
Original file line numberDiff line numberDiff line change
@@ -36,15 +36,23 @@ public struct Triple: Encodable, Equatable {
3636
case unknownOS(os: String)
3737
}
3838

39-
public enum Arch: String, Encodable {
39+
public enum ARMCore: String, Encodable, CaseIterable {
40+
case a = "a"
41+
case r = "r"
42+
case m = "m"
43+
case k = "k"
44+
case s = "s"
45+
}
46+
47+
public enum Arch: Encodable {
4048
case x86_64
4149
case x86_64h
4250
case i686
4351
case powerpc64le
4452
case s390x
4553
case aarch64
4654
case amd64
47-
case armv7
55+
case armv7(core: ARMCore?)
4856
case armv6
4957
case armv5
5058
case arm
@@ -111,7 +119,7 @@ public struct Triple: Encodable, Equatable {
111119
throw Error.badFormat(triple: string)
112120
}
113121

114-
guard let arch = Arch(rawValue: components[0]) else {
122+
guard let arch = Triple.parseArch(components[0]) else {
115123
throw Error.unknownArch(arch: components[0])
116124
}
117125

@@ -135,6 +143,43 @@ public struct Triple: Encodable, Equatable {
135143
self.abiVersion = abiVersion
136144
}
137145

146+
fileprivate static func parseArch(_ string: String) -> Arch? {
147+
let candidates: [String:Arch] = [
148+
"x86_64h": .x86_64h,
149+
"x86_64": .x86_64,
150+
"i686": .i686,
151+
"powerpc64le": .powerpc64le,
152+
"s390x": .s390x,
153+
"aarch64": .aarch64,
154+
"amd64": .amd64,
155+
"armv7": .armv7(core: nil),
156+
"armv6": .armv6,
157+
"armv5": .armv5,
158+
"arm": .arm,
159+
"arm64": .arm64,
160+
"arm64e": .arm64e,
161+
"wasm32": .wasm32,
162+
]
163+
if let match = candidates.first(where: { string.hasPrefix($0.key) })?.value {
164+
if case let .armv7(core: _) = match {
165+
if string.hasPrefix("armv7a") {
166+
return .armv7(core: .a)
167+
} else if string.hasPrefix("armv7r") {
168+
return .armv7(core: .r)
169+
} else if string.hasPrefix("armv7m") {
170+
return .armv7(core: .m)
171+
} else if string.hasPrefix("armv7k") {
172+
return .armv7(core: .k)
173+
} else if string.hasPrefix("armv7s") {
174+
return .armv7(core: .s)
175+
}
176+
return .armv7(core: nil)
177+
}
178+
return match
179+
}
180+
return nil
181+
}
182+
138183
fileprivate static func parseOS(_ string: String) -> OS? {
139184
var candidates = OS.allCases.map{ (name: $0.rawValue, value: $0) }
140185
// LLVM target triples support this alternate spelling as well.
@@ -201,6 +246,7 @@ public struct Triple: Encodable, Equatable {
201246
fatalError("Failed to get target info (\(error))")
202247
#endif
203248
}
249+
204250
// Parse the compiler's JSON output.
205251
let parsedTargetInfo: JSON
206252
do {
@@ -283,6 +329,78 @@ extension Triple {
283329
}
284330
}
285331

332+
extension Triple.Arch: CustomStringConvertible {
333+
public var description: String {
334+
switch self {
335+
case .x86_64:
336+
return "x86_64"
337+
case .x86_64h:
338+
return "x86_64h"
339+
case .i686:
340+
return "i686"
341+
case .powerpc64le:
342+
return "powerpc64le"
343+
case .s390x:
344+
return "s390x"
345+
case .aarch64:
346+
return "aarch64"
347+
case .amd64:
348+
return "amd64"
349+
case .armv7(.none):
350+
return "armv7"
351+
case let .armv7(core: .some(core)):
352+
return "armv7\(core)"
353+
case .armv6:
354+
return "armv6"
355+
case .armv5:
356+
return "armv5"
357+
case .arm:
358+
return "arm"
359+
case .arm64:
360+
return "arm64"
361+
case .arm64e:
362+
return "arm64e"
363+
case .wasm32:
364+
return "wasm32"
365+
}
366+
}
367+
}
368+
369+
extension Triple.Arch: Equatable {
370+
public static func == (_ lhs: Triple.Arch, _ rhs: Triple.Arch) -> Bool {
371+
switch (lhs, rhs) {
372+
case (.x86_64, .x86_64):
373+
return true
374+
case (.x86_64h, .x86_64h):
375+
return true
376+
case (.i686, .i686):
377+
return true
378+
case (.powerpc64le, .powerpc64le):
379+
return true
380+
case (.s390x, .s390x):
381+
return true
382+
case (.armv7(.none), .armv7(.none)):
383+
return true
384+
case let (.armv7(.some(lhs)), .armv7(.some(rhs))) where lhs == rhs:
385+
return true
386+
case (.armv6, .armv6):
387+
return true
388+
case (.armv5, .armv5):
389+
return true
390+
case (.arm, .arm):
391+
return true
392+
case (.arm64, .arm64):
393+
return true
394+
case (.arm64e, .arm64e):
395+
return true
396+
case (.wasm32, .wasm32):
397+
return true
398+
default:
399+
return false
400+
}
401+
}
402+
}
403+
286404
extension Triple.Error: CustomNSError {
287405
public var errorUserInfo: [String : Any] {
288406
return [NSLocalizedDescriptionKey: "\(self)"]

Tests/TSCUtilityTests/TripleTests.swift

+6
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,12 @@ class TripleTests : XCTestCase {
4040
let linuxWithABIVersion = try? Triple("x86_64-unknown-linux-gnu42")
4141
XCTAssertEqual(linuxWithABIVersion!.abi, .other(name: "gnu"))
4242
XCTAssertEqual(linuxWithABIVersion!.abiVersion, "42")
43+
44+
let androidArm = try? Triple("armv7a-unknown-linux-androideabi")
45+
XCTAssertEqual(androidArm!.arch, .armv7(core: .a))
46+
47+
let watchOS = try? Triple("armv7k-apple-watchos")
48+
XCTAssertEqual(watchOS!.arch, .armv7(core: .k))
4349
}
4450

4551
func testEquality() throws {

0 commit comments

Comments
 (0)