16
16
package com .diffplug .common .swt .os ;
17
17
18
18
19
+ import java .io .ByteArrayOutputStream ;
20
+ import java .io .IOException ;
21
+ import java .io .InputStream ;
22
+ import java .io .OutputStream ;
23
+ import java .nio .charset .StandardCharsets ;
19
24
import java .util .Arrays ;
20
25
import java .util .Locale ;
21
26
22
27
/** Enum representing an OS and its underlying CPU architecture. */
23
28
public enum OS {
24
- WIN_x64 , WIN_x86 , LINUX_x64 , LINUX_x86 , MAC_x64 ;
29
+ WIN_x64 , WIN_x86 , LINUX_x64 , LINUX_x86 , MAC_x64 , MAC_silicon ;
25
30
26
31
public boolean isWindows () {
27
32
return this == WIN_x64 || this == WIN_x86 ;
@@ -32,7 +37,7 @@ public boolean isLinux() {
32
37
}
33
38
34
39
public boolean isMac () {
35
- return this == MAC_x64 ;
40
+ return this == MAC_x64 || this == MAC_silicon ;
36
41
}
37
42
38
43
public boolean isMacOrLinux () {
@@ -62,6 +67,8 @@ public Arch getArch() {
62
67
case WIN_x86 :
63
68
case LINUX_x86 :
64
69
return Arch .x86 ;
70
+ case MAC_silicon :
71
+ return Arch .arm64 ;
65
72
default :
66
73
throw unsupportedException (this );
67
74
}
@@ -74,7 +81,7 @@ public String os() {
74
81
75
82
/** SWT-style x86/x86_64 */
76
83
public String arch () {
77
- return getArch ().x86x64 ("x86" , "x86_64" );
84
+ return getArch ().x86x64arm64 ("x86" , "x86_64" , "aarch64 " );
78
85
}
79
86
80
87
/** os().arch() */
@@ -84,7 +91,7 @@ public String osDotArch() {
84
91
85
92
/** windowing.os.arch */
86
93
public String toSwt () {
87
- return winMacLinux ("win32" , "cocoa" , "gtk" ) + "." + winMacLinux ("win32" , "macosx" , "linux" ) + "." + getArch ().x86x64 ("x86" , "x86_64" );
94
+ return winMacLinux ("win32" , "cocoa" , "gtk" ) + "." + winMacLinux ("win32" , "macosx" , "linux" ) + "." + getArch ().x86x64arm64 ("x86" , "x86_64" , "aarch64 " );
88
95
}
89
96
90
97
/** Returns the native OS: 32-bit JVM on 64-bit Windows returns OS.WIN_64. */
@@ -105,9 +112,8 @@ private static OS calculateNative() {
105
112
boolean isWin = os_name .contains ("win" );
106
113
boolean isMac = os_name .contains ("mac" );
107
114
boolean isLinux = Arrays .asList ("nix" , "nux" , "aix" ).stream ().anyMatch (os_name ::contains );
108
-
109
115
if (isMac ) {
110
- return MAC_x64 ;
116
+ return exec ( "uname" , "-a" ). contains ( "_ARM64_" ) ? MAC_silicon : MAC_x64 ;
111
117
} else if (isWin ) {
112
118
boolean is64bit = System .getenv ("ProgramFiles(x86)" ) != null ;
113
119
return is64bit ? WIN_x64 : WIN_x86 ;
@@ -128,15 +134,38 @@ private static OS calculateNative() {
128
134
}
129
135
}
130
136
137
+ private static String exec (String ... cmd ) {
138
+ try {
139
+ Process process = Runtime .getRuntime ().exec (new String []{"uname" , "-a" });
140
+ ByteArrayOutputStream output = new ByteArrayOutputStream ();
141
+ drain (process .getInputStream (), output );
142
+ return new String (output .toByteArray (), StandardCharsets .UTF_8 );
143
+ } catch (IOException e ) {
144
+ throw new RuntimeException (e );
145
+ }
146
+ }
147
+
148
+ private static void drain (InputStream input , OutputStream output ) throws IOException {
149
+ byte [] buf = new byte [1024 ];
150
+ int numRead ;
151
+ while ((numRead = input .read (buf )) != -1 ) {
152
+ output .write (buf , 0 , numRead );
153
+ }
154
+ }
155
+
131
156
private static final OS RUNNING_OS = calculateRunning ();
132
157
133
158
/** Calculates the running OS. */
134
159
private static OS calculateRunning () {
135
160
Arch runningArch = runningJvm ();
136
- return NATIVE_OS .winMacLinux (
137
- runningArch .x86x64 (OS .WIN_x86 , OS .WIN_x64 ),
138
- OS .MAC_x64 ,
139
- runningArch .x86x64 (OS .LINUX_x86 , OS .LINUX_x64 ));
161
+ OS runningOs = NATIVE_OS .winMacLinux (
162
+ runningArch .x86x64arm64 (OS .WIN_x86 , OS .WIN_x64 , null ),
163
+ runningArch .x86x64arm64 (null , OS .MAC_x64 , OS .MAC_silicon ),
164
+ runningArch .x86x64arm64 (OS .LINUX_x86 , OS .LINUX_x64 , null ));
165
+ if (runningOs == null ) {
166
+ throw new IllegalArgumentException ("Unsupported OS/Arch combo: " + runningOs + " " + runningArch );
167
+ }
168
+ return runningOs ;
140
169
}
141
170
142
171
/** Returns the arch of the currently running JVM. */
@@ -146,14 +175,19 @@ private static Arch runningJvm() {
146
175
case "32" :
147
176
return Arch .x86 ;
148
177
case "64" :
149
- return Arch .x64 ;
178
+ return "aarch64" . equals ( System . getProperty ( "os.arch" )) ? Arch . arm64 : Arch .x64 ;
150
179
default :
151
- throw new IllegalArgumentException (sunArchDataModel );
180
+ throw new IllegalArgumentException ("Expcted 32 or 64, was " + sunArchDataModel );
152
181
}
153
182
}
154
183
155
184
/** Returns an UnsupportedOperationException for the given OS. */
156
185
public static UnsupportedOperationException unsupportedException (OS os ) {
157
186
return new UnsupportedOperationException ("Operating system '" + os + "' is not supported." );
158
187
}
188
+
189
+ public static void main (String [] args ) {
190
+ System .out .println ("native=" + OS .getNative ());
191
+ System .out .println ("running=" + OS .getRunning ());
192
+ }
159
193
}
0 commit comments