Skip to content

Commit 0f24910

Browse files
authored
Add support for Apple silicon to the durian-swt enums (#13)
2 parents d46be2b + a226950 commit 0f24910

File tree

5 files changed

+80
-14
lines changed

5 files changed

+80
-14
lines changed

CHANGES.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
# DurianSwt releases
22

33
## [Unreleased]
4+
### Added
5+
- Support for Apple Silicon in the `OS`, `Arch`, and `SwtPlatform` classes. ([#13](https://github.com/diffplug/durian-swt/pull/13))
46

57
## [3.3.1] - 2020-01-13
68
### Fixed

build.gradle

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,10 @@ subprojects { subProject ->
4343
compileOnly 'com.google.code.findbugs:jsr305:3.0.2'
4444
testImplementation "junit:junit:$VER_JUNIT"
4545
}
46+
tasks.register('osMain', JavaExec) {
47+
classpath = sourceSets.main.runtimeClasspath
48+
main = 'com.diffplug.common.swt.os.OS'
49+
}
4650
} else {
4751
apply plugin: 'com.diffplug.gradle.eclipse.mavencentral'
4852
String platformCode = project.name.substring('durian-swt.'.length())

durian-swt.os/src/main/java/com/diffplug/common/swt/os/Arch.java

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717

1818
/** Enum for handling different processor architectures supported by SWT. */
1919
public enum Arch {
20-
x86, x64;
20+
x86, x64, arm64;
2121

2222
/** Returns the appropriate value depending on the arch. */
2323
public <T> T x86x64(T val86, T val64) {
@@ -31,6 +31,32 @@ public <T> T x86x64(T val86, T val64) {
3131
}
3232
}
3333

34+
/** Returns the appropriate value depending on the arch. */
35+
public <T> T x64arm64(T val64, T arm64) {
36+
switch (this) {
37+
case x64:
38+
return val64;
39+
case arm64:
40+
return arm64;
41+
default:
42+
throw unsupportedException(this);
43+
}
44+
}
45+
46+
/** Returns the appropriate value depending on the arch. */
47+
public <T> T x86x64arm64(T val86, T val64, T arm64) {
48+
switch (this) {
49+
case x86:
50+
return val86;
51+
case x64:
52+
return val64;
53+
case arm64:
54+
return arm64;
55+
default:
56+
throw unsupportedException(this);
57+
}
58+
}
59+
3460
/** Returns the Arch for the native platform: 32-bit JVM on 64-bit Windows returns Arch.x64. */
3561
public static Arch getNative() {
3662
return OS.getNative().getArch();

durian-swt.os/src/main/java/com/diffplug/common/swt/os/OS.java

Lines changed: 46 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,17 @@
1616
package com.diffplug.common.swt.os;
1717

1818

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;
1924
import java.util.Arrays;
2025
import java.util.Locale;
2126

2227
/** Enum representing an OS and its underlying CPU architecture. */
2328
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;
2530

2631
public boolean isWindows() {
2732
return this == WIN_x64 || this == WIN_x86;
@@ -32,7 +37,7 @@ public boolean isLinux() {
3237
}
3338

3439
public boolean isMac() {
35-
return this == MAC_x64;
40+
return this == MAC_x64 || this == MAC_silicon;
3641
}
3742

3843
public boolean isMacOrLinux() {
@@ -62,6 +67,8 @@ public Arch getArch() {
6267
case WIN_x86:
6368
case LINUX_x86:
6469
return Arch.x86;
70+
case MAC_silicon:
71+
return Arch.arm64;
6572
default:
6673
throw unsupportedException(this);
6774
}
@@ -74,7 +81,7 @@ public String os() {
7481

7582
/** SWT-style x86/x86_64 */
7683
public String arch() {
77-
return getArch().x86x64("x86", "x86_64");
84+
return getArch().x86x64arm64("x86", "x86_64", "aarch64");
7885
}
7986

8087
/** os().arch() */
@@ -84,7 +91,7 @@ public String osDotArch() {
8491

8592
/** windowing.os.arch */
8693
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");
8895
}
8996

9097
/** Returns the native OS: 32-bit JVM on 64-bit Windows returns OS.WIN_64. */
@@ -105,9 +112,8 @@ private static OS calculateNative() {
105112
boolean isWin = os_name.contains("win");
106113
boolean isMac = os_name.contains("mac");
107114
boolean isLinux = Arrays.asList("nix", "nux", "aix").stream().anyMatch(os_name::contains);
108-
109115
if (isMac) {
110-
return MAC_x64;
116+
return exec("uname", "-a").contains("_ARM64_") ? MAC_silicon : MAC_x64;
111117
} else if (isWin) {
112118
boolean is64bit = System.getenv("ProgramFiles(x86)") != null;
113119
return is64bit ? WIN_x64 : WIN_x86;
@@ -128,15 +134,38 @@ private static OS calculateNative() {
128134
}
129135
}
130136

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+
131156
private static final OS RUNNING_OS = calculateRunning();
132157

133158
/** Calculates the running OS. */
134159
private static OS calculateRunning() {
135160
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;
140169
}
141170

142171
/** Returns the arch of the currently running JVM. */
@@ -146,14 +175,19 @@ private static Arch runningJvm() {
146175
case "32":
147176
return Arch.x86;
148177
case "64":
149-
return Arch.x64;
178+
return "aarch64".equals(System.getProperty("os.arch")) ? Arch.arm64 : Arch.x64;
150179
default:
151-
throw new IllegalArgumentException(sunArchDataModel);
180+
throw new IllegalArgumentException("Expcted 32 or 64, was " + sunArchDataModel);
152181
}
153182
}
154183

155184
/** Returns an UnsupportedOperationException for the given OS. */
156185
public static UnsupportedOperationException unsupportedException(OS os) {
157186
return new UnsupportedOperationException("Operating system '" + os + "' is not supported.");
158187
}
188+
189+
public static void main(String[] args) {
190+
System.out.println("native=" + OS.getNative());
191+
System.out.println("running=" + OS.getRunning());
192+
}
159193
}

durian-swt.os/src/main/java/com/diffplug/common/swt/os/SwtPlatform.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ public static SwtPlatform getRunning() {
129129
public static SwtPlatform fromOS(OS raw) {
130130
String ws = raw.winMacLinux("win32", "cocoa", "gtk");
131131
String os = raw.winMacLinux("win32", "macosx", "linux");
132-
String arch = raw.getArch().x86x64("x86", "x86_64");
132+
String arch = raw.getArch().x86x64arm64("x86", "x86_64", "aarch64");
133133
return new SwtPlatform(ws, os, arch);
134134
}
135135

0 commit comments

Comments
 (0)