-
Notifications
You must be signed in to change notification settings - Fork 83
/
Copy pathArchitecture.swift
122 lines (112 loc) · 3.84 KB
/
Architecture.swift
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
//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift open source project
//
// Copyright (c) 2025 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 the list of Swift project authors
//
//===----------------------------------------------------------------------===//
import Foundation
import SWBLibc
#if canImport(Darwin)
import Darwin
import MachO
#if canImport(MachO.dyld.utils)
import MachO.dyld.utils
#endif
#endif
public struct Architecture: Sendable {
private let cputype: cpu_type_t
private init(cputype: cpu_type_t = CPU_TYPE_ANY) {
self.cputype = cputype
}
/// Returns the native architecture of the host machine, not including subtypes like arm64e and x86_64h.
public static let host: Architecture = {
#if canImport(Darwin) && canImport(MachO.dyld.utils)
if let value = macho_arch_name_for_mach_header(nil) {
var cputype: cpu_type_t = 0
var cpusubtype: cpu_subtype_t = 0
if macho_cpu_type_for_arch_name(value, &cputype, &cpusubtype) {
return Self(cputype: cputype)
}
}
#endif
return Self()
}()
/// Returns the 32-bit counterpart of the architecture, which may be the same value.
public var as32bit: Architecture {
#if canImport(Darwin)
return Self(cputype: cputype & ~CPU_ARCH_ABI64)
#else
return Self()
#endif
}
/// Returns the 64-bit counterpart of the architecture, which may be the same value.
public var as64bit: Architecture {
#if canImport(Darwin)
return Self(cputype: cputype | CPU_ARCH_ABI64)
#else
return Self()
#endif
}
/// Returns the string representation of the architecture, or `nil` if it cannot be determined.
public var stringValue: String? {
#if canImport(Darwin)
// This only needs to consider the known 4 values as it's only for computing the host architecture build settings.
switch cputype {
case CPU_TYPE_ARM:
return "arm"
case CPU_TYPE_ARM64:
return "arm64"
case CPU_TYPE_I386:
return "i386"
case CPU_TYPE_X86_64:
return "x86_64"
default:
break
}
#endif
return nil
}
public static var hostStringValue: String? {
return host.stringValue ?? { () -> String? in
#if os(Windows)
var sysInfo = SYSTEM_INFO()
GetSystemInfo(&sysInfo)
switch Int32(sysInfo.wProcessorArchitecture) {
case PROCESSOR_ARCHITECTURE_AMD64:
return "x86_64"
case PROCESSOR_ARCHITECTURE_ARM64:
return "aarch64"
default:
return nil
}
#else
var buf = utsname()
if uname(&buf) == 0 {
return withUnsafeBytes(of: &buf.machine) { buf in
let data = Data(buf)
let value = String(decoding: data[0...(data.lastIndex(where: { $0 != 0 }) ?? 0)], as: UTF8.self)
switch value {
case "amd64":
return "x86_64"
default:
return value
}
}
}
return nil
#endif
}()
}
static func stringValue(cputype: cpu_type_t, cpusubtype: cpu_subtype_t) -> String? {
#if canImport(Darwin) && canImport(MachO.dyld.utils)
return macho_arch_name_for_cpu_type(cputype, cpusubtype).map(String.init(cString:))
#else
return nil
#endif
}
}