diff --git a/Sources/TSCUtility/Triple.swift b/Sources/TSCUtility/Triple.swift index 449a21fe..87e70b56 100644 --- a/Sources/TSCUtility/Triple.swift +++ b/Sources/TSCUtility/Triple.swift @@ -27,6 +27,8 @@ public struct Triple: Encodable, Equatable { public let vendor: Vendor public let os: OS public let abi: ABI + public let osVersion: String? + public let abiVersion: String? public enum Error: Swift.Error { case badFormat @@ -83,13 +85,18 @@ public struct Triple: Encodable, Equatable { throw Error.unknownOS } + let osVersion = Triple.parseVersion(components[2]) + let abi = components.count > 3 ? Triple.parseABI(components[3]) : nil + let abiVersion = components.count > 3 ? Triple.parseVersion(components[3]) : nil self.tripleString = string self.arch = arch self.vendor = vendor self.os = os + self.osVersion = osVersion self.abi = abi ?? .unknown + self.abiVersion = abiVersion } fileprivate static func parseOS(_ string: String) -> OS? { @@ -100,6 +107,15 @@ public struct Triple: Encodable, Equatable { return nil } + fileprivate static func parseVersion(_ string: String) -> String? { + let candidate = String(string.drop(while: { $0.isLetter })) + if candidate != string && !candidate.isEmpty { + return candidate + } + + return nil + } + fileprivate static func parseABI(_ string: String) -> ABI? { if string.hasPrefix(ABI.android.rawValue) { return ABI.android @@ -132,18 +148,18 @@ public struct Triple: Encodable, Equatable { /// This is currently meant for Apple platforms only. public func tripleString(forPlatformVersion version: String) -> String { precondition(isDarwin()) - return self.tripleString + version + return String(self.tripleString.dropLast(self.osVersion?.count ?? 0)) + version } public static let macOS = try! Triple("x86_64-apple-macosx") - /// Determine the host triple using the Swift compiler. + /// Determine the versioned host triple using the Swift compiler. public static func getHostTriple(usingSwiftCompiler swiftCompiler: AbsolutePath) -> Triple { do { let result = try Process.popen(args: swiftCompiler.pathString, "-print-target-info") let output = try result.utf8Output().spm_chomp() let targetInfo = try JSON(string: output) - let tripleString: String = try targetInfo.get("target").get("unversionedTriple") + let tripleString: String = try targetInfo.get("target").get("triple") return try Triple(tripleString) } catch { // FIXME: Remove the macOS special-casing once the latest version of Xcode comes with diff --git a/Tests/TSCUtilityTests/TripleTests.swift b/Tests/TSCUtilityTests/TripleTests.swift new file mode 100644 index 00000000..f2918bdc --- /dev/null +++ b/Tests/TSCUtilityTests/TripleTests.swift @@ -0,0 +1,33 @@ +/* + This source file is part of the Swift.org open source project + + Copyright (c) 2014 - 2020 Apple Inc. and the Swift project authors + Licensed under Apache License v2.0 with Runtime Library Exception + + See http://swift.org/LICENSE.txt for license information + See http://swift.org/CONTRIBUTORS.txt for Swift project authors +*/ + +import TSCUtility +import XCTest + +class TripleTests : XCTestCase { + func testTriple() { + let linux = try? Triple("x86_64-unknown-linux-gnu") + XCTAssertNotNil(linux) + XCTAssertEqual(linux!.os, .linux) + XCTAssertNil(linux!.osVersion) + + let macos = try? Triple("x86_64-apple-macosx10.15") + XCTAssertNotNil(macos!) + XCTAssertEqual(macos!.osVersion, "10.15") + let newVersion = "10.12" + let tripleString = macos!.tripleString(forPlatformVersion: newVersion) + XCTAssertEqual(tripleString, "x86_64-apple-macosx10.12") + + let android = try? Triple("aarch64-unknown-linux-android24") + XCTAssertNotNil(android) + XCTAssertEqual(android!.os, .linux) + XCTAssertEqual(android!.abiVersion, "24") + } +}